├── .clang-format ├── .editorconfig ├── .gitignore ├── CMakeLists.txt ├── compile_flags.txt ├── examples ├── basic │ ├── main.lua │ ├── noto-sans-jp.ttf │ ├── player.lua │ ├── player.png │ └── readme.md ├── boxes │ ├── atlas.png │ ├── atlas.rtpa │ ├── main.lua │ └── readme.md ├── dungeon │ ├── arrow.lua │ ├── arrow.png │ ├── bow.png │ ├── camera.lua │ ├── chort.lua │ ├── coin.ase │ ├── coin.lua │ ├── cursor.lua │ ├── cursor.png │ ├── elf.ase │ ├── enemy.ase │ ├── main.lua │ ├── map.ldtk │ ├── player.lua │ ├── readme.md │ ├── skeleton.lua │ └── tiles.png ├── ecs │ ├── main.lua │ ├── player.png │ └── readme.md ├── inheritance │ ├── animal.lua │ ├── crab.lua │ ├── dog.lua │ └── main.lua ├── jump │ ├── atlas.png │ ├── atlas.rtpa │ ├── camera.lua │ ├── jump.lua │ ├── king-around-here.ogg │ ├── main.lua │ ├── moving_platform.lua │ ├── phaseJump2.ogg │ ├── phaserUp1.ogg │ ├── platform.lua │ ├── player.ase │ ├── player.lua │ ├── readme.md │ ├── spikes.lua │ └── spring_box.lua ├── microui │ └── main.lua ├── networking │ ├── client │ │ └── main.lua │ └── server │ │ ├── main.lua │ │ └── server.py ├── novel │ ├── bg │ │ ├── School_Hallway_Day.png │ │ └── Train_Day.png │ ├── char │ │ ├── Alice_Blush.png │ │ ├── Alice_Default.png │ │ ├── Alice_Embarrassed.png │ │ ├── Alice_Happy.png │ │ └── Alice_Worried.png │ ├── main.lua │ ├── noto-sans-jp.ttf │ ├── readme.md │ └── script.lua ├── pathfinding │ ├── Grass.png │ ├── actor.lua │ ├── char.ase │ ├── chest.ase │ ├── main.lua │ ├── map.ldtk │ └── readme.md ├── planes │ ├── _composite.png │ ├── atlas.png │ ├── atlas.rtpa │ ├── bullet.lua │ ├── enemy.lua │ ├── explosion.lua │ ├── main.lua │ ├── player.lua │ ├── readme.md │ ├── rocket.lua │ └── smoke.lua └── sampler │ ├── main.lua │ ├── player.png │ └── readme.md ├── html5 ├── data │ └── main.lua ├── index.html ├── readme.md ├── spry.js └── spry.wasm ├── musings.md ├── readme.md ├── src ├── algebra.h ├── api.cpp ├── api.h ├── app.h ├── arena.cpp ├── arena.h ├── array.h ├── assets.cpp ├── assets.h ├── atlas.cpp ├── atlas.h ├── bootstrap.lua ├── concurrency.cpp ├── concurrency.h ├── deps.cpp ├── deps │ ├── box2d │ │ ├── box2d │ │ │ ├── b2_api.h │ │ │ ├── b2_block_allocator.h │ │ │ ├── b2_body.h │ │ │ ├── b2_broad_phase.h │ │ │ ├── b2_chain_shape.h │ │ │ ├── b2_circle_shape.h │ │ │ ├── b2_collision.h │ │ │ ├── b2_common.h │ │ │ ├── b2_contact.h │ │ │ ├── b2_contact_manager.h │ │ │ ├── b2_distance.h │ │ │ ├── b2_distance_joint.h │ │ │ ├── b2_draw.h │ │ │ ├── b2_dynamic_tree.h │ │ │ ├── b2_edge_shape.h │ │ │ ├── b2_fixture.h │ │ │ ├── b2_friction_joint.h │ │ │ ├── b2_gear_joint.h │ │ │ ├── b2_growable_stack.h │ │ │ ├── b2_joint.h │ │ │ ├── b2_math.h │ │ │ ├── b2_motor_joint.h │ │ │ ├── b2_mouse_joint.h │ │ │ ├── b2_polygon_shape.h │ │ │ ├── b2_prismatic_joint.h │ │ │ ├── b2_pulley_joint.h │ │ │ ├── b2_revolute_joint.h │ │ │ ├── b2_rope.h │ │ │ ├── b2_settings.h │ │ │ ├── b2_shape.h │ │ │ ├── b2_stack_allocator.h │ │ │ ├── b2_time_of_impact.h │ │ │ ├── b2_time_step.h │ │ │ ├── b2_timer.h │ │ │ ├── b2_types.h │ │ │ ├── b2_weld_joint.h │ │ │ ├── b2_wheel_joint.h │ │ │ ├── b2_world.h │ │ │ ├── b2_world_callbacks.h │ │ │ └── box2d.h │ │ ├── collision │ │ │ ├── b2_broad_phase.cpp │ │ │ ├── b2_chain_shape.cpp │ │ │ ├── b2_circle_shape.cpp │ │ │ ├── b2_collide_circle.cpp │ │ │ ├── b2_collide_edge.cpp │ │ │ ├── b2_collide_polygon.cpp │ │ │ ├── b2_collision.cpp │ │ │ ├── b2_distance.cpp │ │ │ ├── b2_dynamic_tree.cpp │ │ │ ├── b2_edge_shape.cpp │ │ │ ├── b2_polygon_shape.cpp │ │ │ └── b2_time_of_impact.cpp │ │ ├── common │ │ │ ├── b2_block_allocator.cpp │ │ │ ├── b2_draw.cpp │ │ │ ├── b2_math.cpp │ │ │ ├── b2_settings.cpp │ │ │ ├── b2_stack_allocator.cpp │ │ │ └── b2_timer.cpp │ │ ├── dynamics │ │ │ ├── b2_body.cpp │ │ │ ├── b2_chain_circle_contact.cpp │ │ │ ├── b2_chain_circle_contact.h │ │ │ ├── b2_chain_polygon_contact.cpp │ │ │ ├── b2_chain_polygon_contact.h │ │ │ ├── b2_circle_contact.cpp │ │ │ ├── b2_circle_contact.h │ │ │ ├── b2_contact.cpp │ │ │ ├── b2_contact_manager.cpp │ │ │ ├── b2_contact_solver.cpp │ │ │ ├── b2_contact_solver.h │ │ │ ├── b2_distance_joint.cpp │ │ │ ├── b2_edge_circle_contact.cpp │ │ │ ├── b2_edge_circle_contact.h │ │ │ ├── b2_edge_polygon_contact.cpp │ │ │ ├── b2_edge_polygon_contact.h │ │ │ ├── b2_fixture.cpp │ │ │ ├── b2_friction_joint.cpp │ │ │ ├── b2_gear_joint.cpp │ │ │ ├── b2_island.cpp │ │ │ ├── b2_island.h │ │ │ ├── b2_joint.cpp │ │ │ ├── b2_motor_joint.cpp │ │ │ ├── b2_mouse_joint.cpp │ │ │ ├── b2_polygon_circle_contact.cpp │ │ │ ├── b2_polygon_circle_contact.h │ │ │ ├── b2_polygon_contact.cpp │ │ │ ├── b2_polygon_contact.h │ │ │ ├── b2_prismatic_joint.cpp │ │ │ ├── b2_pulley_joint.cpp │ │ │ ├── b2_revolute_joint.cpp │ │ │ ├── b2_weld_joint.cpp │ │ │ ├── b2_wheel_joint.cpp │ │ │ ├── b2_world.cpp │ │ │ └── b2_world_callbacks.cpp │ │ └── rope │ │ │ └── b2_rope.cpp │ ├── cute_aseprite.h │ ├── lua │ │ ├── lapi.c │ │ ├── lapi.h │ │ ├── lauxlib.c │ │ ├── lauxlib.h │ │ ├── lbaselib.c │ │ ├── lcode.c │ │ ├── lcode.h │ │ ├── lcorolib.c │ │ ├── lctype.c │ │ ├── lctype.h │ │ ├── ldblib.c │ │ ├── ldebug.c │ │ ├── ldebug.h │ │ ├── ldo.c │ │ ├── ldo.h │ │ ├── ldump.c │ │ ├── lfunc.c │ │ ├── lfunc.h │ │ ├── lgc.c │ │ ├── lgc.h │ │ ├── linit.c │ │ ├── liolib.c │ │ ├── ljumptab.h │ │ ├── llex.c │ │ ├── llex.h │ │ ├── llimits.h │ │ ├── lmathlib.c │ │ ├── lmem.c │ │ ├── lmem.h │ │ ├── loadlib.c │ │ ├── lobject.c │ │ ├── lobject.h │ │ ├── lopcodes.c │ │ ├── lopcodes.h │ │ ├── lopnames.h │ │ ├── loslib.c │ │ ├── lparser.c │ │ ├── lparser.h │ │ ├── lprefix.h │ │ ├── lstate.c │ │ ├── lstate.h │ │ ├── lstring.c │ │ ├── lstring.h │ │ ├── lstrlib.c │ │ ├── ltable.c │ │ ├── ltable.h │ │ ├── ltablib.c │ │ ├── ltests.c │ │ ├── ltests.h │ │ ├── ltm.c │ │ ├── ltm.h │ │ ├── lua.c │ │ ├── lua.h │ │ ├── luaconf.h │ │ ├── lualib.h │ │ ├── lundump.c │ │ ├── lundump.h │ │ ├── lutf8lib.c │ │ ├── lvm.c │ │ ├── lvm.h │ │ ├── lzio.c │ │ ├── lzio.h │ │ └── onelua.c │ ├── luaalloc.c │ ├── luaalloc.h │ ├── luasocket │ │ ├── auxiliar.c │ │ ├── auxiliar.h │ │ ├── buffer.c │ │ ├── buffer.h │ │ ├── compat.c │ │ ├── compat.h │ │ ├── except.c │ │ ├── except.h │ │ ├── inet.c │ │ ├── inet.h │ │ ├── io.c │ │ ├── io.h │ │ ├── luasocket.c │ │ ├── luasocket.h │ │ ├── mime.c │ │ ├── mime.h │ │ ├── options.c │ │ ├── options.h │ │ ├── pierror.h │ │ ├── select.c │ │ ├── select.h │ │ ├── serial.c │ │ ├── socket.h │ │ ├── tcp.c │ │ ├── tcp.h │ │ ├── timeout.c │ │ ├── timeout.h │ │ ├── udp.c │ │ ├── udp.h │ │ ├── unix.c │ │ ├── unix.h │ │ ├── unixdgram.c │ │ ├── unixdgram.h │ │ ├── unixstream.c │ │ ├── unixstream.h │ │ ├── usocket.c │ │ ├── usocket.h │ │ ├── wsocket.c │ │ └── wsocket.h │ ├── microui.c │ ├── microui.h │ ├── microui_atlas.inl │ ├── miniaudio.h │ ├── miniz.c │ ├── miniz.h │ ├── sokol_app.h │ ├── sokol_gfx.h │ ├── sokol_gl.h │ ├── sokol_glue.h │ ├── sokol_log.h │ ├── sokol_time.h │ ├── stb_image.h │ ├── stb_image_resize2.h │ ├── stb_truetype.h │ ├── stb_vorbis.c │ └── tinydir.h ├── draw.cpp ├── draw.h ├── embed │ ├── Cousine-Regular.ttf │ ├── binary_to_compressed_c.cpp │ ├── cousine_compressed.h │ ├── ltn12.lua │ ├── ltn12_compressed.h │ ├── mbox.lua │ ├── mbox_compressed.h │ ├── mime.lua │ ├── mime_compressed.h │ ├── socket.ftp.lua │ ├── socket.headers.lua │ ├── socket.http.lua │ ├── socket.lua │ ├── socket.smtp.lua │ ├── socket.tp.lua │ ├── socket.url.lua │ ├── socket_compressed.h │ ├── socket_ftp_compressed.h │ ├── socket_headers_compressed.h │ ├── socket_http_compressed.h │ ├── socket_smtp_compressed.h │ ├── socket_tp_compressed.h │ └── socket_url_compressed.h ├── font.cpp ├── font.h ├── hash_map.h ├── image.cpp ├── image.h ├── json.cpp ├── json.h ├── luax.cpp ├── luax.h ├── main.cpp ├── microui.cpp ├── microui.h ├── os.cpp ├── os.h ├── physics.cpp ├── physics.h ├── prelude.cpp ├── prelude.h ├── priority_queue.h ├── profile.cpp ├── profile.h ├── queue.h ├── scanner.cpp ├── scanner.h ├── slice.h ├── sound.cpp ├── sound.h ├── sprite.cpp ├── sprite.h ├── stb_decompress.h ├── strings.cpp ├── strings.h ├── sync.cpp ├── sync.h ├── tilemap.cpp ├── tilemap.h ├── vfs.cpp └── vfs.h └── website ├── .gitignore ├── Parsedown.php ├── guides ├── debugging.md ├── distribution.md ├── hot-reload.md ├── quick-start.php └── ufo-game.md ├── index.php ├── package.json ├── pages ├── demo.php ├── docs.php ├── guide.php └── index.php ├── readme.md └── static ├── alpine.js ├── assets ├── code-ase.webm ├── code-hello.png ├── code-tile.webm ├── debug-vscode.png ├── debug-zerobrane.png ├── feat-ase.png ├── feat-lua.png ├── feat-web.png ├── green-ufo.png ├── hot-ldtk.webm ├── hot-lua.webm ├── hot-png.webm └── ufo-demo.webm ├── atom-one-light.min.css ├── default-dark.min.css ├── demos ├── boxes.zip ├── dungeon.zip ├── example-dungeon.webm ├── example-jump.webm ├── example-physics.webm ├── example-ships.webm ├── jump.zip ├── planes.zip ├── spry.js └── spry.wasm ├── highlight.min.js ├── style.css └── tachyons.min.css /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IndentWidth: 2 3 | AllowShortCaseLabelsOnASingleLine: true -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_style = space 6 | indent_size = 2 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.exp 3 | *.lib 4 | *.pdb 5 | *.ilk 6 | *.obj 7 | *.o 8 | *.out 9 | spry 10 | .vs 11 | ignore 12 | dist 13 | *.data 14 | 15 | /spry.wasm 16 | /spry.js 17 | /*.zip 18 | /*.json 19 | /build 20 | /debug 21 | /release 22 | /emdebug 23 | /emrelease -------------------------------------------------------------------------------- /compile_flags.txt: -------------------------------------------------------------------------------- 1 | -xc++-header 2 | -std=c++17 3 | -Wall 4 | -Isrc/deps/box2d 5 | -Isrc/deps/lua -------------------------------------------------------------------------------- /examples/basic/main.lua: -------------------------------------------------------------------------------- 1 | function spry.start() 2 | jp = spry.font_load("noto-sans-jp.ttf") 3 | font = spry.default_font() 4 | 5 | world = World() 6 | world:add(Player(200, 200)) 7 | end 8 | 9 | function spry.frame(dt) 10 | world:update(dt) 11 | world:draw() 12 | 13 | if spry.mouse_down(0) then 14 | world:add(Player(spry.mouse_pos())) 15 | end 16 | 17 | jp:draw("Hello, 世界!", 100, 100, 24) 18 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 19 | end -------------------------------------------------------------------------------- /examples/basic/noto-sans-jp.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/basic/noto-sans-jp.ttf -------------------------------------------------------------------------------- /examples/basic/player.lua: -------------------------------------------------------------------------------- 1 | class "Player" 2 | 3 | function Player:new(x, y) 4 | self.x, self.y = x, y 5 | self.img = spry.image_load "player.png" 6 | end 7 | 8 | function Player:update(dt) 9 | local vx, vy = 0, 0 10 | 11 | if spry.key_down "w" then vy = vy - 1 end 12 | if spry.key_down "s" then vy = vy + 1 end 13 | if spry.key_down "a" then vx = vx - 1 end 14 | if spry.key_down "d" then vx = vx + 1 end 15 | 16 | vx, vy = normalize(vx, vy) 17 | self.x = self.x + vx * dt * 300 18 | self.y = self.y + vy * dt * 300 19 | end 20 | 21 | function Player:draw() 22 | local ox = self.img:width() * 0.5 23 | local oy = self.img:height() * 0.5 24 | self.img:draw(self.x, self.y, 0, 3, 3, ox, oy) 25 | end -------------------------------------------------------------------------------- /examples/basic/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/basic/player.png -------------------------------------------------------------------------------- /examples/basic/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `player.png` https://www.kenney.nl/assets/pixel-platformer (CC0) 4 | - `noto-sans-jp.ttf` https://fonts.google.com/noto/specimen/Noto+Sans+JP (OFL) -------------------------------------------------------------------------------- /examples/boxes/atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/boxes/atlas.png -------------------------------------------------------------------------------- /examples/boxes/atlas.rtpa: -------------------------------------------------------------------------------- 1 | # 2 | # rTexPacker atlas descriptor file (v2.0) 3 | # 4 | # Number of packed sprites: 11 5 | # 6 | # Atlas info: a 7 | # Sprite info: s 8 | # 9 | a atlas.png 512 512 11 0 32 10 | s stone0 0 0 0 356 140 70 1 0 0 0 140 70 11 | s stone1 0 0 142 356 70 70 1 0 0 0 70 70 12 | s stone2 0 0 214 356 70 70 1 0 0 0 70 70 13 | s stone3 0 0 364 284 70 70 1 0 0 0 70 70 14 | s stone4 0 0 222 284 140 70 1 0 0 0 140 70 15 | s stone5 0 0 0 284 220 70 1 0 0 0 220 70 16 | s stone6 0 0 356 142 70 140 1 0 0 0 70 140 17 | s stone7 0 0 214 142 140 140 1 0 0 0 140 140 18 | s stone8 0 0 214 0 220 140 1 0 0 0 220 140 19 | s stone9 0 0 142 0 70 220 1 0 0 0 70 220 20 | s stone10 0 0 0 0 140 220 1 0 0 0 140 220 21 | -------------------------------------------------------------------------------- /examples/boxes/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `atlas.png` https://www.kenney.nl/assets/physics-assets (CC0) 4 | -------------------------------------------------------------------------------- /examples/dungeon/arrow.lua: -------------------------------------------------------------------------------- 1 | class "Arrow" 2 | 3 | function Arrow:new(x, y, angle) 4 | self.x = x 5 | self.y = y 6 | self.angle = angle 7 | self.lifetime = 0 8 | end 9 | 10 | function Arrow:on_create() 11 | local vx, vy = heading(self.angle, 500) 12 | 13 | self.body = b2:make_dynamic_body { 14 | x = self.x, 15 | y = self.y, 16 | vx = vx, 17 | vy = vy, 18 | angle = self.angle, 19 | fixed_rotation = true, 20 | } 21 | 22 | self.body:make_box_fixture { 23 | w = 8, 24 | h = 2, 25 | udata = self.id, 26 | begin_contact = Arrow.begin_contact, 27 | } 28 | end 29 | 30 | function Arrow:on_death() 31 | self.body:destroy() 32 | end 33 | 34 | function Arrow:update(dt) 35 | self.lifetime = self.lifetime + dt 36 | if self.lifetime > 10 then 37 | world:kill(self) 38 | end 39 | 40 | self.x, self.y = self.body:position() 41 | end 42 | 43 | function Arrow:draw() 44 | local img = arrow_img 45 | local ox = img:width() / 2 46 | local oy = img:height() / 2 47 | img:draw(self.x, self.y, self.angle + math.pi / 2, 1, 1, ox, oy) 48 | 49 | if draw_fixtures then 50 | self.body:draw_fixtures() 51 | end 52 | end 53 | 54 | function Arrow.begin_contact(a, b) 55 | local self = world:query_id(a:udata()) 56 | local is_player = b:udata() == player.id 57 | 58 | if not is_player then 59 | world:kill(self) 60 | end 61 | end -------------------------------------------------------------------------------- /examples/dungeon/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/arrow.png -------------------------------------------------------------------------------- /examples/dungeon/bow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/bow.png -------------------------------------------------------------------------------- /examples/dungeon/camera.lua: -------------------------------------------------------------------------------- 1 | class "Camera" 2 | 3 | function Camera:new(def) 4 | self.x = def.x 5 | self.y = def.y 6 | self.scale = def.scale 7 | end 8 | 9 | function Camera:to_world_space(x, y) 10 | x = x - spry.window_width() / 2 11 | y = y - spry.window_height() / 2 12 | 13 | x = x / camera.scale 14 | y = y / camera.scale 15 | 16 | x = x + camera.x 17 | y = y + camera.y 18 | 19 | return x, y 20 | end 21 | 22 | function Camera:begin_draw() 23 | spry.push_matrix() 24 | spry.translate(spry.window_width() / 2, spry.window_height() / 2) 25 | spry.scale(self.scale, self.scale) 26 | spry.translate(-self.x, -self.y) 27 | end 28 | 29 | function Camera:end_draw() 30 | spry.pop_matrix() 31 | end -------------------------------------------------------------------------------- /examples/dungeon/coin.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/coin.ase -------------------------------------------------------------------------------- /examples/dungeon/coin.lua: -------------------------------------------------------------------------------- 1 | class "Coin" 2 | 3 | function Coin:new(x, y) 4 | self.x = x 5 | self.y = y 6 | self.z = -1 7 | self.vx, self.vy = heading(random(0, math.pi * 2), 20) 8 | self.vz = random(-120, -330) 9 | self.spring = Spring() 10 | self.update_thread = coroutine.create(self.co_update) 11 | 12 | self.sprite = spry.sprite_load "coin.ase" 13 | self.sprite:set_frame(math.random(0, self.sprite:total_frames() - 1)) 14 | end 15 | 16 | function Coin:co_update(dt) 17 | while true do 18 | self.vz = self.vz + dt * 800 19 | 20 | self.z = self.z + self.vz * dt 21 | self.x = self.x + self.vx * dt 22 | self.y = self.y + self.vy * dt 23 | 24 | if self.z > 0 then 25 | break 26 | end 27 | 28 | self, dt = coroutine.yield() 29 | end 30 | 31 | self.z = 0 32 | self.spring:pull(0.6) 33 | dt = sleep(0.5) 34 | 35 | repeat 36 | local dist = distance(self.x, self.y, player.x, player.y) 37 | self, dt = coroutine.yield() 38 | until dist < 128 39 | 40 | repeat 41 | local blend = 1 - 0.5 ^ (dt * 40) 42 | self.x = lerp(self.x, player.x, blend) 43 | self.y = lerp(self.y, player.y, blend) 44 | 45 | local dist = distance(self.x, self.y, player.x, player.y) 46 | self, dt = coroutine.yield() 47 | until dist < 8 48 | 49 | world:kill(self) 50 | end 51 | 52 | function Coin:update(dt) 53 | self.sprite:update(dt) 54 | self.spring:update(dt) 55 | resume(self.update_thread, self, dt) 56 | end 57 | 58 | function Coin:draw() 59 | local sx = 1 + self.spring.x 60 | local sy = 1 - self.spring.x 61 | local ox = self.sprite:width() / 2 62 | local oy = self.sprite:height() 63 | self.sprite:draw(self.x, self.y + self.z, 0, sx, sy, ox, oy) 64 | end 65 | -------------------------------------------------------------------------------- /examples/dungeon/cursor.lua: -------------------------------------------------------------------------------- 1 | class "Cursor" 2 | 3 | function Cursor:new(img) 4 | self.img = img 5 | self.angle = 0 6 | end 7 | 8 | function Cursor:update(dt) 9 | self.angle = self.angle + 2 * dt 10 | end 11 | 12 | function Cursor:draw() 13 | local x, y = spry.mouse_pos() 14 | if x == 0 and y == 0 then 15 | return 16 | end 17 | 18 | x, y = camera:to_world_space(x, y) 19 | 20 | local ox = self.img:width() / 2 21 | local oy = self.img:height() / 2 22 | self.img:draw(x, y, self.angle, 1, 1, ox, oy) 23 | end 24 | -------------------------------------------------------------------------------- /examples/dungeon/cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/cursor.png -------------------------------------------------------------------------------- /examples/dungeon/elf.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/elf.ase -------------------------------------------------------------------------------- /examples/dungeon/enemy.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/enemy.ase -------------------------------------------------------------------------------- /examples/dungeon/main.lua: -------------------------------------------------------------------------------- 1 | function spry.conf(t) 2 | t.swap_interval = 1 3 | t.target_fps = 0 4 | t.reload_interval = 0.001 5 | t.window_width = 800 6 | t.window_height = 600 7 | end 8 | 9 | function spry.start(arg) 10 | if arg[#arg] == "-mobdebug" then unsafe_require "mobdebug".start() end 11 | if os.getenv "LOCAL_LUA_DEBUGGER_VSCODE" == "1" then unsafe_require "lldebugger".start() end 12 | 13 | font = spry.default_font() 14 | 15 | cursor = Cursor(spry.image_load "cursor.png") 16 | spry.show_mouse(false) 17 | 18 | b2 = spry.b2_world { gx = 0, gy = 0, meter = 16 } 19 | world = World() 20 | 21 | bow_img = spry.image_load "bow.png" 22 | arrow_img = spry.image_load "arrow.png" 23 | tilemap = spry.tilemap_load "map.ldtk" 24 | tilemap:make_collision(b2, "Collision", { 1 }) 25 | 26 | for k, v in ipairs(tilemap:entities()) do 27 | local mt = _G[v.id] 28 | if mt ~= nil then 29 | local obj = world:add(mt(v.x, v.y)) 30 | if v.id == "Player" then 31 | player = obj 32 | end 33 | else 34 | print("no " .. v.id .. " class exists") 35 | end 36 | end 37 | 38 | camera = Camera { 39 | x = player.x, 40 | y = player.y, 41 | scale = 5, 42 | } 43 | 44 | draw_fixtures = false 45 | spry.clear_color(48, 32, 32, 255) 46 | end 47 | 48 | function spry.frame(dt) 49 | if spry.platform() ~= "html5" and spry.key_down "esc" then 50 | spry.quit() 51 | end 52 | 53 | if spry.key_press "tab" then 54 | draw_fixtures = not draw_fixtures 55 | end 56 | 57 | b2:step(dt) 58 | world:update(dt) 59 | cursor:update(dt) 60 | 61 | local blend = 1 - 0.85 ^ (dt * 40) 62 | camera.x = lerp(camera.x, player.x, blend) 63 | camera.y = lerp(camera.y, player.y, blend) 64 | camera.scale = lerp(camera.scale, 2, dt ^ 0.8) 65 | 66 | camera:begin_draw() 67 | tilemap:draw() 68 | world:draw() 69 | cursor:draw() 70 | 71 | if draw_fixtures then 72 | tilemap:draw_fixtures(b2, "Collision") 73 | end 74 | camera:end_draw() 75 | 76 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 77 | end 78 | -------------------------------------------------------------------------------- /examples/dungeon/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | https://0x72.itch.io/dungeontileset-ii (CC0) -------------------------------------------------------------------------------- /examples/dungeon/tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/dungeon/tiles.png -------------------------------------------------------------------------------- /examples/ecs/main.lua: -------------------------------------------------------------------------------- 1 | function spry.conf(t) 2 | t.swap_interval = 0 3 | end 4 | 5 | function spry.start() 6 | ecs = ECS() 7 | 8 | for i = 1, 10 do 9 | ecs:add { 10 | pos = vec2(spry.window_width() / 2, spry.window_height() / 2), 11 | vel = vec2(random(-100, 100), random(-100, 100)), 12 | scale = 0.25, 13 | z_index = -1, 14 | img = spry.image_load "player.png", 15 | } 16 | end 17 | 18 | for i = 1, 10 do 19 | local id = ecs:add { 20 | pos = vec2(random(0, spry.window_width()), random(0, spry.window_height())), 21 | rot = { angle = random(0, math.pi), delta = random(-1, 1) }, 22 | scale = 1, 23 | z_index = 0, 24 | img = spry.image_load "player.png", 25 | } 26 | 27 | ecs:add { 28 | pos = vec2(random(0, spry.window_width()), random(0, spry.window_height())), 29 | follow = id, 30 | scale = 0.5, 31 | z_index = -10, 32 | img = spry.image_load "player.png", 33 | } 34 | end 35 | end 36 | 37 | function spry.frame(dt) 38 | ecs:update() 39 | 40 | for id, e in ecs:select { "pos", "vel" } do 41 | e.pos = e.pos + e.vel * vec2(dt, dt) 42 | 43 | if spry.key_down "p" then 44 | e.vel = nil 45 | end 46 | 47 | if spry.key_down "k" then 48 | ecs:kill(id) 49 | end 50 | end 51 | 52 | for id, e in ecs:select { "pos", "follow" } do 53 | local other = ecs:get(e.follow) 54 | if other ~= nil then 55 | e.pos = e.pos:lerp(other.pos, dt) 56 | end 57 | end 58 | 59 | for id, e in ecs:select { "pos", "rot" } do 60 | e.rot.angle = e.rot.angle + e.rot.delta * dt 61 | end 62 | 63 | for id, e in ecs:query { 64 | select = { "pos", "img", "z_index" }, 65 | where = function(e) 66 | return e.pos.x < spry.window_width() / 2 67 | end, 68 | order_by = function(lhs, rhs) 69 | return lhs.entity.z_index < rhs.entity.z_index 70 | end, 71 | } do 72 | local ox = e.img:width() * 0.5 73 | local oy = e.img:height() * 0.5 74 | local angle = e.rot and e.rot.angle or 0 75 | local scale = e.scale or 1 76 | 77 | e.img:draw(e.pos.x, e.pos.y, angle, scale * 3, scale * 3, ox, oy) 78 | 79 | if e.vel == nil and spry.key_down "v" then 80 | e.vel = vec2(4, 1) 81 | end 82 | end 83 | 84 | spry.default_font():draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 85 | end -------------------------------------------------------------------------------- /examples/ecs/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/ecs/player.png -------------------------------------------------------------------------------- /examples/ecs/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `player.png` https://www.kenney.nl/assets/pixel-platformer (CC0) -------------------------------------------------------------------------------- /examples/inheritance/animal.lua: -------------------------------------------------------------------------------- 1 | class "Animal" 2 | 3 | function Animal:new(x, y) 4 | self.x, self.y = x, y 5 | end 6 | 7 | function Animal:say() 8 | font:draw(("%s has %d legs"):format(self.kind, self.legs), self.x, self.y, 24) 9 | end 10 | -------------------------------------------------------------------------------- /examples/inheritance/crab.lua: -------------------------------------------------------------------------------- 1 | require "animal" 2 | class("Crab", Animal) 3 | 4 | function Crab:new(x, y) 5 | self.super.new(self, x, y) 6 | self.kind = "Crab" 7 | self.legs = 8 8 | end 9 | -------------------------------------------------------------------------------- /examples/inheritance/dog.lua: -------------------------------------------------------------------------------- 1 | require "animal" 2 | class("Dog", Animal) 3 | 4 | function Dog:new(x, y) 5 | self.super.new(self, x, y) 6 | self.kind = "Dog" 7 | self.legs = 4 8 | end 9 | -------------------------------------------------------------------------------- /examples/inheritance/main.lua: -------------------------------------------------------------------------------- 1 | function spry.start() 2 | font = spry.default_font() 3 | 4 | a = Dog(100, 100) 5 | b = Crab(100, 120) 6 | end 7 | 8 | function spry.frame(dt) 9 | if spry.platform() ~= "html5" and spry.key_down "esc" then 10 | spry.quit() 11 | end 12 | 13 | a:say() 14 | b:say() 15 | end 16 | -------------------------------------------------------------------------------- /examples/jump/atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/jump/atlas.png -------------------------------------------------------------------------------- /examples/jump/atlas.rtpa: -------------------------------------------------------------------------------- 1 | # 2 | # rTexPacker atlas descriptor file (v2.0) 3 | # 4 | # Number of packed sprites: 6 5 | # 6 | # Atlas info: a 7 | # Sprite info: s 8 | # 9 | a atlas.png 128 128 6 0 32 10 | s bg 0 0 102 2 16 16 0 0 0 0 16 16 11 | s platform 0 0 2 2 18 18 0 0 0 0 18 10 12 | s platform2 0 0 22 2 18 18 0 0 0 0 18 10 13 | s spikes 0 0 42 2 18 18 0 0 0 9 18 9 14 | s spring_down 0 0 62 2 18 18 0 0 0 8 18 10 15 | s spring_up 0 0 82 2 18 18 0 0 0 4 18 14 16 | -------------------------------------------------------------------------------- /examples/jump/camera.lua: -------------------------------------------------------------------------------- 1 | class "Camera" 2 | 3 | function Camera:new(def) 4 | self.x = def.x 5 | self.y = def.y 6 | self.scale = def.scale or 1 7 | end 8 | 9 | function Camera:to_world_space(x, y) 10 | x = x - spry.window_width() / 2 11 | y = y - spry.window_height() / 2 12 | 13 | x = x / camera.scale 14 | y = y / camera.scale 15 | 16 | x = x + camera.x 17 | y = y + camera.y 18 | 19 | return x, y 20 | end 21 | 22 | function Camera:to_screen_space(x, y) 23 | x = x + spry.window_width() / 2 24 | y = y + spry.window_height() / 2 25 | 26 | x = x * camera.scale 27 | y = y * camera.scale 28 | 29 | x = x - camera.x 30 | y = y - camera.y 31 | 32 | return x, y 33 | end 34 | 35 | function Camera:begin_draw() 36 | spry.push_matrix() 37 | spry.translate(spry.window_width() / 2, spry.window_height() / 2) 38 | spry.scale(self.scale, self.scale) 39 | spry.translate(-self.x, -self.y) 40 | end 41 | 42 | function Camera:end_draw() 43 | spry.pop_matrix() 44 | end 45 | -------------------------------------------------------------------------------- /examples/jump/jump.lua: -------------------------------------------------------------------------------- 1 | jump = {} 2 | 3 | function jump:reset() 4 | max_height = 0 5 | next_platform = -20 6 | game_over = false 7 | 8 | if world then 9 | world:destroy_all() 10 | end 11 | 12 | if b2 then 13 | b2:destroy() 14 | end 15 | 16 | b2 = spry.b2_world { gx = 0, gy = 9.81, meter = 16 } 17 | world = World() 18 | 19 | world:add(Player(0, -50)) 20 | world:add(Platform(0, 0)) 21 | 22 | camera = Camera { 23 | x = 0, 24 | y = 0, 25 | scale = 5, 26 | } 27 | end 28 | 29 | function jump:update() 30 | while next_platform > max_height - 200 do 31 | local right, top = camera:to_world_space(spry.window_width(), spry.window_height()) 32 | local left = -right 33 | 34 | local rx = random(left, right) 35 | 36 | local moving_chance 37 | if max_height < -4000 then 38 | moving_chance = 0.75 39 | elseif max_height < -2000 then 40 | moving_chance = 0.50 41 | elseif max_height < -1000 then 42 | moving_chance = 0.25 43 | else 44 | moving_chance = 0.10 45 | end 46 | 47 | local obj = (math.random() < moving_chance) and MovingPlatform or Platform 48 | world:add(obj(rx, next_platform)) 49 | 50 | if (obj == Platform) and (math.random() < 0.1) then 51 | world:add(SpringBox(rx, next_platform - 6)) 52 | end 53 | 54 | if (max_height < -1000) and (math.random() < 0.1) then 55 | local rx = random(left, right) 56 | local ry = next_platform + choose {-20, 20} 57 | world:add(Spikes(rx, ry - 5)) 58 | world:add(Platform(rx, ry)) 59 | end 60 | 61 | if max_height < -4000 then 62 | next_platform = next_platform - 60 63 | elseif max_height < -2000 then 64 | next_platform = next_platform - 40 65 | elseif max_height < -1000 then 66 | next_platform = next_platform - 30 67 | else 68 | next_platform = next_platform - 20 69 | end 70 | end 71 | end 72 | 73 | function jump.death_barrier(y) 74 | return y > max_height + 145 75 | end 76 | -------------------------------------------------------------------------------- /examples/jump/king-around-here.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/jump/king-around-here.ogg -------------------------------------------------------------------------------- /examples/jump/main.lua: -------------------------------------------------------------------------------- 1 | function spry.conf(t) 2 | t.swap_interval = 1 3 | t.window_width = 540 4 | t.window_height = 970 5 | t.window_title = "Jump Game" 6 | end 7 | 8 | function spry.start() 9 | font = spry.default_font() 10 | atlas = spry.atlas_load "atlas.rtpa" 11 | 12 | music = spry.sound_load "king-around-here.ogg" 13 | music:set_loop(true) 14 | music:set_vol(0.25) 15 | music:start() 16 | 17 | jump:reset() 18 | 19 | spry.clear_color(252, 223, 205, 255) 20 | 21 | 22 | muted = spry.platform() == "html5" 23 | end 24 | 25 | function spry.frame(dt) 26 | if spry.platform() ~= "html5" and spry.key_down "esc" then 27 | spry.quit() 28 | end 29 | 30 | if spry.key_press "m" then 31 | muted = not muted 32 | end 33 | 34 | if muted then 35 | spry.set_master_volume(0) 36 | else 37 | spry.set_master_volume(1) 38 | end 39 | 40 | 41 | if game_over and spry.key_release "space" then 42 | jump:reset() 43 | end 44 | 45 | jump:update() 46 | 47 | b2:step(dt) 48 | world:update(dt) 49 | 50 | local target_y = max_height 51 | 52 | local blend = 1 - 0.85 ^ (dt * 20) 53 | camera.y = lerp(camera.y, target_y, blend) 54 | 55 | camera:begin_draw() 56 | world:draw() 57 | camera:end_draw() 58 | 59 | spry.push_color(0, 0, 0, 255) 60 | if spry.platform() ~= "html5" then 61 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 62 | end 63 | 64 | local text_size = 80 65 | local text = ("%.0f"):format(-max_height) 66 | local x = (spry.window_width() - font:width(text, text_size)) / 2 67 | local y = 100 68 | font:draw(text, x, y, text_size) 69 | 70 | if game_over then 71 | text_size = 60 72 | text = "Game Over" 73 | x = (spry.window_width() - font:width(text, text_size)) / 2 74 | y = (spry.window_height() - text_size) / 2 - 50 75 | font:draw(text, x, y, text_size) 76 | 77 | text_size = 30 78 | text = "Space to restart" 79 | x = (spry.window_width() - font:width(text, text_size)) / 2 80 | y = (spry.window_height() - text_size) / 2 81 | font:draw(text, x, y, text_size) 82 | end 83 | spry.pop_color() 84 | end 85 | -------------------------------------------------------------------------------- /examples/jump/moving_platform.lua: -------------------------------------------------------------------------------- 1 | class "MovingPlatform" 2 | 3 | function MovingPlatform:new(x, y) 4 | self.x = x 5 | self.y = y 6 | self.img = atlas:get_image "platform2" 7 | end 8 | 9 | function MovingPlatform:on_create() 10 | self.body = b2:make_kinematic_body { 11 | x = self.x, 12 | y = self.y, 13 | vx = choose {-30, 30, -40, 40, -50, 50}, 14 | } 15 | 16 | self.body:make_box_fixture { 17 | w = 4, 18 | h = 2, 19 | udata = self.id, 20 | sensor = true, 21 | } 22 | end 23 | 24 | function MovingPlatform:on_death() 25 | self.body:destroy() 26 | end 27 | 28 | function MovingPlatform:update(dt) 29 | if jump.death_barrier(self.y) then 30 | world:kill(self) 31 | end 32 | 33 | self.x, self.y = self.body:position() 34 | 35 | local right, top = camera:to_world_space(spry.window_width(), spry.window_height()) 36 | right = right + 8 37 | local left = -right 38 | if self.x < left then 39 | self.x = right 40 | elseif self.x > right then 41 | self.x = left 42 | end 43 | self.body:set_position(self.x, self.y) 44 | end 45 | 46 | function MovingPlatform:draw() 47 | 48 | local ox = self.img:width() * 0.5 49 | local oy = self.img:height() * 0.5 50 | self.img:draw(self.x, self.y + 2, 0, 0.5, 0.5, ox, oy) 51 | --self.body:draw_fixtures() 52 | end 53 | -------------------------------------------------------------------------------- /examples/jump/phaseJump2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/jump/phaseJump2.ogg -------------------------------------------------------------------------------- /examples/jump/phaserUp1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/jump/phaserUp1.ogg -------------------------------------------------------------------------------- /examples/jump/platform.lua: -------------------------------------------------------------------------------- 1 | class "Platform" 2 | 3 | function Platform:new(x, y) 4 | self.x = x 5 | self.y = y 6 | self.img = atlas:get_image "platform" 7 | end 8 | 9 | function Platform:on_create() 10 | self.body = b2:make_static_body { x = self.x, y = self.y } 11 | self.body:make_box_fixture { 12 | w = 4, 13 | h = 2, 14 | udata = self.id, 15 | sensor = true, 16 | } 17 | end 18 | 19 | function Platform:on_death() 20 | self.body:destroy() 21 | end 22 | 23 | function Platform:update(dt) 24 | if jump.death_barrier(self.y) then 25 | world:kill(self) 26 | end 27 | end 28 | 29 | function Platform:draw() 30 | local ox = self.img:width() * 0.5 31 | local oy = self.img:height() * 0.5 32 | self.img:draw(self.x, self.y + 2, 0, 0.5, 0.5, ox, oy) 33 | --self.body:draw_fixtures() 34 | end 35 | -------------------------------------------------------------------------------- /examples/jump/player.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/jump/player.ase -------------------------------------------------------------------------------- /examples/jump/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `atlas.png` https://www.kenney.nl/assets/pixel-platformer (CC0) 4 | - `phaserUp1.ogg`, `phaseJump2.ogg` https://www.kenney.nl/assets/digital-audio (CC0) 5 | - `king-around-here.ogg` https://pixabay.com/music/beats-electronic-rock-king-around-here-15045/ (https://pixabay.com/service/license-summary/) -------------------------------------------------------------------------------- /examples/jump/spikes.lua: -------------------------------------------------------------------------------- 1 | class "Spikes" 2 | 3 | function Spikes:new(x, y) 4 | self.x = x 5 | self.y = y 6 | self.img = atlas:get_image "spikes" 7 | end 8 | 9 | function Spikes:on_create() 10 | self.body = b2:make_static_body { x = self.x, y = self.y } 11 | self.body:make_box_fixture { 12 | w = 4, 13 | h = 2, 14 | udata = self.id, 15 | sensor = true, 16 | } 17 | end 18 | 19 | function Spikes:on_death() 20 | self.body:destroy() 21 | end 22 | 23 | function Spikes:update(dt) 24 | if jump.death_barrier(self.y) then 25 | world:kill(self) 26 | end 27 | end 28 | 29 | function Spikes:draw() 30 | local ox = self.img:width() * 0.5 31 | local oy = self.img:height() * 0.5 32 | self.img:draw(self.x, self.y - 2, 0, 0.5, 0.5, ox, oy) 33 | --self.body:draw_fixtures() 34 | end 35 | -------------------------------------------------------------------------------- /examples/jump/spring_box.lua: -------------------------------------------------------------------------------- 1 | class "SpringBox" 2 | 3 | function SpringBox:new(x, y) 4 | self.x = x 5 | self.y = y 6 | 7 | self.is_up = false 8 | self.img_down = atlas:get_image "spring_down" 9 | self.img_up = atlas:get_image "spring_up" 10 | end 11 | 12 | function SpringBox:on_create() 13 | self.body = b2:make_static_body { x = self.x, y = self.y } 14 | self.body:make_box_fixture { 15 | w = 4, 16 | h = 2, 17 | udata = self.id, 18 | sensor = true, 19 | } 20 | end 21 | 22 | function SpringBox:on_death() 23 | self.body:destroy() 24 | end 25 | 26 | function SpringBox:update(dt) 27 | if jump.death_barrier(self.y) then 28 | world:kill(self) 29 | end 30 | end 31 | 32 | function SpringBox:draw() 33 | local x, y = self.body:position() 34 | 35 | local img = self.is_up and self.img_up or self.img_down 36 | 37 | local ox = img:width() * 0.5 38 | local oy = img:height() * 0.5 39 | img:draw(x, y - 1, 0, 0.5, 0.5, ox, oy) 40 | 41 | --self.body:draw_fixtures() 42 | end 43 | -------------------------------------------------------------------------------- /examples/networking/client/main.lua: -------------------------------------------------------------------------------- 1 | local socket = require "socket" 2 | 3 | function spry.conf(t) 4 | t.window_title = "Client" 5 | end 6 | 7 | function spry.start(arg) 8 | udp = socket.udp() 9 | udp:settimeout(0) 10 | udp:setpeername("127.0.0.1", 4242) 11 | 12 | my_id = os.time() 13 | entity = { 14 | x = 100, 15 | y = 100, 16 | } 17 | 18 | state = {} 19 | 20 | sendf("entity %d %d", entity.x, entity.y) 21 | 22 | font = spry.default_font() 23 | end 24 | 25 | send_update = coroutine.create(function() 26 | while true do 27 | sendf("entity %d %d", entity.x, entity.y) 28 | sendf "ping me" 29 | sleep(0.1) 30 | end 31 | end) 32 | 33 | recv_update = coroutine.create(function() 34 | while true do 35 | local data = udp:receive() 36 | if data ~= nil then 37 | local head, tail = data:match "(.-) (.*)" 38 | if head == "state" then 39 | local fn, err = load("return " .. tail) 40 | if not fn then 41 | error(err, 2) 42 | else 43 | state = fn() 44 | end 45 | end 46 | else 47 | coroutine.yield() 48 | end 49 | end 50 | end) 51 | 52 | function spry.frame(dt) 53 | if spry.platform() ~= "html5" and spry.key_down "esc" then 54 | spry.quit() 55 | end 56 | 57 | entity.x, entity.y = spry.mouse_pos() 58 | 59 | resume(send_update) 60 | resume(recv_update) 61 | 62 | font:draw(stringify(state), 40, 40, 18) 63 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 64 | end 65 | 66 | function sendf(fmt, ...) 67 | local payload = ("%d " .. fmt):format(my_id, ...) 68 | udp:send(payload) 69 | end 70 | -------------------------------------------------------------------------------- /examples/networking/server/main.lua: -------------------------------------------------------------------------------- 1 | -- this server works with a lua interpreter with luasockets, but you can also 2 | -- run this server with the spry binary 3 | 4 | local socket = require "socket" 5 | 6 | local udp = socket.udp() 7 | udp:settimeout(0) 8 | udp:setsockname("*", 4242) 9 | print "listening on port 4242" 10 | 11 | local state = {} 12 | local connections = {} 13 | 14 | local cmd = {} 15 | 16 | function cmd.entity(id, data) 17 | local x, y = data:match "(.-) (.*)" 18 | state[id] = { x = x, y = y } 19 | end 20 | 21 | function cmd.ping(id, data, ip, port) 22 | local arr = {} 23 | for k, v in pairs(state) do 24 | arr[#arr + 1] = ("[%s]={x=%s,y=%s}"):format(k, v.x, v.y) 25 | end 26 | local payload = "state {" .. table.concat(arr, ",") .. "}" 27 | udp:sendto(payload, ip, port) 28 | end 29 | 30 | while true do 31 | while true do 32 | local data, ip, port = udp:receivefrom() 33 | if data == nil then 34 | break 35 | end 36 | 37 | local id, head, tail = data:match "(.-) (.-) (.*)" 38 | connections[id] = os.time() 39 | 40 | local fn = cmd[head] 41 | if fn ~= nil then 42 | fn(id, tail, ip, port) 43 | end 44 | end 45 | 46 | -- remove connections after 3 seconds 47 | local now = os.time() 48 | local kill = {} 49 | for k, v in pairs(connections) do 50 | if os.difftime(now, v) >= 3 then 51 | kill[#kill + 1] = k 52 | end 53 | end 54 | 55 | for _, id in ipairs(kill) do 56 | connections[id] = nil 57 | state[id] = nil 58 | end 59 | 60 | socket.sleep(0.01) 61 | end 62 | 63 | -- quit before we make a window 64 | os.exit() -------------------------------------------------------------------------------- /examples/networking/server/server.py: -------------------------------------------------------------------------------- 1 | # python port of main.lua 2 | 3 | import re 4 | import socket 5 | import time 6 | 7 | udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 8 | udp.settimeout(0) 9 | udp.bind(("", 4242)) 10 | print("listening on port 4242") 11 | 12 | state = {} 13 | connections = {} 14 | 15 | cmd = {} 16 | 17 | def add_cmd(name): 18 | def decor(fn): 19 | cmd[name] = fn 20 | def handle(*args, **kwargs): 21 | fn(*args, **kwargs) 22 | return handle 23 | return decor 24 | 25 | @add_cmd("entity") 26 | def entity(ident, data, addr): 27 | x, y = re.search(r"(\S*) (.*)", data).groups() 28 | state[ident] = (x, y) 29 | 30 | @add_cmd("ping") 31 | def ping(ident, data, addr): 32 | arr = [f"[{k}]={{x={v[0]},y={v[1]}}}" for k, v in state.items()] 33 | payload = "state {" + ",".join(arr) + "}" 34 | udp.sendto(payload.encode(), addr) 35 | 36 | while True: 37 | while True: 38 | try: 39 | data, addr = udp.recvfrom(1024) 40 | 41 | ident, head, tail = re.search(r"(\S*) (\S*) (.*)", data.decode()).groups() 42 | connections[ident] = time.time() 43 | 44 | if head in cmd: 45 | cmd[head](ident, tail, addr) 46 | except socket.error: break 47 | 48 | # remove connections after 3 seconds 49 | now = time.time() 50 | for k in list(connections.keys()): 51 | if now - connections[k] >= 3: 52 | del connections[k] 53 | del state[k] 54 | 55 | time.sleep(0.01) 56 | -------------------------------------------------------------------------------- /examples/novel/bg/School_Hallway_Day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/bg/School_Hallway_Day.png -------------------------------------------------------------------------------- /examples/novel/bg/Train_Day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/bg/Train_Day.png -------------------------------------------------------------------------------- /examples/novel/char/Alice_Blush.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/char/Alice_Blush.png -------------------------------------------------------------------------------- /examples/novel/char/Alice_Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/char/Alice_Default.png -------------------------------------------------------------------------------- /examples/novel/char/Alice_Embarrassed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/char/Alice_Embarrassed.png -------------------------------------------------------------------------------- /examples/novel/char/Alice_Happy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/char/Alice_Happy.png -------------------------------------------------------------------------------- /examples/novel/char/Alice_Worried.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/char/Alice_Worried.png -------------------------------------------------------------------------------- /examples/novel/noto-sans-jp.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/novel/noto-sans-jp.ttf -------------------------------------------------------------------------------- /examples/novel/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - Character https://sutemo.itch.io/female-character 4 | - Background Images https://noranekogames.itch.io/yumebackground 5 | -------------------------------------------------------------------------------- /examples/novel/script.lua: -------------------------------------------------------------------------------- 1 | local function bg(name) 2 | if name then 3 | stat.bg = spry.image_load("bg/" .. name .. ".png", true) 4 | else 5 | stat.bg = nil 6 | end 7 | end 8 | 9 | local function ch(name) 10 | if name then 11 | stat.char = spry.image_load("char/" .. name .. ".png", true) 12 | else 13 | stat.char = nil 14 | end 15 | end 16 | 17 | function menu(tab) 18 | stat.menu_time = 0 19 | stat.menu = tab 20 | if #tab > 0 then 21 | return coroutine.yield() 22 | end 23 | end 24 | 25 | local function name(str) 26 | stat.name = str 27 | end 28 | 29 | local function color(r, g, b) 30 | if r then 31 | stat.color = {r, g, b, 255} 32 | else 33 | stat.color = nil 34 | end 35 | end 36 | 37 | local function say(str) 38 | stat.dialog_time = 0 39 | stat.dialog = str 40 | coroutine.yield() 41 | end 42 | 43 | local function _(str) 44 | name(nil) 45 | color(nil) 46 | say(str) 47 | end 48 | 49 | local function p(str) 50 | name "Player" 51 | color(255, 255, 255) 52 | say(str) 53 | end 54 | 55 | local function a(str) 56 | name "Alice" 57 | color(255, 96, 96) 58 | say(str) 59 | end 60 | 61 | script = coroutine.create(function() 62 | bg "Train_Day" 63 | _ "You're on the train on the way to school." 64 | _ "You hear the announcer through the train speakers." 65 | _ "\"The next station is, Aoyama-itchōme. Aoyama-itchōme.\"" 66 | _ "This is your stop. You leave the train." 67 | 68 | bg "School_Hallway_Day" 69 | _ "You arrived to school on time. You see one of your classmates walk towards you." 70 | 71 | ch "Alice_Blush" 72 | a "Hey! How was your weekend?" 73 | 74 | local i = menu { 75 | "It was fun!", 76 | "It was boring.", 77 | } 78 | ch "Alice_Default" 79 | 80 | if i == 1 then 81 | p "My weekend was great. I had a lot of fun." 82 | 83 | ch "Alice_Happy" 84 | a "I'm glad to hear it." 85 | 86 | elseif i == 2 then 87 | p "The weekend was pretty dull." 88 | 89 | ch "Alice_Worried" 90 | a "Aww. Well, maybe next week will be better." 91 | end 92 | 93 | _ "The school bell rings." 94 | 95 | ch "Alice_Default" 96 | a "Ah, I guess we'll talk later." 97 | 98 | ch "Alice_Embarrassed" 99 | a "See you!" 100 | 101 | ch() 102 | _ "Alice leaves." 103 | _ "You head to your classroom." 104 | end) 105 | -------------------------------------------------------------------------------- /examples/pathfinding/Grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/pathfinding/Grass.png -------------------------------------------------------------------------------- /examples/pathfinding/actor.lua: -------------------------------------------------------------------------------- 1 | class "Actor" 2 | 3 | function Actor:new(path) 4 | assert(#path ~= 0) 5 | 6 | self.path = path 7 | self.index = 1 8 | self.x, self.y = path[1].x, path[1].y 9 | self.vx, self.vy = 0, 0 10 | self.dx, self.dy = 0, 0 11 | self.sprite = spry.sprite_load "char.ase" 12 | self.spring = Spring() 13 | self.spring:pull(0.5) 14 | end 15 | 16 | function Actor:update(dt) 17 | self.spring:update(dt) 18 | self.sprite:update(dt) 19 | 20 | local top = self.path[self.index] 21 | local tx, ty = top.x, top.y 22 | 23 | if distance(self.x, self.y, tx, ty) < 2 then 24 | self.index = self.index + 1 25 | if self.index > #self.path then 26 | world:kill(self) 27 | end 28 | end 29 | 30 | local vx = tx - self.x 31 | local vy = ty - self.y 32 | vx, vy = normalize(vx, vy) 33 | 34 | local dx, dy = sign(vx), sign(vy) 35 | self.dx, self.dy = dx, dy 36 | 37 | if math.abs(vx) < 0.1 then 38 | if dy < 0 then 39 | self.sprite:play "walk_up" 40 | elseif dy > 0 then 41 | self.sprite:play "walk_down" 42 | end 43 | else 44 | if dx < 0 then 45 | self.sprite:play "walk_left" 46 | elseif dx > 0 then 47 | self.sprite:play "walk_right" 48 | end 49 | end 50 | 51 | local s = dt * 50 52 | self.x = self.x + vx * s 53 | self.y = self.y + vy * s 54 | end 55 | 56 | function Actor:draw() 57 | local x = self.x + tile / 2 58 | local y = self.y + tile / 2 59 | local sx = 1 + self.spring.x 60 | local sy = 1 - self.spring.x 61 | local ox = self.sprite:width() / 2 62 | local oy = self.sprite:height() / 2 63 | self.sprite:draw(x, y, 0, sx, sy, ox, oy) 64 | end 65 | -------------------------------------------------------------------------------- /examples/pathfinding/char.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/pathfinding/char.ase -------------------------------------------------------------------------------- /examples/pathfinding/chest.ase: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/pathfinding/chest.ase -------------------------------------------------------------------------------- /examples/pathfinding/main.lua: -------------------------------------------------------------------------------- 1 | function spry.conf(t) 2 | t.swap_interval = 1 3 | t.target_fps = 0 4 | end 5 | 6 | function spry.start() 7 | font = spry.default_font() 8 | 9 | map = spry.tilemap_load "map.ldtk" 10 | map:make_graph("IntGrid", { [1] = 1 }, 2) 11 | 12 | start = { x = 0, y = 0 } 13 | goal = { x = 0, y = 0 } 14 | 15 | world = World() 16 | 17 | scale = 2 18 | tile = 16 19 | 20 | spry.clear_color(155, 212, 195, 255) 21 | end 22 | 23 | function screen_to_world(x, y) 24 | x = x / scale 25 | y = y / scale 26 | 27 | return x, y 28 | end 29 | 30 | function spry.frame(dt) 31 | if spry.platform() ~= "html5" and spry.key_down "esc" then 32 | spry.quit() 33 | end 34 | 35 | if spry.mouse_down(0) then 36 | local x, y = spry.mouse_pos() 37 | start.x, start.y = screen_to_world(x, y) 38 | path = map:astar(start.x, start.y, goal.x, goal.y) 39 | if spry.mouse_click(0) and #path > 0 then 40 | world:add(Actor(path)) 41 | end 42 | end 43 | 44 | if spry.mouse_down(1) then 45 | local x, y = spry.mouse_pos() 46 | goal.x, goal.y = screen_to_world(x, y) 47 | path = map:astar(goal.x, goal.y, start.x, start.y) 48 | if spry.mouse_click(1) and #path > 0 then 49 | world:add(Actor(path)) 50 | end 51 | end 52 | 53 | world:update(dt) 54 | 55 | spry.push_matrix() 56 | spry.scale(scale, scale) 57 | map:draw() 58 | 59 | if path ~= nil then 60 | for i = 1, #path - 1 do 61 | local x0 = path[i + 0].x + tile / 2 62 | local y0 = path[i + 0].y + tile / 2 63 | local x1 = path[i + 1].x + tile / 2 64 | local y1 = path[i + 1].y + tile / 2 65 | 66 | spry.push_color(255, 0, i * 255 / #path, 255) 67 | spry.draw_line(x0, y0, x1, y1) 68 | spry.pop_color() 69 | end 70 | end 71 | 72 | world:draw() 73 | spry.pop_matrix() 74 | 75 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 76 | end 77 | -------------------------------------------------------------------------------- /examples/pathfinding/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | https://cupnooble.itch.io/sprout-lands-asset-pack (https://cupnooble.itch.io/) -------------------------------------------------------------------------------- /examples/planes/_composite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/planes/_composite.png -------------------------------------------------------------------------------- /examples/planes/atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/planes/atlas.png -------------------------------------------------------------------------------- /examples/planes/bullet.lua: -------------------------------------------------------------------------------- 1 | class "Bullet" 2 | 3 | function Bullet:new() 4 | self.x = 0 5 | self.y = 0 6 | self.angle = 0 7 | self.speed = 600 8 | self.lifetime = 0 9 | end 10 | 11 | function Bullet:on_death() 12 | local e = world:add(Explosion()) 13 | e.x = self.x 14 | e.y = self.y 15 | end 16 | 17 | function Bullet:update(dt) 18 | self.lifetime = self.lifetime + dt 19 | if self.lifetime > 5 then 20 | world:kill(self) 21 | end 22 | 23 | local vx, vy = heading(self.angle, self.speed) 24 | 25 | self.x = self.x + vx * dt 26 | self.y = self.y + vy * dt 27 | 28 | local enemies = world:query_mt(Enemy) 29 | for id, enemy in pairs(enemies) do 30 | local dist = distance(self.x, self.y, enemy.x, enemy.y) 31 | if dist < 40 then 32 | enemy:on_bullet_hit() 33 | world:kill(self) 34 | end 35 | end 36 | 37 | local rockets = world:query_mt(Rocket) 38 | for id, rocket in pairs(rockets) do 39 | local dist = distance(self.x, self.y, rocket.x, rocket.y) 40 | if dist < 20 then 41 | world:kill(rocket) 42 | world:kill(self) 43 | end 44 | end 45 | end 46 | 47 | function Bullet:draw() 48 | local tile = atlas:get_image "tile_0000" 49 | 50 | local r = self.angle + math.pi / 2 51 | local ox = tile:width() / 2 52 | local oy = tile:height() / 2 53 | 54 | tile:draw(self.x, self.y, r, 2, 2, ox, oy) 55 | end 56 | -------------------------------------------------------------------------------- /examples/planes/enemy.lua: -------------------------------------------------------------------------------- 1 | class "Enemy" 2 | 3 | function Enemy:new() 4 | self.spring = Spring() 5 | self.hp = 5 6 | self.x = random(0, spry.window_width()) 7 | self.z = 5 8 | self.rocket_cooldown = 3 9 | 10 | if math.random() < 0.5 then 11 | self.y = spry.window_height() 12 | self.angle = -math.pi / 2 13 | else 14 | self.y = 0 15 | self.angle = math.pi / 2 16 | end 17 | end 18 | 19 | function Enemy:on_death() 20 | for i = 1, 10 do 21 | timeout(random(0, 0.2), function() 22 | local e = world:add(Explosion()) 23 | e.x = self.x + random(-20, 20) 24 | e.y = self.y + random(-20, 20) 25 | end) 26 | end 27 | end 28 | 29 | function Enemy:update(dt) 30 | self.spring:update(dt) 31 | 32 | local enemies = world:query_mt(Enemy) 33 | for id, enemy in pairs(enemies) do 34 | if id ~= self.id then 35 | local dist = distance(self.x, self.y, enemy.x, enemy.y) 36 | if dist < 40 then 37 | world:kill(self) 38 | end 39 | end 40 | end 41 | 42 | self.rocket_cooldown = self.rocket_cooldown - dt 43 | if self.rocket_cooldown <= 0 then 44 | self.rocket_cooldown = self.rocket_cooldown + 5 45 | 46 | local r = world:add(Rocket()) 47 | 48 | r.owner = self.id 49 | r.x = self.x 50 | r.y = self.y 51 | r.angle = self.angle 52 | end 53 | 54 | local angle = direction(self.x, self.y, player.x, player.y) 55 | local delta = delta_angle(self.angle, angle) 56 | self.angle = self.angle + sign(delta) * dt * 0.2 57 | 58 | local vx, vy = heading(self.angle, 50) 59 | 60 | self.x = self.x + vx * dt 61 | self.y = self.y + vy * dt 62 | 63 | local dist = distance(self.x, self.y, player.x, player.y) 64 | if dist < 40 then 65 | world:kill(self) 66 | end 67 | end 68 | 69 | function Enemy:draw() 70 | local ship = atlas:get_image "ship_0013" 71 | 72 | local r = self.angle + math.pi / 2 73 | local sx = 2 + self.spring.x 74 | local sy = 2 - self.spring.x 75 | local ox = ship:width() / 2 76 | local oy = ship:height() / 2 77 | 78 | if self.rocket_cooldown < 0.5 then 79 | spry.push_color(255, 192, 128, 255) 80 | end 81 | 82 | ship:draw(self.x, self.y, r, sx, sy, ox, oy) 83 | 84 | if self.rocket_cooldown < 0.5 then 85 | spry.pop_color() 86 | end 87 | end 88 | 89 | function Enemy:on_bullet_hit() 90 | self.spring:pull(0.6) 91 | self.hp = self.hp - 1 92 | if self.hp == 0 then 93 | world:kill(self) 94 | end 95 | end -------------------------------------------------------------------------------- /examples/planes/explosion.lua: -------------------------------------------------------------------------------- 1 | class "Explosion" 2 | 3 | function Explosion:new() 4 | self.x = 0 5 | self.y = 0 6 | self.z = 50 7 | self.lifetime = 0 8 | end 9 | 10 | function Explosion:update(dt) 11 | self.lifetime = self.lifetime + dt 12 | 13 | if self.lifetime >= 0.1 then 14 | world:kill(self) 15 | end 16 | end 17 | 18 | function Explosion:draw() 19 | local tile = atlas:get_image "tile_0005" 20 | tile:draw(self.x, self.y, 0, 2, 2, tile:width() / 2, tile:height() / 2) 21 | end -------------------------------------------------------------------------------- /examples/planes/main.lua: -------------------------------------------------------------------------------- 1 | function spry.conf(t) 2 | t.swap_interval = 0 3 | t.reload_interval = 0.001 4 | t.window_width = 1366 5 | t.window_height = 768 6 | t.window_title = "Plane Game" 7 | end 8 | 9 | function spry.start(arg) 10 | if arg[#arg] == "-mobdebug" then unsafe_require "mobdebug".start() end 11 | if os.getenv "LOCAL_LUA_DEBUGGER_VSCODE" == "1" then unsafe_require "lldebugger".start() end 12 | 13 | composite = spry.image_load "_composite.png" 14 | atlas = spry.atlas_load "atlas.rtpa" 15 | world = World() 16 | 17 | interval(2, function() 18 | world:add(Enemy()) 19 | end) 20 | 21 | player = world:add(Player()) 22 | end 23 | 24 | function spry.frame(dt) 25 | if spry.platform() ~= "html5" and spry.key_down "esc" then 26 | spry.quit() 27 | end 28 | 29 | world:update(dt) 30 | 31 | composite:draw(0, 0, 0, 3, 3) 32 | world:draw() 33 | end 34 | -------------------------------------------------------------------------------- /examples/planes/player.lua: -------------------------------------------------------------------------------- 1 | class "Player" 2 | 3 | function Player:new() 4 | self.x = 100 5 | self.y = 100 6 | self.z = 10 7 | self.speed = 0 8 | self.angle = 0 9 | self.bullet_cooldown = 0 10 | self.spring = Spring() 11 | 12 | self.timer = interval(0.1, function() 13 | if self.speed > 100 then 14 | local s = world:add(Smoke()) 15 | s.x = self.x 16 | s.y = self.y 17 | s.scale = 1.5 18 | s.vx, s.vy = heading(self.angle - math.pi, 100) 19 | end 20 | end) 21 | end 22 | 23 | function Player:on_death() 24 | stop_interval(self.timer) 25 | end 26 | 27 | function Player:update(dt) 28 | self.spring:update(dt) 29 | 30 | local turn_speed = 4 31 | local max_speed = 300 32 | if spry.key_down "space" then 33 | turn_speed = 1 34 | max_speed = 100 35 | end 36 | 37 | local blend = 1 - 0.85 ^ (dt * 20) 38 | if spry.key_down "w" then 39 | self.speed = lerp(self.speed, max_speed, blend) 40 | else 41 | self.speed = lerp(self.speed, 0, blend) 42 | end 43 | 44 | if spry.key_down "a" then self.angle = self.angle - dt * turn_speed end 45 | if spry.key_down "d" then self.angle = self.angle + dt * turn_speed end 46 | 47 | self.bullet_cooldown = self.bullet_cooldown - dt 48 | if spry.key_down "space" and self.bullet_cooldown <= 0 then 49 | self.bullet_cooldown = 0.15 50 | self.spring:pull(0.1) 51 | 52 | local vx, vy = heading(self.angle - math.pi, 5) 53 | self.x = self.x + vx 54 | self.y = self.y + vy 55 | 56 | local b = world:add(Bullet()) 57 | b.x = self.x 58 | b.y = self.y 59 | b.angle = self.angle + random(-0.1, 0.1) 60 | b.speed = b.speed + self.speed 61 | end 62 | 63 | local vx, vy = heading(self.angle, self.speed) 64 | 65 | self.x = self.x + vx * dt 66 | self.y = self.y + vy * dt 67 | 68 | self.x = clamp(self.x, 0, spry.window_width()) 69 | self.y = clamp(self.y, 0, spry.window_height()) 70 | end 71 | 72 | function Player:draw() 73 | local ship = atlas:get_image "ship_0000" 74 | 75 | local r = self.angle + math.pi / 2 76 | local sx = 2 + self.spring.x 77 | local sy = 2 - self.spring.x 78 | local ox = ship:width() / 2 79 | local oy = ship:height() / 2 80 | 81 | ship:draw(self.x, self.y, r, sx, sy, ox, oy) 82 | end -------------------------------------------------------------------------------- /examples/planes/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `atlas.png`, `_composite.png` https://www.kenney.nl/assets/pixel-shmup (CC0) -------------------------------------------------------------------------------- /examples/planes/rocket.lua: -------------------------------------------------------------------------------- 1 | class "Rocket" 2 | 3 | function Rocket:new() 4 | self.x = 0 5 | self.y = 0 6 | self.angle = 0 7 | self.lifetime = 0 8 | 9 | self.timer = interval(0.1, function() 10 | local s = world:add(Smoke()) 11 | s.x = self.x 12 | s.y = self.y 13 | s.scale = 1 14 | s.max_lifetime = 0.2 15 | s.vx, s.vy = heading(self.angle - math.pi, 50) 16 | end) 17 | end 18 | 19 | function Rocket:on_death() 20 | local e = world:add(Explosion()) 21 | e.x = self.x 22 | e.y = self.y 23 | 24 | stop_interval(self.timer) 25 | end 26 | 27 | function Rocket:update(dt) 28 | self.lifetime = self.lifetime + dt 29 | if self.lifetime > 8 then 30 | world:kill(self) 31 | end 32 | 33 | local angle = direction(self.x, self.y, player.x, player.y) 34 | local delta = delta_angle(self.angle, angle) 35 | self.angle = self.angle + sign(delta) * dt * 0.8 36 | 37 | local vx, vy = heading(self.angle, 200) 38 | 39 | self.x = self.x + vx * dt 40 | self.y = self.y + vy * dt 41 | 42 | local rockets = world:query_mt(Rocket) 43 | for id, rocket in pairs(rockets) do 44 | if id ~= self.id then 45 | local dist = distance(self.x, self.y, rocket.x, rocket.y) 46 | if dist < 20 then 47 | world:kill(self) 48 | end 49 | end 50 | end 51 | 52 | local enemies = world:query_mt(Enemy) 53 | for id, enemy in pairs(enemies) do 54 | if id == self.owner then 55 | goto continue 56 | end 57 | 58 | local dist = distance(self.x, self.y, enemy.x, enemy.y) 59 | if dist < 40 then 60 | enemy:on_bullet_hit() 61 | world:kill(self) 62 | end 63 | 64 | ::continue:: 65 | end 66 | 67 | local dist = distance(self.x, self.y, player.x, player.y) 68 | if dist < 40 then 69 | world:kill(self) 70 | end 71 | end 72 | 73 | function Rocket:draw() 74 | local tile = atlas:get_image "tile_0012" 75 | 76 | local r = self.angle + math.pi / 2 77 | local ox = tile:width() / 2 78 | local oy = tile:height() / 2 79 | 80 | tile:draw(self.x, self.y, r, 2, 2, ox, oy) 81 | end 82 | -------------------------------------------------------------------------------- /examples/planes/smoke.lua: -------------------------------------------------------------------------------- 1 | class "Smoke" 2 | 3 | function Smoke:new() 4 | self.x = 0 5 | self.y = 0 6 | self.z = -1 7 | self.vx = 0 8 | self.vy = 0 9 | self.rotation = random(-1, 1) 10 | self.angle = 0 11 | self.lifetime = 0 12 | self.max_lifetime = 0.4 13 | self.scale = 1 14 | end 15 | 16 | function Smoke:update(dt) 17 | self.lifetime = self.lifetime + dt 18 | if self.lifetime >= self.max_lifetime then 19 | world:kill(self) 20 | end 21 | 22 | self.x = self.x + self.vx * dt 23 | self.y = self.y + self.vy * dt 24 | 25 | self.angle = self.angle + self.rotation * dt 26 | end 27 | 28 | function Smoke:draw() 29 | local tile = atlas:get_image "tile_0008" 30 | local fade = (1 - (self.lifetime / self.max_lifetime)) * 255 31 | spry.push_color(255, 255, 255, fade) 32 | tile:draw(self.x, self.y, self.angle, self.scale, self.scale, tile:width() / 2, tile:height() / 2) 33 | spry.pop_color() 34 | end -------------------------------------------------------------------------------- /examples/sampler/main.lua: -------------------------------------------------------------------------------- 1 | function spry.start() 2 | font = spry.default_font() 3 | 4 | player = spry.image_load "player.png" 5 | 6 | nearest = spry.make_sampler { 7 | min_filter = "nearest", 8 | mag_filter = "nearest", 9 | } 10 | 11 | linear = spry.make_sampler { 12 | min_filter = "linear", 13 | mag_filter = "linear", 14 | } 15 | 16 | wrap = spry.make_sampler { 17 | wrap_u = "repeat", 18 | wrap_v = "repeat", 19 | } 20 | 21 | mirrored = spry.make_sampler { 22 | wrap_u = "mirroredrepeat", 23 | wrap_v = "mirroredrepeat", 24 | } 25 | 26 | clamp = spry.make_sampler { 27 | wrap_u = "clamp", 28 | wrap_v = "clamp", 29 | } 30 | 31 | linear_clamp = spry.make_sampler { 32 | min_filter = "linear", 33 | mag_filter = "linear", 34 | wrap_u = "clamp", 35 | wrap_v = "clamp", 36 | } 37 | end 38 | 39 | function spry.frame(dt) 40 | nearest:use() 41 | font:draw("Hello, World!", 100, 100, 16) 42 | linear:use() 43 | font:draw("Hello, World!", 100, 140, 16) 44 | 45 | local rot = 0 46 | local sx, sy = 3, 3 47 | local ox, oy = 0, 0 48 | local u0, v0, u1, v1 = -0.5, -0.5, 1.5, 1.5 49 | 50 | wrap:use() 51 | player:draw(200, 200, rot, sx, sy, ox, oy, u0, v0, u1, v1) 52 | mirrored:use() 53 | player:draw(300, 300, rot, sx, sy, ox, oy, u0, v0, u1, v1) 54 | clamp:use() 55 | player:draw(400, 400, rot, sx, sy, ox, oy, u0, v0, u1, v1) 56 | 57 | linear_clamp:use() 58 | player:draw(0, 0, rot, sx, sy, ox, oy, u0, v0, u1, v1) 59 | 60 | font:draw(("fps: %.2f (%.4f)"):format(1 / dt, dt * 1000)) 61 | end -------------------------------------------------------------------------------- /examples/sampler/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/examples/sampler/player.png -------------------------------------------------------------------------------- /examples/sampler/readme.md: -------------------------------------------------------------------------------- 1 | ## Assets 2 | 3 | - `player.png` https://www.kenney.nl/assets/pixel-platformer (CC0) -------------------------------------------------------------------------------- /html5/data/main.lua: -------------------------------------------------------------------------------- 1 | function spry.start() 2 | font = spry.default_font() 3 | end 4 | 5 | function spry.frame(dt) 6 | font:draw("Hello, World!", 100, 100, 36) 7 | end -------------------------------------------------------------------------------- /html5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 16 |
17 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /html5/readme.md: -------------------------------------------------------------------------------- 1 | # Spry - HTML5 Version 2 | 3 | This directory contains the web version of Spry. Run a local web server in 4 | this location to run Spry in a browser: 5 | 6 | ``` 7 | python -m http.server 8 | php -S localhost:8080 9 | npx live-server 10 | ``` 11 | 12 | Read the [Distribution](https://jasonliang.js.org/spry/distribution.html) 13 | guide for more info. -------------------------------------------------------------------------------- /html5/spry.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/html5/spry.wasm -------------------------------------------------------------------------------- /src/algebra.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(_M_AMD64) || defined(__SSE__) 4 | #ifndef SSE_AVAILABLE 5 | #define SSE_AVAILABLE 6 | #endif 7 | #include 8 | #endif 9 | 10 | union Vector4 { 11 | struct { 12 | float x, y, z, w; 13 | }; 14 | float arr[4]; 15 | #ifdef SSE_AVAILABLE 16 | __m128 sse; 17 | #endif 18 | }; 19 | 20 | inline Vector4 vec4(float x, float y, float z, float w) { 21 | Vector4 v = {}; 22 | #ifdef SSE_AVAILABLE 23 | v.sse = _mm_set_ps(w, z, y, x); 24 | #else 25 | v.x = x; 26 | v.y = y; 27 | v.z = z; 28 | v.w = w; 29 | #endif 30 | return v; 31 | } 32 | 33 | inline Vector4 vec4_xy(float x, float y) { 34 | Vector4 v = {}; 35 | #ifdef SSE_AVAILABLE 36 | v.sse = _mm_set_ps(1, 0, y, x); 37 | #else 38 | v.x = x; 39 | v.y = y; 40 | v.w = 1; 41 | #endif 42 | return v; 43 | } 44 | 45 | union Matrix4 { 46 | float cols[4][4]; 47 | Vector4 vecs[4]; 48 | #ifdef SSE_AVAILABLE 49 | __m128 sse[4]; 50 | #endif 51 | }; 52 | 53 | inline Vector4 vec4_mul_mat4(Vector4 v, Matrix4 m) { 54 | #ifdef SSE_AVAILABLE 55 | __m128 mul0 = _mm_mul_ps(_mm_shuffle_ps(v.sse, v.sse, 0x00), m.sse[0]); 56 | __m128 mul1 = _mm_mul_ps(_mm_shuffle_ps(v.sse, v.sse, 0x55), m.sse[1]); 57 | __m128 mul2 = _mm_mul_ps(_mm_shuffle_ps(v.sse, v.sse, 0xaa), m.sse[2]); 58 | __m128 mul3 = _mm_mul_ps(_mm_shuffle_ps(v.sse, v.sse, 0xff), m.sse[3]); 59 | 60 | Vector4 out = {}; 61 | out.sse = _mm_add_ps(_mm_add_ps(mul0, mul1), _mm_add_ps(mul2, mul3)); 62 | return out; 63 | #else 64 | Vector4 out = {}; 65 | for (int i = 0; i < 4; i++) { 66 | out.x += v.arr[i] * m.cols[i][0]; 67 | out.y += v.arr[i] * m.cols[i][1]; 68 | out.z += v.arr[i] * m.cols[i][2]; 69 | out.w += v.arr[i] * m.cols[i][3]; 70 | } 71 | return out; 72 | #endif 73 | } 74 | 75 | inline Matrix4 mat4_mul_mat4(Matrix4 lhs, Matrix4 rhs) { 76 | Matrix4 m = {}; 77 | m.vecs[0] = vec4_mul_mat4(rhs.vecs[0], lhs); 78 | m.vecs[1] = vec4_mul_mat4(rhs.vecs[1], lhs); 79 | m.vecs[2] = vec4_mul_mat4(rhs.vecs[2], lhs); 80 | m.vecs[3] = vec4_mul_mat4(rhs.vecs[3], lhs); 81 | return m; 82 | } 83 | -------------------------------------------------------------------------------- /src/api.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct lua_State; 4 | void open_spry_api(lua_State *L); 5 | void open_luasocket(lua_State *L); -------------------------------------------------------------------------------- /src/app.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "array.h" 4 | #include "deps/luaalloc.h" 5 | #include "deps/sokol_gfx.h" 6 | #include "deps/sokol_gl.h" 7 | #include "font.h" 8 | #include "slice.h" 9 | #include "sound.h" 10 | #include 11 | 12 | #define SPRY_VERSION "0.8" 13 | 14 | struct AppTime { 15 | u64 startup; 16 | u64 last; 17 | u64 accumulator; 18 | u64 target_ticks; 19 | double delta; 20 | }; 21 | 22 | struct lua_State; 23 | struct App { 24 | Mutex gpu_mtx; 25 | 26 | LuaAlloc *LA; 27 | lua_State *L; 28 | 29 | AppTime time; 30 | 31 | bool win_console; 32 | Slice args; 33 | 34 | std::atomic main_thread_id; 35 | std::atomic error_mode; 36 | std::atomic is_fused; 37 | 38 | Mutex error_mtx; 39 | String fatal_error; 40 | String traceback; 41 | 42 | std::atomic hot_reload_enabled; 43 | std::atomic reload_interval; 44 | 45 | bool key_state[349]; 46 | bool prev_key_state[349]; 47 | 48 | bool mouse_state[3]; 49 | bool prev_mouse_state[3]; 50 | float prev_mouse_x; 51 | float prev_mouse_y; 52 | float mouse_x; 53 | float mouse_y; 54 | float scroll_x; 55 | float scroll_y; 56 | 57 | FontFamily *default_font; 58 | 59 | void *miniaudio_vfs; 60 | ma_engine audio_engine; 61 | Array garbage_sounds; 62 | }; 63 | 64 | extern App *g_app; 65 | 66 | inline void fatal_error(String str) { 67 | if (!g_app->error_mode.load()) { 68 | LockGuard lock{&g_app->error_mtx}; 69 | 70 | g_app->fatal_error = to_cstr(str); 71 | fprintf(stderr, "%s\n", g_app->fatal_error.data); 72 | g_app->error_mode.store(true); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/arena.cpp: -------------------------------------------------------------------------------- 1 | #include "arena.h" 2 | 3 | struct ArenaNode { 4 | ArenaNode *next; 5 | u64 capacity; 6 | u64 allocd; 7 | u64 prev; 8 | u8 buf[1]; 9 | }; 10 | 11 | static u64 align_forward(u64 p, u32 align) { 12 | if ((p & (align - 1)) != 0) { 13 | p += align - (p & (align - 1)); 14 | } 15 | return p; 16 | } 17 | 18 | static ArenaNode *arena_block_make(u64 capacity) { 19 | u64 page = 4096 - offsetof(ArenaNode, buf); 20 | if (capacity < page) { 21 | capacity = page; 22 | } 23 | 24 | ArenaNode *a = (ArenaNode *)mem_alloc(offsetof(ArenaNode, buf[capacity])); 25 | a->next = nullptr; 26 | a->allocd = 0; 27 | a->capacity = capacity; 28 | return a; 29 | } 30 | 31 | void Arena::trash() { 32 | ArenaNode *a = head; 33 | while (a != nullptr) { 34 | ArenaNode *rm = a; 35 | a = a->next; 36 | mem_free(rm); 37 | } 38 | } 39 | 40 | void *Arena::bump(u64 size) { 41 | if (head == nullptr) { 42 | head = arena_block_make(size); 43 | } 44 | 45 | u64 next = 0; 46 | do { 47 | next = align_forward(head->allocd, 16); 48 | if (next + size <= head->capacity) { 49 | break; 50 | } 51 | 52 | ArenaNode *block = arena_block_make(size); 53 | block->next = head; 54 | 55 | head = block; 56 | } while (true); 57 | 58 | void *ptr = &head->buf[next]; 59 | head->allocd = next + size; 60 | head->prev = next; 61 | return ptr; 62 | } 63 | 64 | void *Arena::rebump(void *ptr, u64 old, u64 size) { 65 | if (head == nullptr || ptr == nullptr || old == 0) { 66 | return bump(size); 67 | } 68 | 69 | if (&head->buf[head->prev] == ptr) { 70 | u64 resize = head->prev + size; 71 | if (resize <= head->capacity) { 72 | head->allocd = resize; 73 | return ptr; 74 | } 75 | } 76 | 77 | void *new_ptr = bump(size); 78 | 79 | u64 copy = old < size ? old : size; 80 | memmove(new_ptr, ptr, copy); 81 | 82 | return new_ptr; 83 | } 84 | 85 | String Arena::bump_string(String s) { 86 | if (s.len > 0) { 87 | char *cstr = (char *)bump(s.len + 1); 88 | memcpy(cstr, s.data, s.len); 89 | cstr[s.len] = '\0'; 90 | return {cstr, s.len}; 91 | } else { 92 | return {}; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/arena.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | struct ArenaNode; 6 | struct Arena { 7 | ArenaNode *head; 8 | 9 | void trash(); 10 | void *bump(u64 size); 11 | void *rebump(void *ptr, u64 old, u64 size); 12 | String bump_string(String s); 13 | }; 14 | -------------------------------------------------------------------------------- /src/array.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | template struct Array { 6 | T *data = nullptr; 7 | u64 len = 0; 8 | u64 capacity = 0; 9 | 10 | T &operator[](size_t i) { 11 | assert(i >= 0 && i < len); 12 | return data[i]; 13 | } 14 | 15 | void trash() { mem_free(data); } 16 | 17 | void reserve(u64 cap) { 18 | if (cap > capacity) { 19 | T *buf = (T *)mem_alloc(sizeof(T) * cap); 20 | memcpy(buf, data, sizeof(T) * len); 21 | mem_free(data); 22 | data = buf; 23 | capacity = cap; 24 | } 25 | } 26 | 27 | void resize(u64 n) { 28 | reserve(n); 29 | len = n; 30 | } 31 | 32 | void push(T item) { 33 | if (len == capacity) { 34 | reserve(len > 0 ? len * 2 : 8); 35 | } 36 | data[len] = item; 37 | len++; 38 | } 39 | 40 | T *begin() { return data; } 41 | T *end() { return &data[len]; } 42 | }; 43 | -------------------------------------------------------------------------------- /src/assets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "image.h" 4 | #include "sprite.h" 5 | #include "tilemap.h" 6 | 7 | enum AssetKind : i32 { 8 | AssetKind_None, 9 | AssetKind_LuaRef, 10 | AssetKind_Image, 11 | AssetKind_Sprite, 12 | AssetKind_Tilemap, 13 | }; 14 | 15 | struct AssetLoadData { 16 | AssetKind kind; 17 | bool generate_mips; 18 | }; 19 | 20 | struct Asset { 21 | String name; 22 | u64 hash; 23 | u64 modtime; 24 | AssetKind kind; 25 | union { 26 | i32 lua_ref; 27 | Image image; 28 | SpriteData sprite; 29 | Tilemap tilemap; 30 | }; 31 | }; 32 | 33 | void assets_shutdown(); 34 | void assets_start_hot_reload(); 35 | void assets_perform_hot_reload_changes(); 36 | 37 | bool asset_load_kind(AssetKind kind, String filepath, Asset *out); 38 | bool asset_load(AssetLoadData desc, String filepath, Asset *out); 39 | 40 | bool asset_read(u64 key, Asset *out); 41 | void asset_write(Asset asset); 42 | 43 | struct lua_State; 44 | Asset check_asset(lua_State *L, u64 key); 45 | Asset check_asset_mt(lua_State *L, i32 arg, const char *mt); 46 | -------------------------------------------------------------------------------- /src/atlas.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hash_map.h" 4 | #include "image.h" 5 | 6 | struct AtlasImage { 7 | float u0, v0, u1, v1; 8 | float width; 9 | float height; 10 | Image img; 11 | }; 12 | 13 | struct Atlas { 14 | HashMap by_name; 15 | Image img; 16 | 17 | bool load(String filepath, bool generate_mips); 18 | void trash(); 19 | AtlasImage *get(String name); 20 | }; 21 | -------------------------------------------------------------------------------- /src/concurrency.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | #include "slice.h" 5 | #include 6 | 7 | struct LuaThread { 8 | Mutex mtx; 9 | String contents; 10 | String name; 11 | Thread thread; 12 | 13 | void make(String code, String thread_name); 14 | void join(); 15 | }; 16 | 17 | struct lua_State; 18 | struct LuaTableEntry; 19 | struct LuaVariant { 20 | i32 type; 21 | union { 22 | bool boolean; 23 | double number; 24 | String string; 25 | Slice table; 26 | struct { 27 | void *ptr; 28 | String tname; 29 | } udata; 30 | }; 31 | 32 | void make(lua_State *L, i32 arg); 33 | void trash(); 34 | void push(lua_State *L); 35 | }; 36 | 37 | struct LuaTableEntry { 38 | LuaVariant key; 39 | LuaVariant value; 40 | }; 41 | 42 | struct LuaChannel { 43 | std::atomic name; 44 | 45 | Mutex mtx; 46 | Cond received; 47 | Cond sent; 48 | 49 | u64 received_total; 50 | u64 sent_total; 51 | 52 | Slice items; 53 | u64 front; 54 | u64 back; 55 | u64 len; 56 | 57 | void make(String n, u64 buf); 58 | void trash(); 59 | void send(LuaVariant item); 60 | LuaVariant recv(); 61 | bool try_recv(LuaVariant *v); 62 | }; 63 | 64 | LuaChannel *lua_channel_make(String name, u64 buf); 65 | LuaChannel *lua_channel_get(String name); 66 | LuaChannel *lua_channels_select(lua_State *L, LuaVariant *v); 67 | void lua_channels_setup(); 68 | void lua_channels_shutdown(); 69 | -------------------------------------------------------------------------------- /src/deps.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #pragma comment(lib, "ws2_32") 3 | #endif 4 | 5 | #define CUTE_ASEPRITE_IMPLEMENTATION 6 | #include "deps/cute_aseprite.h" 7 | 8 | #include "deps/luaalloc.c" 9 | 10 | extern "C" { 11 | #define MAKE_LIB 12 | #include "deps/lua/onelua.c" 13 | } 14 | 15 | #undef RELATIVE 16 | #undef ABSOLUTE 17 | #include "deps/microui.c" 18 | 19 | #include "deps/miniz.c" 20 | 21 | #define SOKOL_IMPL 22 | #if defined(_WIN32) 23 | #define SOKOL_D3D11 24 | #define SOKOL_WIN32_FORCE_MAIN 25 | #elif defined(__linux__) 26 | #define SOKOL_GLCORE33 27 | #elif defined(__EMSCRIPTEN__) 28 | #define SOKOL_GLES3 29 | #endif 30 | #include "deps/sokol_app.h" 31 | #include "deps/sokol_gfx.h" 32 | #include "deps/sokol_gl.h" 33 | #include "deps/sokol_glue.h" 34 | #include "deps/sokol_log.h" 35 | #include "deps/sokol_time.h" 36 | 37 | #define STB_IMAGE_IMPLEMENTATION 38 | #include "deps/stb_image.h" 39 | 40 | #define STB_IMAGE_RESIZE_IMPLEMENTATION 41 | #include "deps/stb_image_resize2.h" 42 | 43 | #define STB_TRUETYPE_IMPLEMENTATION 44 | #include "deps/stb_truetype.h" 45 | 46 | #define STB_VORBIS_HEADER_ONLY 47 | #include "deps/stb_vorbis.c" 48 | 49 | #ifdef __clang__ 50 | #pragma clang diagnostic push 51 | #pragma clang diagnostic ignored "-Wunused-function" 52 | #endif 53 | 54 | #define MA_ENABLE_ONLY_SPECIFIC_BACKENDS 55 | #define MA_ENABLE_WASAPI 56 | #define MA_ENABLE_ALSA 57 | #define MA_ENABLE_WEBAUDIO 58 | #define MA_NO_ENCODING 59 | #define MA_NO_GENERATION 60 | #define MINIAUDIO_IMPLEMENTATION 61 | #include "deps/miniaudio.h" 62 | 63 | #ifdef __clang__ 64 | #pragma clang diagnostic pop 65 | #endif 66 | 67 | #undef STB_VORBIS_HEADER_ONLY 68 | #include "deps/stb_vorbis.c" 69 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_api.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_API_H 24 | #define B2_API_H 25 | 26 | #ifdef B2_SHARED 27 | #if defined _WIN32 || defined __CYGWIN__ 28 | #ifdef box2d_EXPORTS 29 | #ifdef __GNUC__ 30 | #define B2_API __attribute__ ((dllexport)) 31 | #else 32 | #define B2_API __declspec(dllexport) 33 | #endif 34 | #else 35 | #ifdef __GNUC__ 36 | #define B2_API __attribute__ ((dllimport)) 37 | #else 38 | #define B2_API __declspec(dllimport) 39 | #endif 40 | #endif 41 | #else 42 | #if __GNUC__ >= 4 43 | #define B2_API __attribute__ ((visibility ("default"))) 44 | #else 45 | #define B2_API 46 | #endif 47 | #endif 48 | #else 49 | #define B2_API 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_block_allocator.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_BLOCK_ALLOCATOR_H 24 | #define B2_BLOCK_ALLOCATOR_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_settings.h" 28 | 29 | const int32 b2_blockSizeCount = 14; 30 | 31 | struct b2Block; 32 | struct b2Chunk; 33 | 34 | /// This is a small object allocator used for allocating small 35 | /// objects that persist for more than one time step. 36 | /// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp 37 | class B2_API b2BlockAllocator 38 | { 39 | public: 40 | b2BlockAllocator(); 41 | ~b2BlockAllocator(); 42 | 43 | /// Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize. 44 | void* Allocate(int32 size); 45 | 46 | /// Free memory. This will use b2Free if the size is larger than b2_maxBlockSize. 47 | void Free(void* p, int32 size); 48 | 49 | void Clear(); 50 | 51 | private: 52 | 53 | b2Chunk* m_chunks; 54 | int32 m_chunkCount; 55 | int32 m_chunkSpace; 56 | 57 | b2Block* m_freeLists[b2_blockSizeCount]; 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_circle_shape.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_CIRCLE_SHAPE_H 24 | #define B2_CIRCLE_SHAPE_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_shape.h" 28 | 29 | /// A solid circle shape 30 | class B2_API b2CircleShape : public b2Shape 31 | { 32 | public: 33 | b2CircleShape(); 34 | 35 | /// Implement b2Shape. 36 | b2Shape* Clone(b2BlockAllocator* allocator) const override; 37 | 38 | /// @see b2Shape::GetChildCount 39 | int32 GetChildCount() const override; 40 | 41 | /// Implement b2Shape. 42 | bool TestPoint(const b2Transform& transform, const b2Vec2& p) const override; 43 | 44 | /// Implement b2Shape. 45 | /// @note because the circle is solid, rays that start inside do not hit because the normal is 46 | /// not defined. 47 | bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, 48 | const b2Transform& transform, int32 childIndex) const override; 49 | 50 | /// @see b2Shape::ComputeAABB 51 | void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const override; 52 | 53 | /// @see b2Shape::ComputeMass 54 | void ComputeMass(b2MassData* massData, float density) const override; 55 | 56 | /// Position 57 | b2Vec2 m_p; 58 | }; 59 | 60 | inline b2CircleShape::b2CircleShape() 61 | { 62 | m_type = e_circle; 63 | m_radius = 0.0f; 64 | m_p.SetZero(); 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_contact_manager.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_CONTACT_MANAGER_H 24 | #define B2_CONTACT_MANAGER_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_broad_phase.h" 28 | 29 | class b2Contact; 30 | class b2ContactFilter; 31 | class b2ContactListener; 32 | class b2BlockAllocator; 33 | 34 | // Delegate of b2World. 35 | class B2_API b2ContactManager 36 | { 37 | public: 38 | b2ContactManager(); 39 | 40 | // Broad-phase callback. 41 | void AddPair(void* proxyUserDataA, void* proxyUserDataB); 42 | 43 | void FindNewContacts(); 44 | 45 | void Destroy(b2Contact* c); 46 | 47 | void Collide(); 48 | 49 | b2BroadPhase m_broadPhase; 50 | b2Contact* m_contactList; 51 | int32 m_contactCount; 52 | b2ContactFilter* m_contactFilter; 53 | b2ContactListener* m_contactListener; 54 | b2BlockAllocator* m_allocator; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_stack_allocator.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_STACK_ALLOCATOR_H 24 | #define B2_STACK_ALLOCATOR_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_settings.h" 28 | 29 | const int32 b2_stackSize = 100 * 1024; // 100k 30 | const int32 b2_maxStackEntries = 32; 31 | 32 | struct B2_API b2StackEntry 33 | { 34 | char* data; 35 | int32 size; 36 | bool usedMalloc; 37 | }; 38 | 39 | // This is a stack allocator used for fast per step allocations. 40 | // You must nest allocate/free pairs. The code will assert 41 | // if you try to interleave multiple allocate/free pairs. 42 | class B2_API b2StackAllocator 43 | { 44 | public: 45 | b2StackAllocator(); 46 | ~b2StackAllocator(); 47 | 48 | void* Allocate(int32 size); 49 | void Free(void* p); 50 | 51 | int32 GetMaxAllocation() const; 52 | 53 | private: 54 | 55 | char m_data[b2_stackSize]; 56 | int32 m_index; 57 | 58 | int32 m_allocation; 59 | int32 m_maxAllocation; 60 | 61 | b2StackEntry m_entries[b2_maxStackEntries]; 62 | int32 m_entryCount; 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_time_of_impact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_TIME_OF_IMPACT_H 24 | #define B2_TIME_OF_IMPACT_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_math.h" 28 | #include "b2_distance.h" 29 | 30 | /// Input parameters for b2TimeOfImpact 31 | struct B2_API b2TOIInput 32 | { 33 | b2DistanceProxy proxyA; 34 | b2DistanceProxy proxyB; 35 | b2Sweep sweepA; 36 | b2Sweep sweepB; 37 | float tMax; // defines sweep interval [0, tMax] 38 | }; 39 | 40 | /// Output parameters for b2TimeOfImpact. 41 | struct B2_API b2TOIOutput 42 | { 43 | enum State 44 | { 45 | e_unknown, 46 | e_failed, 47 | e_overlapped, 48 | e_touching, 49 | e_separated 50 | }; 51 | 52 | State state; 53 | float t; 54 | }; 55 | 56 | /// Compute the upper bound on time before two shapes penetrate. Time is represented as 57 | /// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate, 58 | /// non-tunneling collisions. If you change the time interval, you should call this function 59 | /// again. 60 | /// Note: use b2Distance to compute the contact point and normal at the time of impact. 61 | B2_API void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_time_step.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | #ifndef B2_TIME_STEP_H 23 | #define B2_TIME_STEP_H 24 | 25 | #include "b2_api.h" 26 | #include "b2_math.h" 27 | 28 | /// Profiling data. Times are in milliseconds. 29 | struct B2_API b2Profile 30 | { 31 | float step; 32 | float collide; 33 | float solve; 34 | float solveInit; 35 | float solveVelocity; 36 | float solvePosition; 37 | float broadphase; 38 | float solveTOI; 39 | }; 40 | 41 | /// This is an internal structure. 42 | struct B2_API b2TimeStep 43 | { 44 | float dt; // time step 45 | float inv_dt; // inverse time step (0 if dt == 0). 46 | float dtRatio; // dt * inv_dt0 47 | int32 velocityIterations; 48 | int32 positionIterations; 49 | bool warmStarting; 50 | }; 51 | 52 | /// This is an internal structure. 53 | struct B2_API b2Position 54 | { 55 | b2Vec2 c; 56 | float a; 57 | }; 58 | 59 | /// This is an internal structure. 60 | struct B2_API b2Velocity 61 | { 62 | b2Vec2 v; 63 | float w; 64 | }; 65 | 66 | /// Solver Data 67 | struct B2_API b2SolverData 68 | { 69 | b2TimeStep step; 70 | b2Position* positions; 71 | b2Velocity* velocities; 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_timer.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_TIMER_H 24 | #define B2_TIMER_H 25 | 26 | #include "b2_api.h" 27 | #include "b2_settings.h" 28 | 29 | /// Timer for profiling. This has platform specific code and may 30 | /// not work on every platform. 31 | class B2_API b2Timer 32 | { 33 | public: 34 | 35 | /// Constructor 36 | b2Timer(); 37 | 38 | /// Reset the timer. 39 | void Reset(); 40 | 41 | /// Get the time since construction or the last reset. 42 | float GetMilliseconds() const; 43 | 44 | private: 45 | 46 | #if defined(_WIN32) 47 | double m_start; 48 | static double s_invFrequency; 49 | #elif defined(__linux__) || defined (__APPLE__) 50 | unsigned long long m_start_sec; 51 | unsigned long long m_start_usec; 52 | #endif 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/b2_types.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2020 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_TYPES_H 24 | #define B2_TYPES_H 25 | 26 | typedef signed char int8; 27 | typedef signed short int16; 28 | typedef signed int int32; 29 | typedef unsigned char uint8; 30 | typedef unsigned short uint16; 31 | typedef unsigned int uint32; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/deps/box2d/box2d/box2d.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef BOX2D_H 24 | #define BOX2D_H 25 | 26 | // These include files constitute the main Box2D API 27 | 28 | #include "b2_settings.h" 29 | #include "b2_draw.h" 30 | #include "b2_timer.h" 31 | 32 | #include "b2_chain_shape.h" 33 | #include "b2_circle_shape.h" 34 | #include "b2_edge_shape.h" 35 | #include "b2_polygon_shape.h" 36 | 37 | #include "b2_broad_phase.h" 38 | #include "b2_dynamic_tree.h" 39 | 40 | #include "b2_body.h" 41 | #include "b2_contact.h" 42 | #include "b2_fixture.h" 43 | #include "b2_time_step.h" 44 | #include "b2_world.h" 45 | #include "b2_world_callbacks.h" 46 | 47 | #include "b2_distance_joint.h" 48 | #include "b2_friction_joint.h" 49 | #include "b2_gear_joint.h" 50 | #include "b2_motor_joint.h" 51 | #include "b2_mouse_joint.h" 52 | #include "b2_prismatic_joint.h" 53 | #include "b2_pulley_joint.h" 54 | #include "b2_revolute_joint.h" 55 | #include "b2_weld_joint.h" 56 | #include "b2_wheel_joint.h" 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/deps/box2d/common/b2_draw.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | #include "box2d/b2_draw.h" 23 | 24 | b2Draw::b2Draw() 25 | { 26 | m_drawFlags = 0; 27 | } 28 | 29 | void b2Draw::SetFlags(uint32 flags) 30 | { 31 | m_drawFlags = flags; 32 | } 33 | 34 | uint32 b2Draw::GetFlags() const 35 | { 36 | return m_drawFlags; 37 | } 38 | 39 | void b2Draw::AppendFlags(uint32 flags) 40 | { 41 | m_drawFlags |= flags; 42 | } 43 | 44 | void b2Draw::ClearFlags(uint32 flags) 45 | { 46 | m_drawFlags &= ~flags; 47 | } 48 | -------------------------------------------------------------------------------- /src/deps/box2d/common/b2_settings.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #define _CRT_SECURE_NO_WARNINGS 24 | 25 | #include "box2d/b2_settings.h" 26 | #include 27 | #include 28 | #include 29 | 30 | b2Version b2_version = {2, 4, 0}; 31 | 32 | // Memory allocators. Modify these to use your own allocator. 33 | void* b2Alloc_Default(int32 size) 34 | { 35 | return malloc(size); 36 | } 37 | 38 | void b2Free_Default(void* mem) 39 | { 40 | free(mem); 41 | } 42 | 43 | // You can modify this to use your logging facility. 44 | void b2Log_Default(const char* string, va_list args) 45 | { 46 | vprintf(string, args); 47 | } 48 | 49 | FILE* b2_dumpFile = nullptr; 50 | 51 | void b2OpenDump(const char* fileName) 52 | { 53 | b2Assert(b2_dumpFile == nullptr); 54 | b2_dumpFile = fopen(fileName, "w"); 55 | } 56 | 57 | void b2Dump(const char* string, ...) 58 | { 59 | if (b2_dumpFile == nullptr) 60 | { 61 | return; 62 | } 63 | 64 | va_list args; 65 | va_start(args, string); 66 | vfprintf(b2_dumpFile, string, args); 67 | va_end(args); 68 | } 69 | 70 | void b2CloseDump() 71 | { 72 | fclose(b2_dumpFile); 73 | b2_dumpFile = nullptr; 74 | } 75 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_chain_circle_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_CHAIN_AND_CIRCLE_CONTACT_H 24 | #define B2_CHAIN_AND_CIRCLE_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2ChainAndCircleContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); 38 | ~b2ChainAndCircleContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_chain_polygon_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_CHAIN_AND_POLYGON_CONTACT_H 24 | #define B2_CHAIN_AND_POLYGON_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2ChainAndPolygonContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); 38 | ~b2ChainAndPolygonContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_circle_contact.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "b2_circle_contact.h" 24 | #include "box2d/b2_block_allocator.h" 25 | #include "box2d/b2_body.h" 26 | #include "box2d/b2_fixture.h" 27 | #include "box2d/b2_time_of_impact.h" 28 | #include "box2d/b2_world_callbacks.h" 29 | 30 | #include 31 | 32 | b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) 33 | { 34 | void* mem = allocator->Allocate(sizeof(b2CircleContact)); 35 | return new (mem) b2CircleContact(fixtureA, fixtureB); 36 | } 37 | 38 | void b2CircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) 39 | { 40 | ((b2CircleContact*)contact)->~b2CircleContact(); 41 | allocator->Free(contact, sizeof(b2CircleContact)); 42 | } 43 | 44 | b2CircleContact::b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) 45 | : b2Contact(fixtureA, 0, fixtureB, 0) 46 | { 47 | b2Assert(m_fixtureA->GetType() == b2Shape::e_circle); 48 | b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); 49 | } 50 | 51 | void b2CircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) 52 | { 53 | b2CollideCircles(manifold, 54 | (b2CircleShape*)m_fixtureA->GetShape(), xfA, 55 | (b2CircleShape*)m_fixtureB->GetShape(), xfB); 56 | } 57 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_circle_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_CIRCLE_CONTACT_H 24 | #define B2_CIRCLE_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2CircleContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); 38 | ~b2CircleContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_edge_circle_contact.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "b2_edge_circle_contact.h" 24 | 25 | #include "box2d/b2_block_allocator.h" 26 | #include "box2d/b2_fixture.h" 27 | 28 | #include 29 | 30 | b2Contact* b2EdgeAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) 31 | { 32 | void* mem = allocator->Allocate(sizeof(b2EdgeAndCircleContact)); 33 | return new (mem) b2EdgeAndCircleContact(fixtureA, fixtureB); 34 | } 35 | 36 | void b2EdgeAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) 37 | { 38 | ((b2EdgeAndCircleContact*)contact)->~b2EdgeAndCircleContact(); 39 | allocator->Free(contact, sizeof(b2EdgeAndCircleContact)); 40 | } 41 | 42 | b2EdgeAndCircleContact::b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) 43 | : b2Contact(fixtureA, 0, fixtureB, 0) 44 | { 45 | b2Assert(m_fixtureA->GetType() == b2Shape::e_edge); 46 | b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); 47 | } 48 | 49 | void b2EdgeAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) 50 | { 51 | b2CollideEdgeAndCircle( manifold, 52 | (b2EdgeShape*)m_fixtureA->GetShape(), xfA, 53 | (b2CircleShape*)m_fixtureB->GetShape(), xfB); 54 | } 55 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_edge_circle_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_EDGE_AND_CIRCLE_CONTACT_H 24 | #define B2_EDGE_AND_CIRCLE_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2EdgeAndCircleContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); 38 | ~b2EdgeAndCircleContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_edge_polygon_contact.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "b2_edge_polygon_contact.h" 24 | 25 | #include "box2d/b2_block_allocator.h" 26 | #include "box2d/b2_fixture.h" 27 | 28 | #include 29 | 30 | b2Contact* b2EdgeAndPolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) 31 | { 32 | void* mem = allocator->Allocate(sizeof(b2EdgeAndPolygonContact)); 33 | return new (mem) b2EdgeAndPolygonContact(fixtureA, fixtureB); 34 | } 35 | 36 | void b2EdgeAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) 37 | { 38 | ((b2EdgeAndPolygonContact*)contact)->~b2EdgeAndPolygonContact(); 39 | allocator->Free(contact, sizeof(b2EdgeAndPolygonContact)); 40 | } 41 | 42 | b2EdgeAndPolygonContact::b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB) 43 | : b2Contact(fixtureA, 0, fixtureB, 0) 44 | { 45 | b2Assert(m_fixtureA->GetType() == b2Shape::e_edge); 46 | b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); 47 | } 48 | 49 | void b2EdgeAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) 50 | { 51 | b2CollideEdgeAndPolygon( manifold, 52 | (b2EdgeShape*)m_fixtureA->GetShape(), xfA, 53 | (b2PolygonShape*)m_fixtureB->GetShape(), xfB); 54 | } 55 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_edge_polygon_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_EDGE_AND_POLYGON_CONTACT_H 24 | #define B2_EDGE_AND_POLYGON_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2EdgeAndPolygonContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB); 38 | ~b2EdgeAndPolygonContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_polygon_circle_contact.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "b2_polygon_circle_contact.h" 24 | 25 | #include "box2d/b2_block_allocator.h" 26 | #include "box2d/b2_fixture.h" 27 | 28 | #include 29 | 30 | b2Contact* b2PolygonAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) 31 | { 32 | void* mem = allocator->Allocate(sizeof(b2PolygonAndCircleContact)); 33 | return new (mem) b2PolygonAndCircleContact(fixtureA, fixtureB); 34 | } 35 | 36 | void b2PolygonAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) 37 | { 38 | ((b2PolygonAndCircleContact*)contact)->~b2PolygonAndCircleContact(); 39 | allocator->Free(contact, sizeof(b2PolygonAndCircleContact)); 40 | } 41 | 42 | b2PolygonAndCircleContact::b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) 43 | : b2Contact(fixtureA, 0, fixtureB, 0) 44 | { 45 | b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); 46 | b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); 47 | } 48 | 49 | void b2PolygonAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) 50 | { 51 | b2CollidePolygonAndCircle( manifold, 52 | (b2PolygonShape*)m_fixtureA->GetShape(), xfA, 53 | (b2CircleShape*)m_fixtureB->GetShape(), xfB); 54 | } 55 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_polygon_circle_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_POLYGON_AND_CIRCLE_CONTACT_H 24 | #define B2_POLYGON_AND_CIRCLE_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2PolygonAndCircleContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 34 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 35 | 36 | b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); 37 | ~b2PolygonAndCircleContact() {} 38 | 39 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_polygon_contact.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "b2_polygon_contact.h" 24 | 25 | #include "box2d/b2_block_allocator.h" 26 | #include "box2d/b2_body.h" 27 | #include "box2d/b2_fixture.h" 28 | #include "box2d/b2_time_of_impact.h" 29 | #include "box2d/b2_world_callbacks.h" 30 | 31 | #include 32 | 33 | b2Contact* b2PolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator) 34 | { 35 | void* mem = allocator->Allocate(sizeof(b2PolygonContact)); 36 | return new (mem) b2PolygonContact(fixtureA, fixtureB); 37 | } 38 | 39 | void b2PolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) 40 | { 41 | ((b2PolygonContact*)contact)->~b2PolygonContact(); 42 | allocator->Free(contact, sizeof(b2PolygonContact)); 43 | } 44 | 45 | b2PolygonContact::b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB) 46 | : b2Contact(fixtureA, 0, fixtureB, 0) 47 | { 48 | b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); 49 | b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); 50 | } 51 | 52 | void b2PolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) 53 | { 54 | b2CollidePolygons( manifold, 55 | (b2PolygonShape*)m_fixtureA->GetShape(), xfA, 56 | (b2PolygonShape*)m_fixtureB->GetShape(), xfB); 57 | } 58 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_polygon_contact.h: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef B2_POLYGON_CONTACT_H 24 | #define B2_POLYGON_CONTACT_H 25 | 26 | #include "box2d/b2_contact.h" 27 | 28 | class b2BlockAllocator; 29 | 30 | class b2PolygonContact : public b2Contact 31 | { 32 | public: 33 | static b2Contact* Create( b2Fixture* fixtureA, int32 indexA, 34 | b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 35 | static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 36 | 37 | b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB); 38 | ~b2PolygonContact() {} 39 | 40 | void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) override; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/deps/box2d/dynamics/b2_world_callbacks.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | 3 | // Copyright (c) 2019 Erin Catto 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include "box2d/b2_fixture.h" 24 | #include "box2d/b2_world_callbacks.h" 25 | 26 | // Return true if contact calculations should be performed between these two shapes. 27 | // If you implement your own collision filter you may want to build from this implementation. 28 | bool b2ContactFilter::ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB) 29 | { 30 | const b2Filter& filterA = fixtureA->GetFilterData(); 31 | const b2Filter& filterB = fixtureB->GetFilterData(); 32 | 33 | if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0) 34 | { 35 | return filterA.groupIndex > 0; 36 | } 37 | 38 | bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0; 39 | return collide; 40 | } 41 | -------------------------------------------------------------------------------- /src/deps/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 17 | "stack overflow");} 18 | 19 | 20 | /* 21 | ** If a call returns too many multiple returns, the callee may not have 22 | ** stack space to accommodate all results. In this case, this macro 23 | ** increases its stack space ('L->ci->top'). 24 | */ 25 | #define adjustresults(L,nres) \ 26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 27 | 28 | 29 | /* Ensure the stack has at least 'n' elements */ 30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 31 | "not enough elements in the stack") 32 | 33 | 34 | /* 35 | ** To reduce the overhead of returning from C functions, the presence of 36 | ** to-be-closed variables in these functions is coded in the CallInfo's 37 | ** field 'nresults', in a way that functions with no to-be-closed variables 38 | ** with zero, one, or "all" wanted results have no overhead. Functions 39 | ** with other number of wanted results, as well as functions with 40 | ** variables to be closed, have an extra check. 41 | */ 42 | 43 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 44 | 45 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 46 | #define codeNresults(n) (-(n) - 3) 47 | #define decodeNresults(n) (-(n) - 3) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/deps/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/deps/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/deps/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/deps/lua/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /src/deps/lua/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /src/deps/lua/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/deps/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/deps/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 47 | TValue *value); 48 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 49 | const TValue *slot, TValue *value); 50 | LUAI_FUNC Table *luaH_new (lua_State *L); 51 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 52 | unsigned int nhsize); 53 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 54 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 55 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 56 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 57 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 58 | 59 | 60 | #if defined(LUA_DEBUG) 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 62 | LUAI_FUNC int luaH_isdummy (const Table *t); 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/deps/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/deps/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 26 | 27 | #define LUAC_FORMAT 0 /* this is the official format */ 28 | 29 | /* load one chunk; from lundump.c */ 30 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/deps/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/deps/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/deps/luasocket/auxiliar.h: -------------------------------------------------------------------------------- 1 | #ifndef AUXILIAR_H 2 | #define AUXILIAR_H 3 | /*=========================================================================*\ 4 | * Auxiliar routines for class hierarchy manipulation 5 | * LuaSocket toolkit (but completely independent of other LuaSocket modules) 6 | * 7 | * A LuaSocket class is a name associated with Lua metatables. A LuaSocket 8 | * group is a name associated with a class. A class can belong to any number 9 | * of groups. This module provides the functionality to: 10 | * 11 | * - create new classes 12 | * - add classes to groups 13 | * - set the class of objects 14 | * - check if an object belongs to a given class or group 15 | * - get the userdata associated to objects 16 | * - print objects in a pretty way 17 | * 18 | * LuaSocket class names follow the convention {}. Modules 19 | * can define any number of classes and groups. The module tcp.c, for 20 | * example, defines the classes tcp{master}, tcp{client} and tcp{server} and 21 | * the groups tcp{client,server} and tcp{any}. Module functions can then 22 | * perform type-checking on their arguments by either class or group. 23 | * 24 | * LuaSocket metatables define the __index metamethod as being a table. This 25 | * table has one field for each method supported by the class, and a field 26 | * "class" with the class name. 27 | * 28 | * The mapping from class name to the corresponding metatable and the 29 | * reverse mapping are done using lauxlib. 30 | \*=========================================================================*/ 31 | 32 | #include "luasocket.h" 33 | 34 | #ifndef _WIN32 35 | #pragma GCC visibility push(hidden) 36 | #endif 37 | 38 | int auxiliar_open(lua_State *L); 39 | void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func); 40 | int auxiliar_tostring(lua_State *L); 41 | void auxiliar_add2group(lua_State *L, const char *classname, const char *group); 42 | int auxiliar_checkboolean(lua_State *L, int objidx); 43 | void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); 44 | void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx); 45 | void auxiliar_setclass(lua_State *L, const char *classname, int objidx); 46 | void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx); 47 | void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx); 48 | int auxiliar_typeerror(lua_State *L, int narg, const char *tname); 49 | 50 | #ifndef _WIN32 51 | #pragma GCC visibility pop 52 | #endif 53 | 54 | #endif /* AUXILIAR_H */ 55 | -------------------------------------------------------------------------------- /src/deps/luasocket/buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef BUF_H 2 | #define BUF_H 3 | /*=========================================================================*\ 4 | * Input/Output interface for Lua programs 5 | * LuaSocket toolkit 6 | * 7 | * Line patterns require buffering. Reading one character at a time involves 8 | * too many system calls and is very slow. This module implements the 9 | * LuaSocket interface for input/output on connected objects, as seen by 10 | * Lua programs. 11 | * 12 | * Input is buffered. Output is *not* buffered because there was no simple 13 | * way of making sure the buffered output data would ever be sent. 14 | * 15 | * The module is built on top of the I/O abstraction defined in io.h and the 16 | * timeout management is done with the timeout.h interface. 17 | \*=========================================================================*/ 18 | #include "luasocket.h" 19 | #include "io.h" 20 | #include "timeout.h" 21 | 22 | /* buffer size in bytes */ 23 | #define BUF_SIZE 8192 24 | 25 | /* buffer control structure */ 26 | typedef struct t_buffer_ { 27 | double birthday; /* throttle support info: creation time, */ 28 | size_t sent, received; /* bytes sent, and bytes received */ 29 | p_io io; /* IO driver used for this buffer */ 30 | p_timeout tm; /* timeout management for this buffer */ 31 | size_t first, last; /* index of first and last bytes of stored data */ 32 | char data[BUF_SIZE]; /* storage space for buffer data */ 33 | } t_buffer; 34 | typedef t_buffer *p_buffer; 35 | 36 | #ifndef _WIN32 37 | #pragma GCC visibility push(hidden) 38 | #endif 39 | 40 | int buffer_open(lua_State *L); 41 | void buffer_init(p_buffer buf, p_io io, p_timeout tm); 42 | int buffer_meth_getstats(lua_State *L, p_buffer buf); 43 | int buffer_meth_setstats(lua_State *L, p_buffer buf); 44 | int buffer_meth_send(lua_State *L, p_buffer buf); 45 | int buffer_meth_receive(lua_State *L, p_buffer buf); 46 | int buffer_isempty(p_buffer buf); 47 | 48 | #ifndef _WIN32 49 | #pragma GCC visibility pop 50 | #endif 51 | 52 | #endif /* BUF_H */ 53 | -------------------------------------------------------------------------------- /src/deps/luasocket/compat.c: -------------------------------------------------------------------------------- 1 | #include "luasocket.h" 2 | #include "compat.h" 3 | 4 | #if LUA_VERSION_NUM==501 5 | 6 | /* 7 | ** Adapted from Lua 5.2 8 | */ 9 | void luasocket_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 10 | luaL_checkstack(L, nup+1, "too many upvalues"); 11 | for (; l->name != NULL; l++) { /* fill the table with given functions */ 12 | int i; 13 | lua_pushstring(L, l->name); 14 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ 15 | lua_pushvalue(L, -(nup+1)); 16 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 17 | lua_settable(L, -(nup + 3)); 18 | } 19 | lua_pop(L, nup); /* remove upvalues */ 20 | } 21 | 22 | /* 23 | ** Duplicated from Lua 5.2 24 | */ 25 | void *luasocket_testudata (lua_State *L, int ud, const char *tname) { 26 | void *p = lua_touserdata(L, ud); 27 | if (p != NULL) { /* value is a userdata? */ 28 | if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ 29 | luaL_getmetatable(L, tname); /* get correct metatable */ 30 | if (!lua_rawequal(L, -1, -2)) /* not the same? */ 31 | p = NULL; /* value is a userdata with wrong metatable */ 32 | lua_pop(L, 2); /* remove both metatables */ 33 | return p; 34 | } 35 | } 36 | return NULL; /* value is not a userdata with a metatable */ 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/deps/luasocket/compat.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPAT_H 2 | #define COMPAT_H 3 | 4 | #if LUA_VERSION_NUM==501 5 | 6 | #ifndef _WIN32 7 | #pragma GCC visibility push(hidden) 8 | #endif 9 | 10 | void luasocket_setfuncs (lua_State *L, const luaL_Reg *l, int nup); 11 | void *luasocket_testudata ( lua_State *L, int arg, const char *tname); 12 | 13 | #ifndef _WIN32 14 | #pragma GCC visibility pop 15 | #endif 16 | 17 | #define luaL_setfuncs luasocket_setfuncs 18 | #define luaL_testudata luasocket_testudata 19 | 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/deps/luasocket/except.h: -------------------------------------------------------------------------------- 1 | #ifndef EXCEPT_H 2 | #define EXCEPT_H 3 | /*=========================================================================*\ 4 | * Exception control 5 | * LuaSocket toolkit (but completely independent from other modules) 6 | * 7 | * This provides support for simple exceptions in Lua. During the 8 | * development of the HTTP/FTP/SMTP support, it became aparent that 9 | * error checking was taking a substantial amount of the coding. These 10 | * function greatly simplify the task of checking errors. 11 | * 12 | * The main idea is that functions should return nil as their first return 13 | * values when they find an error, and return an error message (or value) 14 | * following nil. In case of success, as long as the first value is not nil, 15 | * the other values don't matter. 16 | * 17 | * The idea is to nest function calls with the "try" function. This function 18 | * checks the first value, and, if it's falsy, wraps the second value in a 19 | * table with metatable and calls "error" on it. Otherwise, it returns all 20 | * values it received. Basically, it works like the Lua "assert" function, 21 | * but it creates errors targeted specifically at "protect". 22 | * 23 | * The "newtry" function is a factory for "try" functions that call a 24 | * finalizer in protected mode before calling "error". 25 | * 26 | * The "protect" function returns a new function that behaves exactly like 27 | * the function it receives, but the new function catches exceptions thrown 28 | * by "try" functions and returns nil followed by the error message instead. 29 | * 30 | * With these three functions, it's easy to write functions that throw 31 | * exceptions on error, but that don't interrupt the user script. 32 | \*=========================================================================*/ 33 | 34 | #include "luasocket.h" 35 | 36 | #ifndef _WIN32 37 | #pragma GCC visibility push(hidden) 38 | #endif 39 | 40 | int except_open(lua_State *L); 41 | 42 | #ifndef _WIN32 43 | #pragma GCC visibility pop 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/deps/luasocket/inet.h: -------------------------------------------------------------------------------- 1 | #ifndef INET_H 2 | #define INET_H 3 | /*=========================================================================*\ 4 | * Internet domain functions 5 | * LuaSocket toolkit 6 | * 7 | * This module implements the creation and connection of internet domain 8 | * sockets, on top of the socket.h interface, and the interface of with the 9 | * resolver. 10 | * 11 | * The function inet_aton is provided for the platforms where it is not 12 | * available. The module also implements the interface of the internet 13 | * getpeername and getsockname functions as seen by Lua programs. 14 | * 15 | * The Lua functions toip and tohostname are also implemented here. 16 | \*=========================================================================*/ 17 | #include "luasocket.h" 18 | #include "socket.h" 19 | #include "timeout.h" 20 | 21 | #ifdef _WIN32 22 | #define LUASOCKET_INET_ATON 23 | #endif 24 | 25 | #ifndef _WIN32 26 | #pragma GCC visibility push(hidden) 27 | #endif 28 | 29 | int inet_open(lua_State *L); 30 | 31 | int inet_optfamily(lua_State* L, int narg, const char* def); 32 | int inet_optsocktype(lua_State* L, int narg, const char* def); 33 | 34 | int inet_meth_getpeername(lua_State *L, p_socket ps, int family); 35 | int inet_meth_getsockname(lua_State *L, p_socket ps, int family); 36 | 37 | const char *inet_trycreate(p_socket ps, int family, int type, int protocol); 38 | const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm); 39 | const char *inet_tryconnect(p_socket ps, int *family, const char *address, const char *serv, p_timeout tm, struct addrinfo *connecthints); 40 | const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm); 41 | const char *inet_trybind(p_socket ps, int *family, const char *address, const char *serv, struct addrinfo *bindhints); 42 | 43 | #ifdef LUASOCKET_INET_ATON 44 | int inet_aton(const char *cp, struct in_addr *inp); 45 | #endif 46 | 47 | #ifdef LUASOCKET_INET_PTON 48 | const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); 49 | int inet_pton(int af, const char *src, void *dst); 50 | #endif 51 | 52 | #ifndef _WIN32 53 | #pragma GCC visibility pop 54 | #endif 55 | 56 | #endif /* INET_H */ 57 | -------------------------------------------------------------------------------- /src/deps/luasocket/io.c: -------------------------------------------------------------------------------- 1 | /*=========================================================================*\ 2 | * Input/Output abstraction 3 | * LuaSocket toolkit 4 | \*=========================================================================*/ 5 | #include "luasocket.h" 6 | #include "io.h" 7 | 8 | /*-------------------------------------------------------------------------*\ 9 | * Initializes C structure 10 | \*-------------------------------------------------------------------------*/ 11 | void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) { 12 | io->send = send; 13 | io->recv = recv; 14 | io->error = error; 15 | io->ctx = ctx; 16 | } 17 | 18 | /*-------------------------------------------------------------------------*\ 19 | * I/O error strings 20 | \*-------------------------------------------------------------------------*/ 21 | const char *io_strerror(int err) { 22 | switch (err) { 23 | case IO_DONE: return NULL; 24 | case IO_CLOSED: return "closed"; 25 | case IO_TIMEOUT: return "timeout"; 26 | default: return "unknown error"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/deps/luasocket/luasocket.h: -------------------------------------------------------------------------------- 1 | #ifndef LUASOCKET_H 2 | #define LUASOCKET_H 3 | /*=========================================================================*\ 4 | * LuaSocket toolkit 5 | * Networking support for the Lua language 6 | * Diego Nehab 7 | * 9/11/1999 8 | \*=========================================================================*/ 9 | 10 | /*-------------------------------------------------------------------------* \ 11 | * Current socket library version 12 | \*-------------------------------------------------------------------------*/ 13 | #define LUASOCKET_VERSION "LuaSocket 3.1.0" 14 | #define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab" 15 | 16 | /*-------------------------------------------------------------------------*\ 17 | * This macro prefixes all exported API functions 18 | \*-------------------------------------------------------------------------*/ 19 | #ifndef LUASOCKET_API 20 | #ifdef _WIN32 21 | #define LUASOCKET_API __declspec(dllexport) 22 | #else 23 | #define LUASOCKET_API __attribute__ ((visibility ("default"))) 24 | #endif 25 | #endif 26 | 27 | #include "lua.h" 28 | #include "lauxlib.h" 29 | #include "compat.h" 30 | 31 | /*-------------------------------------------------------------------------*\ 32 | * Initializes the library. 33 | \*-------------------------------------------------------------------------*/ 34 | LUASOCKET_API int luaopen_socket_core(lua_State *L); 35 | 36 | #endif /* LUASOCKET_H */ 37 | -------------------------------------------------------------------------------- /src/deps/luasocket/mime.h: -------------------------------------------------------------------------------- 1 | #ifndef MIME_H 2 | #define MIME_H 3 | /*=========================================================================*\ 4 | * Core MIME support 5 | * LuaSocket toolkit 6 | * 7 | * This module provides functions to implement transfer content encodings 8 | * and formatting conforming to RFC 2045. It is used by mime.lua, which 9 | * provide a higher level interface to this functionality. 10 | \*=========================================================================*/ 11 | #include "luasocket.h" 12 | 13 | /*-------------------------------------------------------------------------*\ 14 | * Current MIME library version 15 | \*-------------------------------------------------------------------------*/ 16 | #define MIME_VERSION "MIME 1.0.3" 17 | #define MIME_COPYRIGHT "Copyright (C) 2004-2013 Diego Nehab" 18 | #define MIME_AUTHORS "Diego Nehab" 19 | 20 | LUASOCKET_API int luaopen_mime_core(lua_State *L); 21 | 22 | #endif /* MIME_H */ 23 | -------------------------------------------------------------------------------- /src/deps/luasocket/pierror.h: -------------------------------------------------------------------------------- 1 | #ifndef PIERROR_H 2 | #define PIERROR_H 3 | /*=========================================================================*\ 4 | * Error messages 5 | * Defines platform independent error messages 6 | \*=========================================================================*/ 7 | 8 | #define PIE_HOST_NOT_FOUND "host not found" 9 | #define PIE_ADDRINUSE "address already in use" 10 | #define PIE_ISCONN "already connected" 11 | #define PIE_ACCESS "permission denied" 12 | #define PIE_CONNREFUSED "connection refused" 13 | #define PIE_CONNABORTED "closed" 14 | #define PIE_CONNRESET "closed" 15 | #define PIE_TIMEDOUT "timeout" 16 | #define PIE_AGAIN "temporary failure in name resolution" 17 | #define PIE_BADFLAGS "invalid value for ai_flags" 18 | #define PIE_BADHINTS "invalid value for hints" 19 | #define PIE_FAIL "non-recoverable failure in name resolution" 20 | #define PIE_FAMILY "ai_family not supported" 21 | #define PIE_MEMORY "memory allocation failure" 22 | #define PIE_NONAME "host or service not provided, or not known" 23 | #define PIE_OVERFLOW "argument buffer overflow" 24 | #define PIE_PROTOCOL "resolved protocol is unknown" 25 | #define PIE_SERVICE "service not supported for socket type" 26 | #define PIE_SOCKTYPE "ai_socktype not supported" 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/deps/luasocket/select.h: -------------------------------------------------------------------------------- 1 | #ifndef SELECT_H 2 | #define SELECT_H 3 | /*=========================================================================*\ 4 | * Select implementation 5 | * LuaSocket toolkit 6 | * 7 | * Each object that can be passed to the select function has to export 8 | * method getfd() which returns the descriptor to be passed to the 9 | * underlying select function. Another method, dirty(), should return 10 | * true if there is data ready for reading (required for buffered input). 11 | \*=========================================================================*/ 12 | 13 | #ifndef _WIN32 14 | #pragma GCC visibility push(hidden) 15 | #endif 16 | 17 | int select_open(lua_State *L); 18 | 19 | #ifndef _WIN32 20 | #pragma GCC visibility pop 21 | #endif 22 | 23 | #endif /* SELECT_H */ 24 | -------------------------------------------------------------------------------- /src/deps/luasocket/tcp.h: -------------------------------------------------------------------------------- 1 | #ifndef TCP_H 2 | #define TCP_H 3 | /*=========================================================================*\ 4 | * TCP object 5 | * LuaSocket toolkit 6 | * 7 | * The tcp.h module is basicly a glue that puts together modules buffer.h, 8 | * timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET, 9 | * SOCK_STREAM) support. 10 | * 11 | * Three classes are defined: master, client and server. The master class is 12 | * a newly created tcp object, that has not been bound or connected. Server 13 | * objects are tcp objects bound to some local address. Client objects are 14 | * tcp objects either connected to some address or returned by the accept 15 | * method of a server object. 16 | \*=========================================================================*/ 17 | #include "luasocket.h" 18 | 19 | #include "buffer.h" 20 | #include "timeout.h" 21 | #include "socket.h" 22 | 23 | typedef struct t_tcp_ { 24 | t_socket sock; 25 | t_io io; 26 | t_buffer buf; 27 | t_timeout tm; 28 | int family; 29 | } t_tcp; 30 | 31 | typedef t_tcp *p_tcp; 32 | 33 | #ifndef _WIN32 34 | #pragma GCC visibility push(hidden) 35 | #endif 36 | 37 | int tcp_open(lua_State *L); 38 | 39 | #ifndef _WIN32 40 | #pragma GCC visibility pop 41 | #endif 42 | 43 | #endif /* TCP_H */ 44 | -------------------------------------------------------------------------------- /src/deps/luasocket/timeout.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMEOUT_H 2 | #define TIMEOUT_H 3 | /*=========================================================================*\ 4 | * Timeout management functions 5 | * LuaSocket toolkit 6 | \*=========================================================================*/ 7 | #include "luasocket.h" 8 | 9 | /* timeout control structure */ 10 | typedef struct t_timeout_ { 11 | double block; /* maximum time for blocking calls */ 12 | double total; /* total number of miliseconds for operation */ 13 | double start; /* time of start of operation */ 14 | } t_timeout; 15 | typedef t_timeout *p_timeout; 16 | 17 | #ifndef _WIN32 18 | #pragma GCC visibility push(hidden) 19 | #endif 20 | 21 | void timeout_init(p_timeout tm, double block, double total); 22 | double timeout_get(p_timeout tm); 23 | double timeout_getstart(p_timeout tm); 24 | double timeout_getretry(p_timeout tm); 25 | p_timeout timeout_markstart(p_timeout tm); 26 | 27 | double timeout_gettime(void); 28 | 29 | int timeout_open(lua_State *L); 30 | 31 | int timeout_meth_settimeout(lua_State *L, p_timeout tm); 32 | int timeout_meth_gettimeout(lua_State *L, p_timeout tm); 33 | 34 | #ifndef _WIN32 35 | #pragma GCC visibility pop 36 | #endif 37 | 38 | #define timeout_iszero(tm) ((tm)->block == 0.0) 39 | 40 | #endif /* TIMEOUT_H */ 41 | -------------------------------------------------------------------------------- /src/deps/luasocket/udp.h: -------------------------------------------------------------------------------- 1 | #ifndef UDP_H 2 | #define UDP_H 3 | /*=========================================================================*\ 4 | * UDP object 5 | * LuaSocket toolkit 6 | * 7 | * The udp.h module provides LuaSocket with support for UDP protocol 8 | * (AF_INET, SOCK_DGRAM). 9 | * 10 | * Two classes are defined: connected and unconnected. UDP objects are 11 | * originally unconnected. They can be "connected" to a given address 12 | * with a call to the setpeername function. The same function can be used to 13 | * break the connection. 14 | \*=========================================================================*/ 15 | #include "luasocket.h" 16 | 17 | #include "timeout.h" 18 | #include "socket.h" 19 | 20 | #define UDP_DATAGRAMSIZE 8192 21 | 22 | typedef struct t_udp_ { 23 | t_socket sock; 24 | t_timeout tm; 25 | int family; 26 | } t_udp; 27 | typedef t_udp *p_udp; 28 | 29 | #ifndef _WIN32 30 | #pragma GCC visibility push(hidden) 31 | #endif 32 | 33 | int udp_open(lua_State *L); 34 | 35 | #ifndef _WIN32 36 | #pragma GCC visibility pop 37 | #endif 38 | 39 | #endif /* UDP_H */ 40 | -------------------------------------------------------------------------------- /src/deps/luasocket/unix.c: -------------------------------------------------------------------------------- 1 | /*=========================================================================*\ 2 | * Unix domain socket 3 | * LuaSocket toolkit 4 | \*=========================================================================*/ 5 | #include "luasocket.h" 6 | 7 | #include "unixstream.h" 8 | #include "unixdgram.h" 9 | 10 | /*-------------------------------------------------------------------------*\ 11 | * Modules and functions 12 | \*-------------------------------------------------------------------------*/ 13 | static const luaL_Reg mod[] = { 14 | {"stream", unixstream_open}, 15 | {"dgram", unixdgram_open}, 16 | {NULL, NULL} 17 | }; 18 | 19 | static void add_alias(lua_State *L, int index, const char *name, const char *target) 20 | { 21 | lua_getfield(L, index, target); 22 | lua_setfield(L, index, name); 23 | } 24 | 25 | static int compat_socket_unix_call(lua_State *L) 26 | { 27 | /* Look up socket.unix.stream in the socket.unix table (which is the first 28 | * argument). */ 29 | lua_getfield(L, 1, "stream"); 30 | 31 | /* Replace the stack entry for the socket.unix table with the 32 | * socket.unix.stream function. */ 33 | lua_replace(L, 1); 34 | 35 | /* Call socket.unix.stream, passing along any arguments. */ 36 | int n = lua_gettop(L); 37 | lua_call(L, n-1, LUA_MULTRET); 38 | 39 | /* Pass along the return values from socket.unix.stream. */ 40 | n = lua_gettop(L); 41 | return n; 42 | } 43 | 44 | /*-------------------------------------------------------------------------*\ 45 | * Initializes module 46 | \*-------------------------------------------------------------------------*/ 47 | LUASOCKET_API int luaopen_socket_unix(lua_State *L) 48 | { 49 | int i; 50 | lua_newtable(L); 51 | int socket_unix_table = lua_gettop(L); 52 | 53 | for (i = 0; mod[i].name; i++) 54 | mod[i].func(L); 55 | 56 | /* Add backwards compatibility aliases "tcp" and "udp" for the "stream" and 57 | * "dgram" functions. */ 58 | add_alias(L, socket_unix_table, "tcp", "stream"); 59 | add_alias(L, socket_unix_table, "udp", "dgram"); 60 | 61 | /* Add a backwards compatibility function and a metatable setup to call it 62 | * for the old socket.unix() interface. */ 63 | lua_pushcfunction(L, compat_socket_unix_call); 64 | lua_setfield(L, socket_unix_table, "__call"); 65 | lua_pushvalue(L, socket_unix_table); 66 | lua_setmetatable(L, socket_unix_table); 67 | 68 | return 1; 69 | } 70 | -------------------------------------------------------------------------------- /src/deps/luasocket/unix.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIX_H 2 | #define UNIX_H 3 | /*=========================================================================*\ 4 | * Unix domain object 5 | * LuaSocket toolkit 6 | * 7 | * This module is just an example of how to extend LuaSocket with a new 8 | * domain. 9 | \*=========================================================================*/ 10 | #include "luasocket.h" 11 | 12 | #include "buffer.h" 13 | #include "timeout.h" 14 | #include "socket.h" 15 | 16 | typedef struct t_unix_ { 17 | t_socket sock; 18 | t_io io; 19 | t_buffer buf; 20 | t_timeout tm; 21 | } t_unix; 22 | typedef t_unix *p_unix; 23 | 24 | LUASOCKET_API int luaopen_socket_unix(lua_State *L); 25 | 26 | #endif /* UNIX_H */ 27 | -------------------------------------------------------------------------------- /src/deps/luasocket/unixdgram.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIXDGRAM_H 2 | #define UNIXDGRAM_H 3 | /*=========================================================================*\ 4 | * DGRAM object 5 | * LuaSocket toolkit 6 | * 7 | * The dgram.h module provides LuaSocket with support for DGRAM protocol 8 | * (AF_INET, SOCK_DGRAM). 9 | * 10 | * Two classes are defined: connected and unconnected. DGRAM objects are 11 | * originally unconnected. They can be "connected" to a given address 12 | * with a call to the setpeername function. The same function can be used to 13 | * break the connection. 14 | \*=========================================================================*/ 15 | 16 | #include "unix.h" 17 | 18 | #ifndef _WIN32 19 | #pragma GCC visibility push(hidden) 20 | #endif 21 | 22 | int unixdgram_open(lua_State *L); 23 | 24 | #ifndef _WIN32 25 | #pragma GCC visibility pop 26 | #endif 27 | 28 | #endif /* UNIXDGRAM_H */ 29 | -------------------------------------------------------------------------------- /src/deps/luasocket/unixstream.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIXSTREAM_H 2 | #define UNIXSTREAM_H 3 | /*=========================================================================*\ 4 | * UNIX STREAM object 5 | * LuaSocket toolkit 6 | * 7 | * The unixstream.h module is basicly a glue that puts together modules buffer.h, 8 | * timeout.h socket.h and inet.h to provide the LuaSocket UNIX STREAM (AF_UNIX, 9 | * SOCK_STREAM) support. 10 | * 11 | * Three classes are defined: master, client and server. The master class is 12 | * a newly created unixstream object, that has not been bound or connected. Server 13 | * objects are unixstream objects bound to some local address. Client objects are 14 | * unixstream objects either connected to some address or returned by the accept 15 | * method of a server object. 16 | \*=========================================================================*/ 17 | #include "unix.h" 18 | 19 | #ifndef _WIN32 20 | #pragma GCC visibility push(hidden) 21 | #endif 22 | 23 | int unixstream_open(lua_State *L); 24 | 25 | #ifndef _WIN32 26 | #pragma GCC visibility pop 27 | #endif 28 | 29 | #endif /* UNIXSTREAM_H */ 30 | -------------------------------------------------------------------------------- /src/deps/luasocket/usocket.h: -------------------------------------------------------------------------------- 1 | #ifndef USOCKET_H 2 | #define USOCKET_H 3 | /*=========================================================================*\ 4 | * Socket compatibilization module for Unix 5 | * LuaSocket toolkit 6 | \*=========================================================================*/ 7 | 8 | /*=========================================================================*\ 9 | * BSD include files 10 | \*=========================================================================*/ 11 | /* error codes */ 12 | #include 13 | /* close function */ 14 | #include 15 | /* fnctnl function and associated constants */ 16 | #include 17 | /* struct sockaddr */ 18 | #include 19 | /* socket function */ 20 | #include 21 | /* struct timeval */ 22 | #include 23 | /* gethostbyname and gethostbyaddr functions */ 24 | #include 25 | /* sigpipe handling */ 26 | #include 27 | /* IP stuff*/ 28 | #include 29 | #include 30 | /* TCP options (nagle algorithm disable) */ 31 | #include 32 | #include 33 | 34 | #ifndef SO_REUSEPORT 35 | #define SO_REUSEPORT SO_REUSEADDR 36 | #endif 37 | 38 | /* Some platforms use IPV6_JOIN_GROUP instead if 39 | * IPV6_ADD_MEMBERSHIP. The semantics are same, though. */ 40 | #ifndef IPV6_ADD_MEMBERSHIP 41 | #ifdef IPV6_JOIN_GROUP 42 | #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 43 | #endif /* IPV6_JOIN_GROUP */ 44 | #endif /* !IPV6_ADD_MEMBERSHIP */ 45 | 46 | /* Same with IPV6_DROP_MEMBERSHIP / IPV6_LEAVE_GROUP. */ 47 | #ifndef IPV6_DROP_MEMBERSHIP 48 | #ifdef IPV6_LEAVE_GROUP 49 | #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 50 | #endif /* IPV6_LEAVE_GROUP */ 51 | #endif /* !IPV6_DROP_MEMBERSHIP */ 52 | 53 | typedef int t_socket; 54 | typedef t_socket *p_socket; 55 | typedef struct sockaddr_storage t_sockaddr_storage; 56 | 57 | #define SOCKET_INVALID (-1) 58 | 59 | #endif /* USOCKET_H */ 60 | -------------------------------------------------------------------------------- /src/deps/luasocket/wsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef WSOCKET_H 2 | #define WSOCKET_H 3 | /*=========================================================================*\ 4 | * Socket compatibilization module for Win32 5 | * LuaSocket toolkit 6 | \*=========================================================================*/ 7 | 8 | /*=========================================================================*\ 9 | * WinSock include files 10 | \*=========================================================================*/ 11 | #include 12 | #include 13 | 14 | typedef int socklen_t; 15 | typedef SOCKADDR_STORAGE t_sockaddr_storage; 16 | typedef SOCKET t_socket; 17 | typedef t_socket *p_socket; 18 | 19 | #ifndef IPV6_V6ONLY 20 | #define IPV6_V6ONLY 27 21 | #endif 22 | 23 | #define SOCKET_INVALID (INVALID_SOCKET) 24 | 25 | #ifndef SO_REUSEPORT 26 | #define SO_REUSEPORT SO_REUSEADDR 27 | #endif 28 | 29 | #ifndef AI_NUMERICSERV 30 | #define AI_NUMERICSERV (0) 31 | #endif 32 | 33 | #endif /* WSOCKET_H */ 34 | -------------------------------------------------------------------------------- /src/draw.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "algebra.h" 4 | #include "font.h" 5 | #include "image.h" 6 | #include "sprite.h" 7 | #include "tilemap.h" 8 | 9 | struct DrawDescription { 10 | float x; 11 | float y; 12 | float rotation; 13 | 14 | float sx; // scale 15 | float sy; 16 | 17 | float ox; // origin 18 | float oy; 19 | 20 | float u0; // uv coords 21 | float v0; 22 | float u1; 23 | float v1; 24 | }; 25 | 26 | struct RectDescription { 27 | float x; 28 | float y; 29 | float w; 30 | float h; 31 | 32 | float rotation; 33 | 34 | float sx; // scale 35 | float sy; 36 | 37 | float ox; // origin 38 | float oy; 39 | }; 40 | 41 | struct Color { 42 | u8 r, g, b, a; 43 | }; 44 | 45 | void renderer_reset(); 46 | void renderer_use_sampler(u32 sampler); 47 | void renderer_get_clear_color(float *rgba); 48 | void renderer_set_clear_color(float *rgba); 49 | void renderer_apply_color(); 50 | bool renderer_push_color(Color c); 51 | bool renderer_pop_color(); 52 | bool renderer_push_matrix(); 53 | bool renderer_pop_matrix(); 54 | Matrix4 renderer_peek_matrix(); 55 | void renderer_set_top_matrix(Matrix4 mat); 56 | void renderer_translate(float x, float y); 57 | void renderer_rotate(float angle); 58 | void renderer_scale(float x, float y); 59 | void renderer_push_quad(Vector4 pos, Vector4 tex); 60 | void renderer_push_xy(float x, float y); 61 | 62 | void draw_image(const Image *img, DrawDescription *desc); 63 | void draw_sprite(Sprite *spr, DrawDescription *desc); 64 | float draw_font(FontFamily *font, float size, float x, float y, String text); 65 | float draw_font_wrapped(FontFamily *font, float size, float x, float y, 66 | String text, float limit); 67 | void draw_tilemap(const Tilemap *tm); 68 | void draw_filled_rect(RectDescription *desc); 69 | void draw_line_rect(RectDescription *desc); 70 | void draw_line_circle(float x, float y, float radius); 71 | void draw_line(float x0, float y0, float x1, float y1); 72 | 73 | struct lua_State; 74 | DrawDescription draw_description_args(lua_State *L, i32 arg_start); 75 | RectDescription rect_description_args(lua_State *L, i32 arg_start); 76 | -------------------------------------------------------------------------------- /src/embed/Cousine-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasonliang-dev/spry/f8d06a21d5266ed5a0a0e70f2757166a86e9cc63/src/embed/Cousine-Regular.ttf -------------------------------------------------------------------------------- /src/font.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "deps/stb_truetype.h" 4 | #include "hash_map.h" 5 | #include "image.h" 6 | #include "strings.h" 7 | 8 | struct FontRange { 9 | stbtt_bakedchar chars[256]; 10 | Image image; 11 | }; 12 | 13 | struct FontQuad { 14 | stbtt_aligned_quad quad; 15 | }; 16 | 17 | struct FontFamily { 18 | String ttf; 19 | HashMap ranges; 20 | StringBuilder sb; 21 | 22 | bool load(String filepath); 23 | void load_default(); 24 | void trash(); 25 | 26 | stbtt_aligned_quad quad(u32 *img, float *x, float *y, float size, i32 ch); 27 | float width(float size, String text); 28 | }; -------------------------------------------------------------------------------- /src/image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | struct Image { 6 | u32 id; 7 | i32 width; 8 | i32 height; 9 | bool has_mips; 10 | 11 | bool load(String filepath, bool generate_mips); 12 | void trash(); 13 | }; -------------------------------------------------------------------------------- /src/json.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "arena.h" 4 | 5 | enum JSONKind : i32 { 6 | JSONKind_Null, 7 | JSONKind_Object, 8 | JSONKind_Array, 9 | JSONKind_String, 10 | JSONKind_Number, 11 | JSONKind_Boolean, 12 | }; 13 | 14 | struct JSONObject; 15 | struct JSONArray; 16 | struct JSON { 17 | union { 18 | JSONObject *object; 19 | JSONArray *array; 20 | String string; 21 | double number; 22 | bool boolean; 23 | }; 24 | JSONKind kind; 25 | 26 | JSON lookup(String key, bool *ok); 27 | JSON index(i32 i, bool *ok); 28 | 29 | JSONObject *as_object(bool *ok); 30 | JSONArray *as_array(bool *ok); 31 | String as_string(bool *ok); 32 | double as_number(bool *ok); 33 | 34 | JSONObject *lookup_object(String key, bool *ok); 35 | JSONArray *lookup_array(String key, bool *ok); 36 | String lookup_string(String key, bool *ok); 37 | double lookup_number(String key, bool *ok); 38 | 39 | double index_number(i32 i, bool *ok); 40 | }; 41 | 42 | struct JSONObject { 43 | JSON value; 44 | String key; 45 | JSONObject *next; 46 | u64 hash; 47 | }; 48 | 49 | struct JSONArray { 50 | JSON value; 51 | JSONArray *next; 52 | u64 index; 53 | }; 54 | 55 | struct JSONDocument { 56 | JSON root; 57 | String error; 58 | Arena arena; 59 | 60 | void parse(String contents); 61 | void trash(); 62 | }; 63 | 64 | struct StringBuilder; 65 | void json_write_string(StringBuilder *sb, JSON *json); 66 | void json_print(JSON *json); 67 | 68 | struct lua_State; 69 | void json_to_lua(lua_State *L, JSON *json); 70 | String lua_to_json_string(lua_State *L, i32 arg, String *contents, i32 width); 71 | -------------------------------------------------------------------------------- /src/microui.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "deps/microui.h" 4 | #include "prelude.h" 5 | 6 | struct sapp_event; 7 | 8 | mu_Context *microui_ctx(); 9 | void microui_init(); 10 | void microui_trash(); 11 | void microui_sokol_event(const sapp_event *e); 12 | void microui_begin(); 13 | void microui_end_and_present(); 14 | 15 | struct lua_State; 16 | mu_Rect lua_mu_check_rect(lua_State *L, i32 arg); 17 | void lua_mu_rect_push(lua_State *L, mu_Rect rect); 18 | mu_Color lua_mu_check_color(lua_State *L, i32 arg); 19 | 20 | enum MUIRefKind : i32 { 21 | MUIRefKind_Nil, 22 | MUIRefKind_Boolean, 23 | MUIRefKind_Real, 24 | MUIRefKind_String, 25 | }; 26 | 27 | struct MUIRef { 28 | MUIRefKind kind; 29 | union { 30 | int boolean; 31 | mu_Real real; 32 | char string[512]; 33 | }; 34 | }; 35 | 36 | void lua_mu_set_ref(lua_State *L, MUIRef *ref, i32 arg); 37 | MUIRef *lua_mu_check_ref(lua_State *L, i32 arg, MUIRefKind kind); 38 | -------------------------------------------------------------------------------- /src/os.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | i32 os_change_dir(const char *path); 6 | String os_program_dir(); 7 | String os_program_path(); 8 | u64 os_file_modtime(const char *filename); 9 | void os_high_timer_resolution(); 10 | void os_sleep(u32 ms); 11 | void os_yield(); 12 | -------------------------------------------------------------------------------- /src/physics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "prelude.h" 5 | #include "luax.h" 6 | 7 | struct PhysicsUserData { 8 | i32 begin_contact_ref; 9 | i32 end_contact_ref; 10 | 11 | i32 ref_count; 12 | i32 type; 13 | union { 14 | char *str; 15 | lua_Number num; 16 | }; 17 | }; 18 | 19 | struct PhysicsContactListener; 20 | struct Physics { 21 | b2World *world; 22 | PhysicsContactListener *contact_listener; 23 | float meter; 24 | 25 | union { 26 | b2Body *body; 27 | b2Fixture *fixture; 28 | }; 29 | }; 30 | 31 | Physics physics_world_make(lua_State *L, b2Vec2 gravity, float meter); 32 | void physics_world_trash(lua_State *L, Physics *p); 33 | void physics_world_begin_contact(lua_State *L, Physics *p, i32 arg); 34 | void physics_world_end_contact(lua_State *L, Physics *p, i32 arg); 35 | Physics physics_weak_copy(Physics *p); 36 | 37 | void physics_destroy_body(lua_State *L, Physics *physics); 38 | PhysicsUserData *physics_userdata(lua_State *L); 39 | void physics_push_userdata(lua_State *L, u64 ptr); 40 | void draw_fixtures_for_body(b2Body *body, float meter); 41 | -------------------------------------------------------------------------------- /src/prelude.cpp: -------------------------------------------------------------------------------- 1 | #include "prelude.h" 2 | 3 | void *DebugAllocator::alloc(size_t bytes, const char *file, i32 line) { 4 | LockGuard lock{&mtx}; 5 | 6 | DebugAllocInfo *info = 7 | (DebugAllocInfo *)malloc(offsetof(DebugAllocInfo, buf[bytes])); 8 | info->file = file; 9 | info->line = line; 10 | info->size = bytes; 11 | info->prev = nullptr; 12 | info->next = head; 13 | if (head != nullptr) { 14 | head->prev = info; 15 | } 16 | head = info; 17 | return info->buf; 18 | } 19 | 20 | void DebugAllocator::free(void *ptr) { 21 | if (ptr == nullptr) { 22 | return; 23 | } 24 | 25 | LockGuard lock{&mtx}; 26 | 27 | DebugAllocInfo *info = 28 | (DebugAllocInfo *)((u8 *)ptr - offsetof(DebugAllocInfo, buf)); 29 | 30 | if (info->prev == nullptr) { 31 | head = info->next; 32 | } else { 33 | info->prev->next = info->next; 34 | } 35 | 36 | if (info->next) { 37 | info->next->prev = info->prev; 38 | } 39 | 40 | ::free(info); 41 | } 42 | 43 | void DebugAllocator::dump_allocs() { 44 | i32 allocs = 0; 45 | for (DebugAllocInfo *info = head; info != nullptr; info = info->next) { 46 | printf(" %10llu bytes: %s:%d\n", (unsigned long long)info->size, 47 | info->file, info->line); 48 | allocs++; 49 | } 50 | printf(" --- %d allocation(s) ---\n", allocs); 51 | } 52 | 53 | bool String::is_cstr() { return data[len] == '\0'; } 54 | 55 | String String::substr(u64 i, u64 j) { 56 | assert(i <= j); 57 | assert(j <= (i64)len); 58 | return {&data[i], j - i}; 59 | } 60 | 61 | bool String::starts_with(String match) { 62 | if (len < match.len) { 63 | return false; 64 | } 65 | return substr(0, match.len) == match; 66 | } 67 | 68 | bool String::ends_with(String match) { 69 | if (len < match.len) { 70 | return false; 71 | } 72 | return substr(len - match.len, len) == match; 73 | } 74 | 75 | u64 String::first_of(char c) { 76 | for (u64 i = 0; i < len; i++) { 77 | if (data[i] == c) { 78 | return i; 79 | } 80 | } 81 | 82 | return (u64)-1; 83 | } 84 | 85 | u64 String::last_of(char c) { 86 | for (u64 i = len; i > 0; i--) { 87 | if (data[i - 1] == c) { 88 | return i - 1; 89 | } 90 | } 91 | 92 | return (u64)-1; 93 | } 94 | -------------------------------------------------------------------------------- /src/priority_queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | template struct PriorityQueue { 6 | T *data = nullptr; 7 | float *costs = nullptr; 8 | u64 len = 0; 9 | u64 capacity = 0; 10 | 11 | void trash() { 12 | mem_free(data); 13 | mem_free(costs); 14 | } 15 | 16 | void reserve(u64 cap) { 17 | if (cap <= capacity) { 18 | return; 19 | } 20 | 21 | T *buf = (T *)mem_alloc(sizeof(T) * cap); 22 | memcpy(buf, data, sizeof(T) * len); 23 | mem_free(data); 24 | data = buf; 25 | 26 | float *cbuf = (float *)mem_alloc(sizeof(float) * cap); 27 | memcpy(cbuf, costs, sizeof(float) * len); 28 | mem_free(costs); 29 | costs = cbuf; 30 | 31 | capacity = cap; 32 | } 33 | 34 | void swap(i32 i, i32 j) { 35 | T t = data[i]; 36 | data[i] = data[j]; 37 | data[j] = t; 38 | 39 | float f = costs[i]; 40 | costs[i] = costs[j]; 41 | costs[j] = f; 42 | } 43 | 44 | void shift_up(i32 j) { 45 | while (j > 0) { 46 | i32 i = (j - 1) / 2; 47 | if (i == j || costs[i] < costs[j]) { 48 | break; 49 | } 50 | 51 | swap(i, j); 52 | j = i; 53 | } 54 | } 55 | 56 | void shift_down(i32 i, i32 n) { 57 | if (i < 0 || i > n) { 58 | return; 59 | } 60 | 61 | i32 j = 2 * i + 1; 62 | while (j >= 0 && j < n) { 63 | if (j + 1 < n && costs[j + 1] < costs[j]) { 64 | j = j + 1; 65 | } 66 | 67 | if (costs[i] < costs[j]) { 68 | break; 69 | } 70 | 71 | swap(i, j); 72 | i = j; 73 | j = 2 * i + 1; 74 | } 75 | } 76 | 77 | void push(T item, float cost) { 78 | if (len == capacity) { 79 | reserve(len > 0 ? len * 2 : 8); 80 | } 81 | 82 | data[len] = item; 83 | costs[len] = cost; 84 | len++; 85 | 86 | shift_up(len - 1); 87 | } 88 | 89 | bool pop(T *item) { 90 | if (len == 0) { 91 | return false; 92 | } 93 | 94 | *item = data[0]; 95 | 96 | data[0] = data[len - 1]; 97 | costs[0] = costs[len - 1]; 98 | len--; 99 | 100 | shift_down(0, len); 101 | return true; 102 | } 103 | }; 104 | -------------------------------------------------------------------------------- /src/profile.cpp: -------------------------------------------------------------------------------- 1 | #include "profile.h" 2 | #include "queue.h" 3 | 4 | #ifndef USE_PROFILER 5 | void profile_setup() {} 6 | void profile_shutdown() {} 7 | #endif 8 | 9 | #ifdef USE_PROFILER 10 | 11 | #include "deps/sokol_time.h" 12 | #include "os.h" 13 | #include "strings.h" 14 | #include "sync.h" 15 | 16 | struct Profile { 17 | Queue events; 18 | Thread recv_thread; 19 | }; 20 | 21 | static Profile g_profile = {}; 22 | 23 | static void profile_recv_thread(void *) { 24 | StringBuilder sb = {}; 25 | sb.swap_filename(os_program_path(), "profile.json"); 26 | 27 | FILE *f = fopen(sb.data, "w"); 28 | sb.trash(); 29 | 30 | defer(fclose(f)); 31 | 32 | fputs("[", f); 33 | while (true) { 34 | TraceEvent e = g_profile.events.demand(); 35 | if (e.name == nullptr) { 36 | return; 37 | } 38 | 39 | fprintf(f, 40 | R"({"name":"%s","cat":"%s","ph":"%c","ts":%.3f,"pid":0,"tid":%hu},)" 41 | "\n", 42 | e.name, e.cat, e.ph, stm_us(e.ts), e.tid); 43 | } 44 | } 45 | 46 | void profile_setup() { 47 | g_profile.events.make(); 48 | g_profile.events.reserve(256); 49 | g_profile.recv_thread.make(profile_recv_thread, nullptr); 50 | } 51 | 52 | void profile_shutdown() { 53 | g_profile.events.enqueue({}); 54 | g_profile.recv_thread.join(); 55 | g_profile.events.trash(); 56 | } 57 | 58 | Instrument::Instrument(const char *cat, const char *name) 59 | : cat(cat), name(name), tid(this_thread_id()) { 60 | TraceEvent e = {}; 61 | e.cat = cat; 62 | e.name = name; 63 | e.ph = 'B'; 64 | e.ts = stm_now(); 65 | e.tid = tid; 66 | 67 | g_profile.events.enqueue(e); 68 | } 69 | 70 | Instrument::~Instrument() { 71 | TraceEvent e = {}; 72 | e.cat = cat; 73 | e.name = name; 74 | e.ph = 'E'; 75 | e.ts = stm_now(); 76 | e.tid = tid; 77 | 78 | g_profile.events.enqueue(e); 79 | } 80 | 81 | #endif // USE_PROFILER -------------------------------------------------------------------------------- /src/profile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void profile_setup(); 4 | void profile_shutdown(); 5 | 6 | #ifndef NDEBUG 7 | #if !defined(USE_PROFILER) && !defined(__EMSCRIPTEN__) 8 | #define USE_PROFILER 9 | #endif 10 | #endif 11 | 12 | #ifdef USE_PROFILER 13 | #include "prelude.h" 14 | 15 | struct TraceEvent { 16 | const char *cat; 17 | const char *name; 18 | u64 ts; 19 | u16 tid; 20 | char ph; 21 | }; 22 | 23 | struct Instrument { 24 | const char *cat; 25 | const char *name; 26 | i32 tid; 27 | 28 | Instrument(const char *cat, const char *name); 29 | ~Instrument(); 30 | }; 31 | 32 | #define PROFILE_FUNC() \ 33 | auto JOIN_2(_profile_, __COUNTER__) = Instrument("function", __func__); 34 | 35 | #define PROFILE_BLOCK(name) \ 36 | auto JOIN_2(_profile_, __COUNTER__) = Instrument("block", name); 37 | 38 | #endif // USE_PROFILER 39 | 40 | #ifndef USE_PROFILER 41 | #define PROFILE_FUNC() 42 | #define PROFILE_BLOCK(name) 43 | #endif 44 | -------------------------------------------------------------------------------- /src/queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | template struct Queue { 6 | Mutex mtx = {}; 7 | Cond cv = {}; 8 | 9 | T *data = nullptr; 10 | u64 front = 0; 11 | u64 back = 0; 12 | u64 len = 0; 13 | u64 capacity = 0; 14 | 15 | void make() { 16 | mtx.make(); 17 | cv.make(); 18 | } 19 | 20 | void trash() { 21 | mtx.trash(); 22 | cv.trash(); 23 | mem_free(data); 24 | } 25 | 26 | void reserve(u64 cap) { 27 | if (cap <= capacity) { 28 | return; 29 | } 30 | 31 | T *buf = (T *)mem_alloc(sizeof(T) * cap); 32 | 33 | if (front < back) { 34 | memcpy(buf, &data[front], sizeof(T) * len); 35 | } else { 36 | u64 lhs = back; 37 | u64 rhs = (capacity - front); 38 | 39 | memcpy(buf, &data[front], sizeof(T) * rhs); 40 | memcpy(&buf[rhs], &data[0], sizeof(T) * lhs); 41 | } 42 | 43 | mem_free(data); 44 | 45 | data = buf; 46 | front = 0; 47 | back = len; 48 | capacity = cap; 49 | } 50 | 51 | void enqueue(T item) { 52 | LockGuard lock{&mtx}; 53 | 54 | if (len == capacity) { 55 | reserve(len > 0 ? len * 2 : 8); 56 | } 57 | 58 | data[back] = item; 59 | back = (back + 1) % capacity; 60 | len++; 61 | 62 | cv.signal(); 63 | } 64 | 65 | T demand() { 66 | LockGuard lock{&mtx}; 67 | 68 | while (len == 0) { 69 | cv.wait(&mtx); 70 | } 71 | 72 | T item = data[front]; 73 | front = (front + 1) % capacity; 74 | len--; 75 | 76 | return item; 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/scanner.cpp: -------------------------------------------------------------------------------- 1 | #include "scanner.h" 2 | #include "strings.h" 3 | 4 | Scanner::Scanner(String str) { 5 | data = str.data; 6 | len = str.len; 7 | pos = 0; 8 | end = 0; 9 | } 10 | 11 | static void advance(Scanner *s) { s->end += utf8_size(s->data[s->end]); } 12 | static bool at_end(Scanner *s) { return s->end >= s->len; } 13 | 14 | static Rune peek(Scanner *s) { 15 | if (at_end(s)) { 16 | return {0}; 17 | } else { 18 | return rune_from_string(&s->data[s->end]); 19 | } 20 | } 21 | 22 | static void skip_whitespace(Scanner *s) { 23 | while (peek(s).is_whitespace() && !at_end(s)) { 24 | advance(s); 25 | } 26 | } 27 | 28 | String Scanner::next_string() { 29 | skip_whitespace(this); 30 | pos = end; 31 | 32 | if (at_end(this)) { 33 | return ""; 34 | } 35 | 36 | while (!peek(this).is_whitespace() && !at_end(this)) { 37 | advance(this); 38 | } 39 | 40 | return {&data[pos], end - pos}; 41 | } 42 | 43 | i32 Scanner::next_int() { 44 | skip_whitespace(this); 45 | pos = end; 46 | 47 | if (at_end(this)) { 48 | return 0; 49 | } 50 | 51 | i32 sign = 1; 52 | if (peek(this).value == '-') { 53 | sign = -1; 54 | advance(this); 55 | } 56 | 57 | i32 num = 0; 58 | while (peek(this).is_digit()) { 59 | num *= 10; 60 | num += peek(this).value - '0'; 61 | advance(this); 62 | } 63 | 64 | return num * sign; 65 | } -------------------------------------------------------------------------------- /src/scanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | struct Scanner { 6 | char *data; 7 | u64 len; 8 | u64 pos; 9 | u64 end; 10 | 11 | Scanner(String str); 12 | String next_string(); 13 | i32 next_int(); 14 | }; 15 | -------------------------------------------------------------------------------- /src/slice.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "arena.h" 4 | #include "array.h" 5 | 6 | template struct Slice { 7 | T *data = nullptr; 8 | u64 len = 0; 9 | 10 | Slice() = default; 11 | explicit Slice(Array arr) : data(arr.data), len(arr.len) {} 12 | 13 | T &operator[](size_t i) { 14 | assert(i >= 0 && i < len); 15 | return data[i]; 16 | } 17 | 18 | const T &operator[](size_t i) const { 19 | assert(i >= 0 && i < len); 20 | return data[i]; 21 | } 22 | 23 | void resize(u64 n) { 24 | T *buf = (T *)mem_alloc(sizeof(T) * n); 25 | memcpy(buf, data, sizeof(T) * len); 26 | mem_free(data); 27 | data = buf; 28 | len = n; 29 | } 30 | 31 | void resize(Arena *arena, u64 n) { 32 | T *buf = (T *)arena->rebump(data, sizeof(T) * len, sizeof(T) * n); 33 | data = buf; 34 | len = n; 35 | } 36 | 37 | T *begin() { return data; } 38 | T *end() { return &data[len]; } 39 | const T *begin() const { return data; } 40 | const T *end() const { return &data[len]; } 41 | }; 42 | -------------------------------------------------------------------------------- /src/sound.cpp: -------------------------------------------------------------------------------- 1 | #include "sound.h" 2 | #include "app.h" 3 | #include "profile.h" 4 | 5 | static void on_sound_end(void *udata, ma_sound *ma) { 6 | Sound *sound = (Sound *)udata; 7 | if (sound->zombie) { 8 | sound->dead_end = true; 9 | } 10 | } 11 | 12 | Sound *sound_load(String filepath) { 13 | PROFILE_FUNC(); 14 | 15 | ma_result res = MA_SUCCESS; 16 | 17 | Sound *sound = (Sound *)mem_alloc(sizeof(Sound)); 18 | 19 | String cpath = to_cstr(filepath); 20 | defer(mem_free(cpath.data)); 21 | 22 | res = ma_sound_init_from_file(&g_app->audio_engine, cpath.data, 0, nullptr, 23 | nullptr, &sound->ma); 24 | if (res != MA_SUCCESS) { 25 | mem_free(sound); 26 | return nullptr; 27 | } 28 | 29 | res = ma_sound_set_end_callback(&sound->ma, on_sound_end, sound); 30 | if (res != MA_SUCCESS) { 31 | mem_free(sound); 32 | return nullptr; 33 | } 34 | 35 | sound->zombie = false; 36 | sound->dead_end = false; 37 | return sound; 38 | } 39 | 40 | void Sound::trash() { 41 | ma_sound_uninit(&ma); 42 | } 43 | -------------------------------------------------------------------------------- /src/sound.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "deps/miniaudio.h" 4 | #include "prelude.h" 5 | 6 | struct Sound { 7 | ma_sound ma; 8 | bool zombie; 9 | bool dead_end; 10 | 11 | void trash(); 12 | }; 13 | 14 | Sound *sound_load(String filepath); -------------------------------------------------------------------------------- /src/sprite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hash_map.h" 4 | #include "image.h" 5 | #include "slice.h" 6 | 7 | struct SpriteFrame { 8 | i32 duration; 9 | float u0, v0, u1, v1; 10 | }; 11 | 12 | struct SpriteLoop { 13 | Slice indices; 14 | }; 15 | 16 | struct SpriteData { 17 | Arena arena; 18 | Slice frames; 19 | HashMap by_tag; 20 | Image img; 21 | i32 width; 22 | i32 height; 23 | 24 | bool load(String filepath); 25 | void trash(); 26 | }; 27 | 28 | struct Sprite { 29 | u64 sprite; // index into assets 30 | u64 loop; // index into SpriteData::by_tag 31 | float elapsed; 32 | i32 current_frame; 33 | 34 | bool play(String tag); 35 | void update(float dt); 36 | void set_frame(i32 frame); 37 | }; 38 | 39 | struct SpriteView { 40 | Sprite *sprite; 41 | SpriteData data; 42 | SpriteLoop loop; 43 | 44 | bool make(Sprite *spr); 45 | i32 frame(); 46 | u64 len(); 47 | }; 48 | -------------------------------------------------------------------------------- /src/strings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "prelude.h" 4 | 5 | struct SplitLinesIterator { 6 | String data; 7 | String view; 8 | 9 | String operator*() const { return view; } 10 | SplitLinesIterator &operator++(); 11 | }; 12 | 13 | bool operator!=(SplitLinesIterator lhs, SplitLinesIterator rhs); 14 | 15 | struct SplitLines { 16 | String str; 17 | SplitLines(String s) : str(s) {} 18 | 19 | SplitLinesIterator begin(); 20 | SplitLinesIterator end(); 21 | }; 22 | 23 | i32 utf8_size(u8 c); 24 | 25 | struct Rune { 26 | u32 value; 27 | 28 | u32 charcode(); 29 | bool is_whitespace(); 30 | bool is_digit(); 31 | }; 32 | 33 | Rune rune_from_string(const char *buf); 34 | 35 | struct UTF8Iterator { 36 | String str; 37 | u64 cursor; 38 | Rune rune; 39 | 40 | Rune operator*() const { return rune; } 41 | UTF8Iterator &operator++(); 42 | }; 43 | 44 | bool operator!=(UTF8Iterator lhs, UTF8Iterator rhs); 45 | 46 | struct UTF8 { 47 | String str; 48 | UTF8(String s) : str(s) {} 49 | 50 | UTF8Iterator begin(); 51 | UTF8Iterator end(); 52 | }; 53 | 54 | struct StringBuilder { 55 | char *data; 56 | u64 len; // does not include null term 57 | u64 capacity; // includes null term 58 | 59 | StringBuilder(); 60 | 61 | void trash(); 62 | void reserve(u64 capacity); 63 | void clear(); 64 | void swap_filename(String filepath, String file); 65 | void concat(String str, i32 times); 66 | 67 | StringBuilder &operator<<(String str); 68 | explicit operator String(); 69 | }; 70 | 71 | FORMAT_ARGS(1) String str_fmt(const char *fmt, ...); 72 | FORMAT_ARGS(1) String tmp_fmt(const char *fmt, ...); 73 | 74 | double string_to_double(String str); 75 | -------------------------------------------------------------------------------- /src/sync.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _WIN32 6 | #include 7 | #else 8 | #include 9 | #include 10 | #endif 11 | 12 | struct Mutex { 13 | #ifdef _WIN32 14 | SRWLOCK srwlock; 15 | #else 16 | pthread_mutex_t pt; 17 | #endif 18 | 19 | void make(); 20 | void trash(); 21 | void lock(); 22 | void unlock(); 23 | bool try_lock(); 24 | }; 25 | 26 | struct Cond { 27 | #ifdef _WIN32 28 | CONDITION_VARIABLE cv; 29 | #else 30 | pthread_cond_t pt; 31 | #endif 32 | 33 | void make(); 34 | void trash(); 35 | void signal(); 36 | void broadcast(); 37 | void wait(Mutex *mtx); 38 | bool timed_wait(Mutex *mtx, uint32_t ms); 39 | }; 40 | 41 | struct RWLock { 42 | #if _WIN32 43 | SRWLOCK srwlock; 44 | #else 45 | pthread_rwlock_t pt; 46 | #endif 47 | 48 | void make(); 49 | void trash(); 50 | void shared_lock(); 51 | void shared_unlock(); 52 | void unique_lock(); 53 | void unique_unlock(); 54 | }; 55 | 56 | struct Sema { 57 | #ifdef _WIN32 58 | HANDLE handle; 59 | #else 60 | sem_t *sem; 61 | #endif 62 | 63 | void make(int n = 0); 64 | void trash(); 65 | void post(int n = 1); 66 | void wait(); 67 | }; 68 | 69 | typedef void (*ThreadProc)(void *); 70 | 71 | struct Thread { 72 | void *ptr = nullptr; 73 | 74 | void make(ThreadProc fn, void *udata); 75 | void join(); 76 | }; 77 | 78 | struct LockGuard { 79 | Mutex *mtx; 80 | 81 | LockGuard(Mutex *mtx) : mtx(mtx) { mtx->lock(); }; 82 | ~LockGuard() { mtx->unlock(); }; 83 | LockGuard(LockGuard &&) = delete; 84 | LockGuard &operator=(LockGuard &&) = delete; 85 | 86 | operator bool() { return true; } 87 | }; 88 | 89 | uint64_t this_thread_id(); 90 | -------------------------------------------------------------------------------- /src/tilemap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hash_map.h" 4 | #include "image.h" 5 | #include "priority_queue.h" 6 | #include "slice.h" 7 | 8 | struct Tile { 9 | float x, y, u, v; 10 | float u0, v0, u1, v1; 11 | i32 flip_bits; 12 | }; 13 | 14 | struct TilemapEntity { 15 | String identifier; 16 | float x, y; 17 | }; 18 | 19 | using TilemapInt = unsigned char; 20 | 21 | struct TilemapLayer { 22 | String identifier; 23 | Image image; 24 | Slice tiles; 25 | Slice entities; 26 | i32 c_width; 27 | i32 c_height; 28 | Slice int_grid; 29 | float grid_size; 30 | }; 31 | 32 | struct TilemapLevel { 33 | String identifier; 34 | String iid; 35 | float world_x, world_y; 36 | float px_width, px_height; 37 | Slice layers; 38 | }; 39 | 40 | enum TileNodeFlags { 41 | TileNodeFlags_Open = 1 << 0, 42 | TileNodeFlags_Closed = 1 << 1, 43 | }; 44 | 45 | struct TileNode { 46 | TileNode *prev; 47 | float g; // cost so far 48 | u32 flags; 49 | 50 | i32 x, y; 51 | float cost; 52 | Slice neighbors; 53 | }; 54 | 55 | struct TileCost { 56 | TilemapInt cell; 57 | float value; 58 | }; 59 | 60 | struct TilePoint { 61 | float x, y; 62 | }; 63 | 64 | inline u64 tile_key(i32 x, i32 y) { return ((u64)x << 32) | (u64)y; } 65 | 66 | class b2Body; 67 | class b2World; 68 | 69 | struct Tilemap { 70 | Arena arena; 71 | Slice levels; 72 | HashMap images; // key: filepath 73 | HashMap bodies; // key: layer name 74 | HashMap graph; // key: x, y 75 | PriorityQueue frontier; 76 | float graph_grid_size; 77 | 78 | bool load(String filepath); 79 | void trash(); 80 | void destroy_bodies(b2World *world); 81 | void make_collision(b2World *world, float meter, String layer_name, 82 | Slice walls); 83 | void make_graph(i32 bloom, String layer_name, Slice costs); 84 | TileNode *astar(TilePoint start, TilePoint goal); 85 | }; 86 | -------------------------------------------------------------------------------- /src/vfs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "array.h" 4 | #include "prelude.h" 5 | 6 | struct MountResult { 7 | bool ok; 8 | bool can_hot_reload; 9 | bool is_fused; 10 | }; 11 | 12 | MountResult vfs_mount(const char *filepath); 13 | void vfs_trash(); 14 | 15 | bool vfs_file_exists(String filepath); 16 | bool vfs_read_entire_file(String *out, String filepath); 17 | bool vfs_write_entire_file(String filepath, String contents); 18 | bool vfs_list_all_files(Array *files); 19 | 20 | void *vfs_for_miniaudio(); -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /website/guides/hot-reload.md: -------------------------------------------------------------------------------- 1 | # Hot Reloading 2 | 3 | Spry has the ablity to hot reload recently changed Lua scripts, Aseprite 4 | files, LDtk files, and images. While Spry is running, you can update a file 5 | and the changes will be reflected without having to restart your program. 6 | 7 | 10 | 11 | 14 | 15 | 18 | 19 | Hot reloading Lua scripts will not update any references or callbacks. For 20 | example, If you change a callback function in a class constructor, old 21 | instances will still hold onto the old function. 22 | 23 | ```lua 24 | function Enemy:new() 25 | self.timer = interval(0.1, function() 26 | -- update this function and save the file. 27 | -- changes are reflected for new Enemy instances only. 28 | end) 29 | end 30 | ``` 31 | 32 | Hot reloads are done by checking the modified time of each loaded file. By 33 | default, this is done every 1/10th of a second. To change this, set 34 | `reload_interval` to a different value in `spry.conf`: 35 | 36 | ```lua 37 | function spry.conf(t) 38 | t.reload_interval = 0.5 -- reload every half second 39 | end 40 | ``` 41 | 42 | You can even set the reload interval to 0 if you want to poll for changes as 43 | fast as possible, but it increases the chance that Spry is reading the file 44 | you want to write to, and it wastes disk usage. 45 | 46 | To disable hot reloading, set `hot_reload` to `false` in `spry.conf`. 47 | 48 | ```lua 49 | function spry.conf(t) 50 | t.hot_reload = false -- disable hot reloading 51 | end 52 | ``` 53 | 54 | Hot reloading is not supported for web builds. 55 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "deploy": "php index.php && gh-pages -d dist" 4 | } 5 | } -------------------------------------------------------------------------------- /website/pages/demo.php: -------------------------------------------------------------------------------- 1 |
px"> 2 |
3 |

4 | text(multiline_trim($page["text"])) ?> 5 |
6 | px; height: px" 12 | > 13 | 31 |
32 | 40 | 41 | 6 |
7 | text($contents) ?> 8 |
9 |