├── doc
├── site
│ ├── _ext
│ │ └── sphinx-lua
│ │ │ ├── src
│ │ │ ├── .gitignore
│ │ │ └── redjack
│ │ │ │ ├── __init__.py
│ │ │ │ └── sphinx
│ │ │ │ └── __init__.py
│ │ │ ├── MANIFEST.in
│ │ │ ├── setup.cfg
│ │ │ └── setup.py
│ ├── _static
│ │ └── logo.png
│ ├── tutorials
│ │ ├── arial.ttf
│ │ ├── basics_black.png
│ │ ├── basics_board.png
│ │ ├── basics_final.gif
│ │ ├── spritesheet.png
│ │ ├── basics_gameover.png
│ │ └── basics_sprites.png
│ ├── tutorials.rst
│ └── resources.rst
├── README.md
└── man
│ ├── drystal.xsl
│ └── CMakeLists.txt
├── tests
├── audio
│ ├── random
│ │ ├── drystal.cfg
│ │ ├── coin1.wav
│ │ ├── coin2.wav
│ │ ├── hurt1.wav
│ │ ├── jump1.wav
│ │ ├── jump2.wav
│ │ ├── select1.wav
│ │ └── main.lua
│ ├── test.ogg
│ ├── test.wav
│ ├── create.lua
│ └── play.lua
├── font
│ ├── arial.ttf
│ ├── parser.lua
│ ├── line.lua
│ ├── simple_draw.lua
│ └── position.lua
├── graphics
│ ├── npot.png
│ ├── tex.png
│ ├── arial.ttf
│ ├── image.png
│ ├── precise.png
│ ├── spritesheet.png
│ ├── regressions
│ │ ├── arial.ttf
│ │ └── font_draw_from.lua
│ ├── title.lua
│ ├── line.lua
│ ├── npot.lua
│ ├── read.lua
│ ├── fullscreen.lua
│ ├── colors.lua
│ ├── resize
│ │ └── resizable.lua
│ ├── draw_point.lua
│ ├── draw_polygon.lua
│ ├── image.json
│ ├── sprites.lua
│ ├── filter.lua
│ ├── fx.lua
│ ├── shaders.lua
│ ├── precise.lua
│ ├── buffer.lua
│ ├── camera.lua
│ └── surface_manipulations.lua
├── particle
│ ├── squish2.wav
│ ├── spritesheet.png
│ ├── fire.lua
│ ├── blood.lua
│ ├── smoke.lua
│ └── simple.lua
├── misc
│ ├── dir
│ │ └── livecode2.lua
│ ├── fps.lua
│ ├── engine_stop.lua
│ ├── objects.lua
│ ├── livecode.lua
│ └── compute_perf.lua
├── drystal.cfg
├── web
│ ├── js.lua
│ └── wget.lua
├── event
│ ├── pointer.lua
│ ├── unicode.lua
│ ├── hooks.lua
│ └── relative.lua
├── physics
│ └── destroy.lua
└── index.html
├── external
├── stb_truetype.h
├── miniz.h
├── cjson-fpconv.patch
├── zlibCMakeLists.cmake
├── libpngCMakeLists.cmake
└── wavloader.c
├── spec
├── 32x32.png
├── 40x40.png
├── bad_32x32.png
├── storage_spec.moon
├── display_spec.moon
├── audio_spec.moon
├── color_spec.moon
├── tools.moon
└── camera_spec.moon
├── tools
├── busted
├── CMakeLists.txt
├── unittest.lua
├── drystal.supp
└── setup_busted.sh
├── .gitignore
├── misc
└── shell-completion
│ └── zsh
│ ├── CMakeLists.txt
│ ├── _drystal
│ └── _drystaljs
├── .gitmodules
├── src
├── font
│ ├── api.h
│ ├── font_bind.h
│ ├── api.c
│ ├── parser.h
│ ├── font.h
│ └── font_bind.c
├── web
│ ├── api.h
│ ├── web_bind.h
│ ├── web.h
│ ├── web.lua
│ ├── api.c
│ ├── web_bind.c
│ └── web.c
├── audio
│ ├── api.h
│ ├── audio_bind.h
│ ├── sound_bind.h
│ ├── music_bind.h
│ ├── sound.h
│ ├── api.c
│ ├── audio_bind.c
│ ├── music.h
│ └── audio.h
├── event
│ ├── api.h
│ ├── event_bind.h
│ ├── event_bind.c
│ ├── api.c
│ └── event.h
├── utils
│ ├── api.h
│ └── api.c
├── particle
│ ├── api.h
│ ├── particle.h
│ ├── particle.c
│ ├── api.c
│ ├── system_bind.h
│ ├── particle.lua
│ └── system.h
├── storage
│ ├── api.h
│ ├── storage.h
│ ├── storage_bind.h
│ ├── api.c
│ └── storage_bind.c
├── graphics
│ ├── api.h
│ ├── camera_bind.h
│ ├── shader_bind.h
│ ├── buffer_bind.h
│ ├── camera.h
│ ├── opengl_util.h
│ ├── opengl_util.c
│ ├── display_bind.h
│ ├── shader.h
│ ├── sprite.lua
│ ├── camera.c
│ ├── shader_bind.c
│ ├── surface.h
│ ├── buffer_bind.c
│ └── camera_bind.c
├── physics
│ ├── api.hpp
│ ├── raycast.lua
│ ├── shape_bind.hpp
│ ├── world_bind.hpp
│ ├── body_bind.hpp
│ └── joint_bind.hpp
├── luafiles.h
├── livecoding.h
├── engine.h
├── dlua.h
├── lua_util.c
├── log.h
├── log.c
├── build.h
├── drystal.lua
├── macro.h
├── util.h
└── module.h
├── Makefile
├── cmake
├── BuildCoverage.cmake
├── GenerateLuaFiles.cmake
└── Utils.cmake
└── CMakeLists.txt
/doc/site/_ext/sphinx-lua/src/.gitignore:
--------------------------------------------------------------------------------
1 | sphinx_lua.egg-info
2 |
--------------------------------------------------------------------------------
/tests/audio/random/drystal.cfg:
--------------------------------------------------------------------------------
1 | [.]
2 | *.lua
3 | wget=*.wav
4 |
--------------------------------------------------------------------------------
/doc/site/_ext/sphinx-lua/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include RELEASE-VERSION
2 |
--------------------------------------------------------------------------------
/doc/site/_ext/sphinx-lua/setup.cfg:
--------------------------------------------------------------------------------
1 | [egg_info]
2 | tag_date = false
3 |
--------------------------------------------------------------------------------
/external/stb_truetype.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "stb_truetype.c"
4 |
--------------------------------------------------------------------------------
/spec/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/spec/32x32.png
--------------------------------------------------------------------------------
/spec/40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/spec/40x40.png
--------------------------------------------------------------------------------
/spec/bad_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/spec/bad_32x32.png
--------------------------------------------------------------------------------
/tools/busted:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ./tools/runner.py -r unittest -- $@
4 |
5 |
--------------------------------------------------------------------------------
/tests/audio/test.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/test.ogg
--------------------------------------------------------------------------------
/tests/audio/test.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/test.wav
--------------------------------------------------------------------------------
/tests/font/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/font/arial.ttf
--------------------------------------------------------------------------------
/tests/graphics/npot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/npot.png
--------------------------------------------------------------------------------
/tests/graphics/tex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/tex.png
--------------------------------------------------------------------------------
/doc/site/_static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/_static/logo.png
--------------------------------------------------------------------------------
/tests/graphics/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/arial.ttf
--------------------------------------------------------------------------------
/tests/graphics/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/image.png
--------------------------------------------------------------------------------
/doc/site/tutorials/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/arial.ttf
--------------------------------------------------------------------------------
/tests/audio/random/coin1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/coin1.wav
--------------------------------------------------------------------------------
/tests/audio/random/coin2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/coin2.wav
--------------------------------------------------------------------------------
/tests/audio/random/hurt1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/hurt1.wav
--------------------------------------------------------------------------------
/tests/audio/random/jump1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/jump1.wav
--------------------------------------------------------------------------------
/tests/audio/random/jump2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/jump2.wav
--------------------------------------------------------------------------------
/tests/graphics/precise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/precise.png
--------------------------------------------------------------------------------
/tests/particle/squish2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/particle/squish2.wav
--------------------------------------------------------------------------------
/tests/audio/random/select1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/audio/random/select1.wav
--------------------------------------------------------------------------------
/tests/graphics/spritesheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/spritesheet.png
--------------------------------------------------------------------------------
/tests/particle/spritesheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/particle/spritesheet.png
--------------------------------------------------------------------------------
/doc/site/tutorials/basics_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/basics_black.png
--------------------------------------------------------------------------------
/doc/site/tutorials/basics_board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/basics_board.png
--------------------------------------------------------------------------------
/doc/site/tutorials/basics_final.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/basics_final.gif
--------------------------------------------------------------------------------
/doc/site/tutorials/spritesheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/spritesheet.png
--------------------------------------------------------------------------------
/doc/site/tutorials/basics_gameover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/basics_gameover.png
--------------------------------------------------------------------------------
/doc/site/tutorials/basics_sprites.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/doc/site/tutorials/basics_sprites.png
--------------------------------------------------------------------------------
/tests/graphics/regressions/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidanger/Drystal/HEAD/tests/graphics/regressions/arial.ttf
--------------------------------------------------------------------------------
/tools/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | include(GNUInstallDirs)
2 | install(PROGRAMS drystaljs.py DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME drystaljs)
3 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build-*/
2 | /web
3 | *.pyc
4 | *.swp
5 | /doc/site/_build/
6 | /tests/storage/.storage
7 | .luarocks
8 | .rocks
9 | .storage
10 |
11 |
--------------------------------------------------------------------------------
/tests/misc/dir/livecode2.lua:
--------------------------------------------------------------------------------
1 | local L = {
2 | value=1,
3 | }
4 | L.__index = L
5 |
6 | function L.new()
7 | return setmetatable({}, L)
8 | end
9 |
10 | return L
11 |
12 |
--------------------------------------------------------------------------------
/external/miniz.h:
--------------------------------------------------------------------------------
1 | #define MINIZ_HEADER_FILE_ONLY
2 | #define MINIZ_NO_ARCHIVE_WRITING_APIS
3 | #define MINIZ_NO_TIME
4 | #define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
5 | #include "miniz.c"
6 |
--------------------------------------------------------------------------------
/misc/shell-completion/zsh/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | install(FILES "_drystal" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions/")
2 | install(FILES "_drystaljs" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions/")
3 |
--------------------------------------------------------------------------------
/tests/graphics/title.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | drystal.resize(400, 300)
5 | end
6 |
7 | local time = 0
8 |
9 | function drystal.update(dt)
10 | time = time + dt
11 | drystal.set_title(time)
12 | end
13 |
--------------------------------------------------------------------------------
/tests/drystal.cfg:
--------------------------------------------------------------------------------
1 | [options]
2 | version = prerelease
3 | destination = web
4 | zip = game.zip
5 | html = index.html
6 | htmltemplate = index.html
7 | arguments =
8 |
9 | [*]
10 | *.lua
11 | *.png
12 | *.ttf
13 | *.json
14 | *.ogg
15 | *.wav
16 |
--------------------------------------------------------------------------------
/doc/README.md:
--------------------------------------------------------------------------------
1 | Documentation build
2 | -------------------
3 |
4 | First, you need sphinx and pip (python2) then, as root, run:
5 |
6 | pip install sphinx_rtd_theme
7 |
8 | If you want to build the documentation in HTML go to doc/site/ and run:
9 |
10 | make html
11 |
--------------------------------------------------------------------------------
/doc/site/tutorials.rst:
--------------------------------------------------------------------------------
1 | Tutorials
2 | =========
3 |
4 | Here is a list of tutorials that will teach you how to use Drystal by creating games. We start with a basic
5 | tic-tac-toe, then we create a space invader and finally a plateformer.
6 |
7 | .. toctree::
8 |
9 | tutorials/basics.rst
10 |
11 |
--------------------------------------------------------------------------------
/tests/misc/fps.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | drystal.resize(400, 400)
5 | end
6 |
7 | function drystal.update(dt)
8 | print(1/dt, dt)
9 | end
10 |
11 | function drystal.key_press(key)
12 | if key == 'a' then
13 | drystal.stop()
14 | end
15 | end
16 |
17 |
--------------------------------------------------------------------------------
/tests/web/js.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.run_js [[
4 | document.title = "Drystal js.lua";
5 | document.body.style.backgroundColor = "red";
6 | window.alert("hello from drystal");
7 | ]]
8 |
9 | print(drystal.run_js [[
10 | "lol";
11 | ]])
12 |
13 | drystal.stop()
14 |
15 |
--------------------------------------------------------------------------------
/misc/shell-completion/zsh/_drystal:
--------------------------------------------------------------------------------
1 | #compdef drystal
2 |
3 | _arguments \
4 | {-h,--help}'[Show this help message and exit]' \
5 | {-v,--version}'[Show Drystal version and available features]' \
6 | {-l,--livecoding}'[Enable the livecoding which will reload the lua code when modifications on the files are performed]' \
7 | '1::Lua file:_files'
8 |
--------------------------------------------------------------------------------
/tests/misc/engine_stop.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | print 'should print: Exiting'
4 | function drystal.init()
5 | print 'should not be printed'
6 | end
7 |
8 | function drystal.update(dt)
9 | end
10 |
11 | function drystal.draw()
12 | end
13 |
14 | function drystal.atexit()
15 | print 'Exiting'
16 | end
17 |
18 | drystal.stop()
19 |
20 |
--------------------------------------------------------------------------------
/tools/unittest.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env drystal
2 |
3 | package.path = './.rocks/share/lua/5.3/?.lua;./.rocks/share/lua/5.3/?/init.lua;' .. package.path
4 | package.cpath = './.rocks/lib/lua/5.3/?.so;' .. package.cpath
5 |
6 | require 'moonscript'
7 | require 'spec.tools'
8 |
9 | require 'busted.runner' {
10 | standalone=false,
11 | }
12 |
13 | drystal = require 'drystal'
14 | drystal.stop()
15 |
16 |
--------------------------------------------------------------------------------
/tests/graphics/line.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(600, 400)
4 |
5 | local mx = 0
6 | local my = 0
7 |
8 | function drystal.draw()
9 | drystal.set_color(0, 0, 0)
10 | drystal.draw_background()
11 |
12 | drystal.set_color(255, 255, 255)
13 | drystal.draw_line(300, 200, mx, my, 6)
14 | end
15 |
16 | function drystal.mouse_motion(x, y)
17 | mx = x
18 | my = y
19 | end
20 |
--------------------------------------------------------------------------------
/doc/site/_ext/sphinx-lua/src/redjack/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # ----------------------------------------------------------------------
3 | # Copyright © 2012, RedJack, LLC.
4 | # All rights reserved.
5 | #
6 | # Please see the LICENSE.txt file in this distribution for license
7 | # details.
8 | # ----------------------------------------------------------------------
9 |
10 | __import__('pkg_resources').declare_namespace(__name__)
11 |
--------------------------------------------------------------------------------
/tools/drystal.supp:
--------------------------------------------------------------------------------
1 | {
2 | xorg_modules
3 | Memcheck:Leak
4 | ...
5 | obj:/usr/lib/xorg/modules/dri/*.so
6 | ...
7 | }
8 | {
9 | mesa
10 | Memcheck:Leak
11 | ...
12 | obj:/usr/lib/mesa/*.so*
13 | ...
14 | }
15 | {
16 | X11
17 | Memcheck:Leak
18 | ...
19 | obj:/usr/lib/libX11.so*
20 | ...
21 | }
22 | {
23 | alsa
24 | Memcheck:Leak
25 | ...
26 | obj:/usr/lib/libasound.so*
27 | ...
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/doc/site/_ext/sphinx-lua/src/redjack/sphinx/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # ----------------------------------------------------------------------
3 | # Copyright © 2012, RedJack, LLC.
4 | # All rights reserved.
5 | #
6 | # Please see the LICENSE.txt file in this distribution for license
7 | # details.
8 | # ----------------------------------------------------------------------
9 |
10 | __import__('pkg_resources').declare_namespace(__name__)
11 |
--------------------------------------------------------------------------------
/tests/misc/objects.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local s = drystal.screen
4 |
5 | s.x = 4
6 | assert(s.x == 4)
7 | assert(s.draw_on ~= nil)
8 | assert(getmetatable(s).draw_on ~= nil)
9 | assert(s.__self == s)
10 |
11 | assert(getmetatable(getmetatable(s)) == drystal.Surface)
12 | assert(getmetatable(getmetatable(s)).draw_on ~= nil)
13 |
14 | for k, v in pairs(getmetatable(s)) do
15 | print(k, v)
16 | end
17 |
18 | drystal.stop()
19 |
20 |
--------------------------------------------------------------------------------
/doc/man/drystal.xsl:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | 1
9 | 0
10 | 0
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/font/parser.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 | math.randomseed(os.time())
3 |
4 | local font = assert(drystal.load_font('arial.ttf', 20))
5 |
6 | function gen()
7 | local text = ''
8 | local chars = "{}|r:9"
9 | for i = 1, math.random(30) do
10 | local r =math.random(#chars)
11 | text = text .. chars:sub(r, r)
12 | end
13 | return text
14 | end
15 |
16 | for i = 1, 100 do
17 | local text = gen()
18 | print(text, font:sizeof(text))
19 | end
20 |
21 | drystal.stop()
22 |
23 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "external/lua"]
2 | path = external/lua
3 | url = https://github.com/kidanger/lua-5.3.git
4 | [submodule "external/lua-cjson"]
5 | path = external/lua-cjson
6 | url = https://github.com/mpx/lua-cjson.git
7 | [submodule "external/box2d"]
8 | path = external/box2d
9 | url = https://github.com/ansman/box2d.git
10 | [submodule "external/libpng"]
11 | path = external/libpng
12 | url = https://github.com/glennrp/libpng.git
13 | [submodule "external/zlib"]
14 | path = external/zlib
15 | url = https://github.com/madler/zlib
16 |
--------------------------------------------------------------------------------
/tests/graphics/npot.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | drystal.resize(300, 200)
5 | surf = assert(drystal.load_surface('npot.png'))
6 | local w, h = surf.w, surf.h
7 |
8 | assert(w == 200, 'width is not 200, ' .. w)
9 | assert(h == 150, 'height is not 150, ' .. h)
10 | surf:draw_from()
11 | end
12 |
13 | function drystal.draw()
14 | local sprite = {x=0,y=0,w=200,h=150}
15 | drystal.draw_sprite(sprite, 0, 0)
16 | end
17 |
18 | function drystal.key_press(k)
19 | if k == 'a' then
20 | drystal.stop()
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/tests/web/wget.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local function onsuccess(filename)
4 | print(filename, 'wgetted!')
5 | print(io.open(filename):read('*all'))
6 | end
7 |
8 | local function onerror(filename)
9 | print(filename, 'ko')
10 | end
11 |
12 | function drystal.init()
13 | print(drystal.is_web)
14 | drystal.wget('/', 'f1', onsuccess, onerror)
15 | drystal.wget('src/log.hpp', 'f2', onsuccess, onerror)
16 | drystal.wget('http://google.fr', 'f3', onsuccess, onerror)
17 | print 'boom'
18 | end
19 |
20 | function drystal.update()
21 | drystal.stop()
22 | end
23 |
24 |
--------------------------------------------------------------------------------
/tests/misc/livecode.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 | local L = require 'dir.livecode2'
3 |
4 | drystal.resize(300, 200)
5 |
6 | local l = L.new()
7 | print('value:', l.value)
8 |
9 | local old
10 | local time = 0
11 | function drystal.update(dt)
12 | time = time + dt
13 | if old ~= l.value then
14 | print(old, '->', l.value)
15 | old = l.value
16 | end
17 | if time > 1 then
18 | time = time - 1
19 | print('ping', dt)
20 | end
21 | end
22 |
23 | function drystal.key_press(k)
24 | if k == 'a' then
25 | drystal.stop()
26 | elseif k == 'x' then
27 | drystal.reload()
28 | end
29 | end
30 |
31 |
--------------------------------------------------------------------------------
/spec/storage_spec.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | describe 'storage', ->
4 |
5 | it 'stores data', ->
6 | drystal.store 'test_storage', {text:'blabla', duck:58}
7 | data = drystal.fetch 'test_storage'
8 | assert.same {text:'blabla', duck:58}, data
9 |
10 | it 'overwrites previous stored data', ->
11 | drystal.store 'test_storage', {text:'blabla', duck:58}
12 | drystal.store 'test_storage', {text:'foobar', duck:59}
13 | data = drystal.fetch 'test_storage'
14 | assert.same {text:'foobar', duck:59}, data
15 |
16 | it 'does not contain unknown keys', ->
17 | data = drystal.fetch 'unknown'
18 | assert.nil data
19 |
20 |
--------------------------------------------------------------------------------
/tests/event/pointer.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | drystal.resize(400, 400)
5 | print 'Press h to hide, r to set relative mode'
6 | end
7 |
8 | local relative = false
9 | local hidden = false
10 | function drystal.key_press(key)
11 | if key == 'a' then
12 | drystal.stop()
13 | elseif key == 'h' then
14 | hidden = not hidden
15 | drystal.show_cursor(not hidden)
16 | elseif key == 'r' then
17 | relative = not relative
18 | drystal.set_relative_mode(relative)
19 | end
20 | print('relative:', relative, 'hide:', hidden)
21 | end
22 |
23 | function drystal.mouse_motion(x, y, dx, dy)
24 | print(x, y, dx, dy)
25 | end
26 |
--------------------------------------------------------------------------------
/doc/site/_ext/sphinx-lua/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from setuptools import setup, find_packages
4 |
5 | from version import get_git_version
6 |
7 | try:
8 | import setuptools_git
9 | except ImportError:
10 | print("WARNING!")
11 | print("We need the setuptools-git package to be installed for")
12 | print("some of the setup.py targets to work correctly.")
13 |
14 | PACKAGE = 'sphinx-lua'
15 | VERSION = get_git_version()
16 |
17 | setup(
18 | name = PACKAGE,
19 | version = VERSION,
20 | package_dir = {'': 'src'},
21 | packages = find_packages('src'),
22 | namespace_packages = ['redjack', 'redjack.sphinx'],
23 | install_requires = ['Sphinx'],
24 | )
25 |
--------------------------------------------------------------------------------
/tests/graphics/read.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local image
4 |
5 | function drystal.init()
6 | drystal.resize(600, 400)
7 | image = drystal.load_surface('tex.png')
8 | end
9 |
10 | function drystal.draw()
11 | drystal.set_color(0, 0, 0)
12 | drystal.set_alpha(255)
13 | drystal.draw_background()
14 |
15 | local radius = 3
16 | for x = 1, image.w do
17 | for y = 1, image.h do
18 | local r, g, b, a = image:get_pixel(x, y)
19 | drystal.set_color(r, g, b)
20 | drystal.set_alpha(a)
21 | drystal.draw_point(x * radius, y * radius, radius)
22 | end
23 | end
24 | end
25 |
26 | function drystal.key_press(k)
27 | if k == 'a' then
28 | drystal.stop()
29 | end
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/spec/display_spec.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | describe 'display', ->
4 |
5 | before_each ->
6 | drystal.set_alpha 255
7 | drystal.set_color 'black'
8 | drystal.screen\draw_on!
9 | drystal.draw_background!
10 |
11 | it 'can resize', ->
12 | drystal.resize 120, 100
13 | assert.equals 120, drystal.screen.w
14 | assert.equals 100, drystal.screen.h
15 |
16 | drystal.resize 150, 110
17 | assert.equals 150, drystal.screen.w
18 | assert.equals 110, drystal.screen.h
19 |
20 | it 'draws lines', ->
21 | drystal.set_color 'red'
22 | drystal.draw_line 10, 10, 20, 10
23 | for i = 11, 20
24 | assert.color drystal.screen, i, 10, 'red'
25 | assert.color drystal.screen, i, 11, 'black'
26 |
27 |
--------------------------------------------------------------------------------
/tests/graphics/fullscreen.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(800, 600)
4 | function drystal.draw(dt)
5 | drystal.set_alpha(255)
6 | drystal.set_color(255, 25, 255)
7 | drystal.draw_background()
8 |
9 | drystal.set_color(255, 0, 0)
10 | drystal.draw_rect(50, 50, drystal.screen.w - 100, drystal.screen.h - 100)
11 | end
12 |
13 | local full = false
14 | function drystal.key_press(k)
15 | if k == 'f' then
16 | full = true
17 | drystal.set_fullscreen(true)
18 | elseif k == 'g' then
19 | full = false
20 | drystal.set_fullscreen(false)
21 | end
22 | end
23 |
24 | function drystal.page_resize(w, h)
25 | print(w, h)
26 | if full then
27 | drystal.set_fullscreen(true)
28 | end
29 | end
30 |
31 |
--------------------------------------------------------------------------------
/tests/graphics/regressions/font_draw_from.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(600, 400)
4 |
5 | local x, y = 0, 0
6 | local font = assert(drystal.load_font('arial.ttf', 25))
7 | local text = 'all fine!'
8 | local surface = drystal.new_surface(font:sizeof(text))
9 | local sprite = drystal.new_sprite({x=0, y=0, w=surface.w, h=surface.h}, x, y)
10 | sprite.angle = math.pi * 2
11 |
12 | function drystal.draw()
13 | collectgarbage()
14 | drystal.set_color(250, 20, 20)
15 | drystal.set_alpha(255)
16 | drystal.draw_background()
17 |
18 | local screen = surface:draw_on()
19 | drystal.set_color(0, 0, 0)
20 | font:draw(text, 0, 0)
21 | surface:draw_from()
22 | screen:draw_on()
23 |
24 | sprite:draw()
25 | end
26 |
--------------------------------------------------------------------------------
/tests/graphics/colors.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local color = drystal.colors['#22DD22']
4 |
5 | function drystal.init()
6 | drystal.resize(600, 400)
7 | print('press d or l or m or a')
8 | end
9 |
10 | function drystal.update(dt)
11 | end
12 |
13 | function drystal.draw()
14 | drystal.set_color(color)
15 | drystal.draw_background()
16 |
17 | drystal.set_color 'cyan'
18 | drystal.draw_rect(20, 20, 40, 40)
19 | end
20 |
21 | function drystal.key_press(key)
22 | if key == 'd' then
23 | color = color:darker()
24 | end
25 | if key == 'l' then
26 | color = color:lighter()
27 | end
28 | if key == 'm' then
29 | color = color * drystal.colors.steelblue
30 | end
31 | if key == 'a' then
32 | color = color + drystal.colors.red
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/tests/font/line.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(600, 400)
4 |
5 | local font = assert(drystal.load_font('arial.ttf', 20))
6 |
7 | local text = [[blba
8 | dsqdsq dsq
9 | k{g:40|??{outr:80|outline|ds}lol}qj dk{r:50|sq
10 | ds}qj dksq
11 | ]]
12 |
13 | function drystal.draw()
14 | drystal.set_color(0, 0, 0)
15 | drystal.draw_background()
16 |
17 | drystal.set_color(255, 255, 255)
18 |
19 | font:draw_plain(text, 10, 10)
20 | drystal.draw_square(10, 10, font:sizeof_plain(text))
21 |
22 | font:draw(text, 10, 100)
23 | drystal.draw_square(10, 100, font:sizeof(text))
24 |
25 | font:draw(text, 100, 200, drystal.aligns.center)
26 | drystal.draw_line(100, 200, 100, 300)
27 | font:draw(text, 300, 200, drystal.aligns.right)
28 | drystal.draw_line(300, 200, 300, 300)
29 | end
30 |
31 |
--------------------------------------------------------------------------------
/src/font/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(font)
22 |
23 |
--------------------------------------------------------------------------------
/src/web/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(web)
22 |
23 |
--------------------------------------------------------------------------------
/src/audio/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(audio)
22 |
23 |
--------------------------------------------------------------------------------
/src/event/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(event)
22 |
23 |
--------------------------------------------------------------------------------
/src/utils/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(utils)
22 |
23 |
--------------------------------------------------------------------------------
/src/particle/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(particle)
22 |
23 |
--------------------------------------------------------------------------------
/src/storage/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(storage)
22 |
23 |
--------------------------------------------------------------------------------
/tests/event/unicode.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | drystal.resize(400, 400)
5 | end
6 |
7 | function drystal.update()
8 | end
9 |
10 | function drystal.draw()
11 | end
12 |
13 | local text = ''
14 | local texting = false
15 |
16 | function drystal.key_press(key)
17 | print('key_press', key)
18 | if texting then
19 | if key == 'return' then
20 | texting = false
21 | print('=>', text)
22 | end
23 | else
24 | if key == 'i' then
25 | text = ''
26 | texting = true
27 | elseif key == 'a' then
28 | drystal.stop()
29 | end
30 | end
31 | end
32 | function drystal.key_release(key)
33 | print('key_release', key)
34 | end
35 |
36 | function drystal.key_text(str)
37 | if texting then
38 | print('key_text', str)
39 | text = text .. str
40 | print("text =", text)
41 | end
42 | end
43 |
44 |
--------------------------------------------------------------------------------
/tests/graphics/resize/resizable.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local w, h = 600, 400
4 |
5 | function drystal.init()
6 | print('init')
7 | drystal.resize(w, h)
8 | update_surf()
9 | end
10 |
11 | function drystal.draw()
12 | drystal.set_color(255, 255, 255)
13 | drystal.draw_background()
14 |
15 | drystal.set_color(0, 0, 0)
16 | drystal.draw_rect(2, 2, w - 4, h - 4)
17 | end
18 |
19 | function drystal.key_press(key)
20 | if key == 'h' then
21 | w = w - 100
22 | elseif key == 'l' then
23 | w = w + 100
24 | elseif key == 'j' then
25 | h = h + 100
26 | elseif key == 'k' then
27 | h = h - 100
28 | else
29 | return
30 | end
31 | drystal.resize(w, h)
32 | update_surf()
33 | end
34 |
35 | function update_surf()
36 | w, h = drystal.screen.w, drystal.screen.h
37 | print("hjlk to resize, current size is " .. w .. "x" .. h)
38 | end
39 |
40 |
--------------------------------------------------------------------------------
/src/event/event_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int mlua_set_relative_mode(lua_State* L);
22 |
23 |
--------------------------------------------------------------------------------
/src/web/web_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int mlua_wget(lua_State *L);
22 | int mlua_run_js(lua_State* L);
23 |
24 |
--------------------------------------------------------------------------------
/src/graphics/api.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "module.h"
20 |
21 | DECLARE_MODULE(graphics)
22 |
23 | int graphics_index(lua_State* L);
24 |
25 |
--------------------------------------------------------------------------------
/src/storage/storage.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | char* storage_fetch(const char* key);
20 | void storage_store(const char* key, const char* value);
21 |
22 |
--------------------------------------------------------------------------------
/src/storage/storage_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int mlua_store(lua_State* L);
22 | int mlua_fetch(lua_State* L);
23 |
24 |
--------------------------------------------------------------------------------
/doc/man/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | include(GNUInstallDirs)
2 |
3 | find_program(MAN_XSLTPROC xsltproc)
4 | if (NOT MAN_XSLTPROC)
5 | message(FATAL_ERROR "Unable to find xsltproc")
6 | endif()
7 |
8 | file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man1)
9 |
10 | set(MAN_RESOURCES
11 | drystal.xsl
12 | )
13 |
14 | add_custom_target(man)
15 | install(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_MAKE_PROGRAM} man)")
16 | function(add_manpage volume title)
17 | add_custom_command(TARGET man
18 | DEPENDS ${title}.${volume}.xml ${MAN_RESOURCES}
19 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
20 | COMMAND ${MAN_XSLTPROC} -nonet --xinclude -o "${CMAKE_CURRENT_BINARY_DIR}/man${volume}/" drystal.xsl ${title}.${volume}.xml
21 | )
22 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/man${volume}/${title}.${volume}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man${volume}")
23 | endfunction()
24 |
25 | add_manpage(1 drystal)
26 |
27 |
--------------------------------------------------------------------------------
/doc/site/resources.rst:
--------------------------------------------------------------------------------
1 | Resources
2 | =========
3 |
4 | .. Snippets
5 | .. --------
6 |
7 | Useful links
8 | ------------
9 |
10 | Lua
11 | ^^^
12 |
13 | - `Programming In Lua `_
14 | - `Lua 5.3 manual `_
15 |
16 |
17 | Box2D
18 | ^^^^^
19 |
20 | - `Box2D manual `_
21 | - `Some Box2D tutorials `_
22 |
23 |
24 | Lua libraries
25 | ^^^^^^^^^^^^^
26 |
27 | - `A simple class library `_
28 | - `Helper utilities `_ made for LÖVE but most can work with Drystal
29 | - `A tweening library `_
30 |
31 |
32 | Moonscript
33 | ^^^^^^^^^^
34 |
35 | `Moonscript `_ is a language that compiles to Lua. It can be used to create games with Drystal.
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/audio/audio_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int mlua_set_sound_volume(lua_State *L);
22 | int mlua_set_music_volume(lua_State *L);
23 |
24 |
--------------------------------------------------------------------------------
/src/web/web.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef EMSCRIPTEN
20 | char *run_js(const char* script);
21 | void wget(const char* url, const char* filename);
22 | #endif
23 |
24 |
--------------------------------------------------------------------------------
/tests/graphics/draw_point.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local mx, my = 0, 0
4 |
5 | function drystal.init()
6 | drystal.resize(600, 400)
7 | image = drystal.load_surface('tex.png')
8 | image:draw_from()
9 | end
10 |
11 | local time = 0
12 | function drystal.update(dt)
13 | time = time + dt
14 | end
15 |
16 | function drystal.draw()
17 | drystal.set_color(drystal.colors.white)
18 | drystal.draw_background()
19 |
20 | for y = 0, 400, 8 do
21 | for x = 0, 600, 8 do
22 | local r = math.sin((x + y + time*1000)/100)/2+0.5
23 | drystal.set_color(r*255, 0, 0)
24 | drystal.draw_point(x, y, 8)
25 | end
26 | end
27 |
28 | drystal.set_color(drystal.colors.lime)
29 | drystal.draw_point_tex(0, 0, mx-8, my-8, 15)
30 | end
31 |
32 | function drystal.mouse_motion(x, y)
33 | mx = x
34 | my = y
35 | end
36 |
37 | function drystal.key_press(k)
38 | if k == 'a' then
39 | drystal.stop()
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/tests/misc/compute_perf.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local W, H = 600, 400
4 | local target = 1 / 60
5 | local number = 100000
6 | local tick = 0
7 |
8 | function drystal.init()
9 | drystal.resize(W, H)
10 | end
11 |
12 | local function compute(n)
13 | local acc = 1
14 | for i = 1, n do
15 | acc = acc * 1.45 + 1/acc
16 | end
17 | return acc
18 | end
19 |
20 | local function compute_int(n)
21 | local acc = 1
22 | for i = 1, n do
23 | acc = acc * 2 - n / 10
24 | end
25 | return acc
26 | end
27 |
28 | function drystal.update(dt)
29 | compute(number)
30 | if tick > 4 then
31 | if dt > target then
32 | number = number * .99
33 | else
34 | number = number * 1.02
35 | end
36 | end
37 | tick = tick + 1
38 | if tick % 60 == 0 then
39 | print(math.floor(number), dt - target)
40 | end
41 | end
42 |
43 | function drystal.key_press(k)
44 | if k == 'a' then
45 | drystal.stop()
46 | end
47 | end
48 |
49 |
--------------------------------------------------------------------------------
/src/storage/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "storage_bind.h"
19 | #include "api.h"
20 |
21 | BEGIN_MODULE(storage)
22 | DECLARE_FUNCTION(store)
23 | DECLARE_FUNCTION(fetch)
24 | END_MODULE()
25 |
26 |
--------------------------------------------------------------------------------
/tools/setup_busted.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | if [ -z "$1" ]; then
4 | TYPE=Release
5 | else
6 | TYPE=$1
7 | fi
8 |
9 | rm -rf .luarocks
10 | rm -rf .rocks
11 |
12 | ROOT=`pwd`
13 | BUILD=$ROOT/build-native-$TYPE
14 | ROCKVER=2.2.2
15 |
16 | wget https://github.com/keplerproject/luarocks/archive/v${ROCKVER}.tar.gz || exit 1
17 | tar zxpf v${ROCKVER}.tar.gz
18 | rm luarocks-${ROCKVER}.tar.gz
19 | mv luarocks-$ROCKVER .luarocks
20 |
21 | cd .luarocks
22 | sh configure --lua-version=5.3 --with-lua-bin=$BUILD/external --with-lua-include=$ROOT/external/lua/src --prefix=`pwd` --sysconfdir=`pwd`/luarocks --force-config || exit 1
23 | make build || exit 1
24 | make install || exit 1
25 | cd ..
26 |
27 | ./.luarocks/bin/luarocks --tree=.rocks install busted || exit 1
28 | ./.luarocks/bin/luarocks --tree=.rocks install moonscript || exit 1
29 | ./.luarocks/bin/luarocks --tree=.rocks install lua_cliargs 2.5-5 || exit 1 # temporary fix for outdated busted
30 |
31 |
--------------------------------------------------------------------------------
/src/physics/api.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #include "module.h"
24 |
25 | DECLARE_MODULE(physics)
26 |
27 | #ifdef __cplusplus
28 | }
29 | #endif
30 |
31 |
--------------------------------------------------------------------------------
/src/web/web.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | if drystal.is_web then
4 | drystal.raw_wget = drystal.wget
5 | local wget_requests = {}
6 |
7 | function drystal.on_wget_success(file)
8 | for _, f in ipairs(wget_requests[file].onload) do
9 | f(file)
10 | end
11 | wget_requests[file] = nil
12 | end
13 | function drystal.on_wget_error(file)
14 | for _, f in ipairs(wget_requests[file].onerror) do
15 | f(file)
16 | end
17 | wget_requests[file] = nil
18 | end
19 |
20 | function drystal.wget(url, file, onload, onerror)
21 | assert(onload)
22 | assert(onerror)
23 |
24 | if not drystal.is_web then
25 | return
26 | end
27 |
28 | if wget_requests[file] then
29 | -- already requested
30 | table.insert(wget_requests[file].onload, onload)
31 | table.insert(wget_requests[file].onerror, onerror)
32 | return
33 | end
34 |
35 | drystal.raw_wget(url, file)
36 | wget_requests[file] ={
37 | onload={onload},
38 | onerror={onerror},
39 | }
40 | end
41 | end
42 |
43 |
--------------------------------------------------------------------------------
/tests/graphics/draw_polygon.lua:
--------------------------------------------------------------------------------
1 | local drystal = require "drystal"
2 |
3 | local mouse_points = {
4 | }
5 |
6 | function drystal.init()
7 | drystal.resize(600, 400)
8 | end
9 |
10 | function drystal.draw()
11 | drystal.set_alpha(255)
12 | drystal.set_color(255, 255, 255)
13 | drystal.draw_background()
14 |
15 | drystal.set_color(0, 0, 0)
16 | local points = {
17 | 25, 25,
18 | 50, 25,
19 | 75, 50,
20 | 25, 50,
21 | 25, 25
22 | }
23 |
24 | drystal.draw_polygon(unpack(points))
25 |
26 | drystal.set_color(200, 0, 0)
27 | drystal.draw_polyline(false, 5, unpack(points))
28 |
29 | if #mouse_points > 2 then
30 | drystal.draw_polygon(unpack(mouse_points))
31 | drystal.set_color(255, 0, 0)
32 | drystal.draw_polyline(true, unpack(mouse_points))
33 | end
34 | end
35 |
36 | function drystal.mouse_press(x, y, b)
37 | table.insert(mouse_points, x)
38 | table.insert(mouse_points, y)
39 | end
40 |
41 | function drystal.key_press(key)
42 | if key == 'a' then
43 | drystal.stop()
44 | end
45 | end
46 |
47 |
--------------------------------------------------------------------------------
/src/luafiles.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | /**
22 | * luafiles.c is generated by CMake at compile time.
23 | * This functions runs .lua files (located in src/) and return 1 if success.
24 | */
25 | int load_luafiles(lua_State* L, int traceback_index);
26 |
27 |
--------------------------------------------------------------------------------
/src/graphics/camera_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int mlua_camera__newindex(lua_State* L);
22 | int mlua_camera__index(lua_State* L);
23 | int mlua_camera_reset(lua_State*);
24 | int mlua_camera_push(lua_State *L);
25 | int mlua_camera_pop(lua_State *L);
26 |
27 |
--------------------------------------------------------------------------------
/external/cjson-fpconv.patch:
--------------------------------------------------------------------------------
1 | diff --git a/fpconv.c b/fpconv.c
2 | index 7990831..c9a1330 100644
3 | --- a/fpconv.c
4 | +++ b/fpconv.c
5 | @@ -49,6 +49,7 @@ static char locale_decimal_point = '.';
6 | * localconv() may not be thread safe (=>crash), and nl_langinfo() is
7 | * not supported on some platforms. Use sprintf() instead - if the
8 | * locale does change, at least Lua CJSON won't crash. */
9 | +#ifndef USE_INTERNAL_FPCONV
10 | static void fpconv_update_locale()
11 | {
12 | char buf[8];
13 | @@ -65,6 +66,13 @@ static void fpconv_update_locale()
14 | locale_decimal_point = buf[1];
15 | }
16 |
17 | +void fpconv_init()
18 | +{
19 | + fpconv_update_locale();
20 | +}
21 | +#endif
22 | +
23 | +
24 | /* Check for a valid number character: [-+0-9a-yA-Y.]
25 | * Eg: -0.6e+5, infinity, 0xF0.F0pF0
26 | *
27 | @@ -196,10 +204,5 @@ int fpconv_g_fmt(char *str, double num, int precision)
28 | return len;
29 | }
30 |
31 | -void fpconv_init()
32 | -{
33 | - fpconv_update_locale();
34 | -}
35 | -
36 | /* vi:ai et sw=4 ts=4:
37 | */
38 |
--------------------------------------------------------------------------------
/src/event/event_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 |
20 | #include "event.h"
21 | #include "event_bind.h"
22 |
23 | int mlua_set_relative_mode(lua_State* L)
24 | {
25 | assert(L);
26 |
27 | bool relative = lua_toboolean(L, 1);
28 | event_set_relative_mode(relative);
29 | return 0;
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/tests/audio/random/main.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local sounds = {
4 | 'jump1.wav',
5 | 'jump2.wav',
6 | 'hurt1.wav',
7 | 'coin1.wav',
8 | 'coin2.wav',
9 | }
10 |
11 | local loaded = {}
12 | for i, s in pairs(sounds) do
13 | if not drystal.file_exists(s) then
14 | drystal.wget(s, s, function ()
15 | local sound = drystal.load_sound(s)
16 | loaded[i] = sound
17 | end, function() print('can\'t download sound', s) end)
18 | else
19 | local sound = drystal.load_sound(s)
20 | print(sound)
21 | loaded[i] = sound
22 | end
23 | end
24 |
25 | function drystal.init()
26 | drystal.resize(400, 400)
27 | drystal.set_sound_volume(0.1)
28 | end
29 |
30 | function drystal.mouse_motion()
31 | loaded[math.random(#loaded)]:play()
32 | end
33 |
34 | function quick_play(str)
35 | local sound = drystal.load_sound(str)
36 | sound:play()
37 | end
38 |
39 | function drystal.key_press(k)
40 | if k == 't' then
41 | quick_play(sounds[math.random(#loaded)])
42 | elseif k == 'escape' or k == 'a' then
43 | drystal.stop()
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/src/livecoding.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | int livecoding_init(void (*callback)(void *arg, const char* filename), void *arg);
20 | int livecoding_watch_directory(const char *directory);
21 | int livecoding_watch_directory_recursively(const char *path);
22 | int livecoding_quit(void);
23 | int livecoding_is_running(void);
24 |
25 |
--------------------------------------------------------------------------------
/src/audio/sound_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "sound.h"
23 |
24 | DECLARE_PUSHPOP(Sound, sound)
25 |
26 | int mlua_load_sound(lua_State *L);
27 | int mlua_create_sound(lua_State *L);
28 | int mlua_play_sound(lua_State *L);
29 | int mlua_free_sound(lua_State *L);
30 |
31 |
--------------------------------------------------------------------------------
/tests/event/hooks.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.init()
4 | print'init'
5 | drystal.resize(400, 400)
6 | end
7 |
8 | function drystal.update(dt)
9 | --print('update, dt')
10 | end
11 |
12 | function drystal.draw()
13 | --print'draw'
14 | end
15 |
16 | function drystal.key_press(key)
17 | print('key_press', key)
18 | if key == 'a' then
19 | drystal.stop()
20 | end
21 | end
22 | function drystal.key_release(key)
23 | print('key_release', key)
24 | end
25 | function drystal.key_text(char)
26 | print('key_text', char)
27 | end
28 |
29 | function drystal.mouse_press(x, y, b)
30 | if b == drystal.buttons.left then
31 | print('button left pressed')
32 | end
33 | print('mouse_press', x, y, b)
34 | end
35 | function drystal.mouse_motion(x, y, dx, dy)
36 | print('mouse_motion', x, y, dx, dy)
37 | end
38 | function drystal.mouse_release(x, y, b)
39 | if b == drystal.buttons.left then
40 | print('button left released')
41 | end
42 | print('mouse_release', x, y, b)
43 | end
44 |
45 | function drystal.atexit()
46 | print'atexit'
47 | end
48 |
49 |
--------------------------------------------------------------------------------
/src/web/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 |
19 | #include "module.h"
20 | #include "web_bind.h"
21 | #include "api.h"
22 |
23 | BEGIN_MODULE(web)
24 | #ifdef EMSCRIPTEN
25 | DECLARE_BOOLEAN(is_web, true)
26 | #else
27 | DECLARE_BOOLEAN(is_web, false)
28 | #endif
29 | DECLARE_FUNCTION(wget)
30 | DECLARE_FUNCTION(run_js)
31 | END_MODULE()
32 |
33 |
--------------------------------------------------------------------------------
/tests/particle/fire.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | if not sys1 then -- for livecoding
4 | sys1 = drystal.new_system(100, 550)
5 | end
6 |
7 | sys1:set_sizes {
8 | [0]=20,
9 | [.2]={7, 10},
10 | [1]=5,
11 | }
12 | sys1:set_colors {
13 | [0.05]=drystal.colors.red:darker(),
14 | [0.4]={'orange', 'yellow'},
15 | [0.9]='black',
16 | }
17 |
18 | sys1:set_lifetime(3)
19 |
20 | sys1:set_direction(- math.pi / 2 - math.pi/12, -math.pi/2 + math.pi/12)
21 | sys1:set_initial_velocity(100)
22 | sys1:set_initial_acceleration(0)
23 | sys1:set_emission_rate(100)
24 | tex = drystal.load_surface('spritesheet.png')
25 | sys1:set_texture(tex, 64, 0)
26 |
27 | function drystal.init()
28 | drystal.resize(600, 600)
29 | sys1:start()
30 | end
31 |
32 | function drystal.update(dt)
33 | if dt > .06 then
34 | dt = .06
35 | end
36 | sys1:update(dt)
37 | end
38 |
39 | function drystal.draw()
40 | drystal.set_color(0, 0, 0)
41 | drystal.draw_background()
42 |
43 | sys1:draw()
44 | end
45 |
46 | function drystal.key_press(k)
47 | if k == 'a' then
48 | drystal.stop()
49 | end
50 | end
51 |
52 |
--------------------------------------------------------------------------------
/tests/physics/destroy.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.init_physics(0, 0)
4 |
5 | local shape = drystal.new_shape('circle', 5)
6 | local body = drystal.new_body(true, shape)
7 | local body2 = drystal.new_body(true, shape)
8 | shape = nil
9 | collectgarbage()
10 |
11 | local joint = drystal.new_joint('distance', body, body2)
12 |
13 | print(body:get_position())
14 | body:destroy()
15 | -- the joint should be destroyed yet
16 |
17 | if pcall(body.get_position, body) then
18 | error("body:get_position should fail after body:destroy")
19 | end
20 | if pcall(joint.destroy, joint) then
21 | error("joint:destroy should fail after body:destroy")
22 | end
23 |
24 | body = nil
25 | if pcall(joint.set_length, joint, 1) then
26 | error('joint:set_length should fail after body:destroy')
27 | end
28 |
29 | joint = nil -- no need to destroy it, body:destroy() did it
30 | collectgarbage()
31 |
32 | body2 = nil
33 | if pcall(collectgarbage) then
34 | error("body2 = nil + collectgarbage should fail because body2 hasn't been destroyed")
35 | end
36 |
37 | print 'ending'
38 | drystal.stop()
39 |
40 |
--------------------------------------------------------------------------------
/src/graphics/shader_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "shader.h"
23 |
24 | DECLARE_PUSHPOP(Shader, shader)
25 |
26 | int mlua_new_shader(lua_State* L);
27 | int mlua_use_shader(lua_State* L);
28 | int mlua_use_default_shader(lua_State* L);
29 | int mlua_feed_shader(lua_State* L);
30 | int mlua_free_shader(lua_State* L);
31 |
32 |
--------------------------------------------------------------------------------
/tests/font/simple_draw.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local font, font_big
4 | function drystal.init()
5 | drystal.resize(512, 512)
6 |
7 | font = drystal.load_font('arial.ttf', 16)
8 | font_big = drystal.load_font('arial.ttf', 42)
9 | end
10 |
11 | local time = 0
12 | function drystal.update(dt)
13 | time = time + dt
14 | end
15 |
16 | local function highlight(text, pos)
17 | pos = math.floor(pos)
18 | return text:sub(0, pos-1) .. '{big|'.. text:sub(pos, pos) .. '}' .. text:sub(pos+1, -1)
19 | end
20 |
21 | function drystal.draw()
22 | drystal.set_alpha(255)
23 | drystal.set_color(200, 200, 200)
24 | drystal.draw_background()
25 |
26 | drystal.set_color(255, 0, 0)
27 | font:draw('abcdefghijklmopqrstuvwxyz', 512 / 2, 100, drystal.aligns.center)
28 |
29 | local text = 'abd {r:0|big|b:150|bla} {small|test} {big|%:50|defghi}'
30 | text = highlight(text, (math.sin(time/10)/2+0.5)*#text + 1)
31 | font_big:draw(text, 512 / 2, 512 / 2, drystal.aligns.center)
32 |
33 | font:draw_plain(text, 10, 512 * 0.7)
34 | end
35 |
36 | function drystal.key_press(k)
37 | if k == 'a' then
38 | drystal.stop()
39 | end
40 | end
41 |
42 |
--------------------------------------------------------------------------------
/tests/event/relative.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(800, 600)
4 |
5 | local relative = false
6 |
7 | local mx = 0
8 | local my = 0
9 | function drystal.draw()
10 | drystal.set_color(0, 0, 0)
11 | drystal.draw_background()
12 |
13 | drystal.set_color(255, 255, 255)
14 | drystal.draw_circle(mx, my, 10)
15 | end
16 |
17 | function drystal.mouse_motion(x, y, dx, dy)
18 | --print(x, y, dx, dy)
19 | if not relative then
20 | mx = x
21 | my = y
22 | else
23 | mx = mx + dx
24 | my = my + dy
25 | if mx < 0 then mx = 0 end
26 | if mx >= drystal.screen.w then mx = drystal.screen.w - 1 end
27 | if my < 0 then my = 0 end
28 | if my >= drystal.screen.h then my = drystal.screen.h - 1 end
29 | end
30 | end
31 |
32 | function drystal.key_press(k)
33 | if k == 'a' then
34 | drystal.stop()
35 | elseif k == 'space' then
36 | relative = not relative
37 | drystal.set_relative_mode(relative)
38 | print(relative)
39 | end
40 | end
41 |
42 | --drystal.run_js [[
43 | --var canvas = document.getElementById('canvas');
44 | --canvas.onmouseover = function() {
45 | --canvas.requestPointerLock();
46 | --};
47 | --]]
48 |
--------------------------------------------------------------------------------
/src/font/font_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "font.h"
23 |
24 | DECLARE_PUSHPOP(Font, font)
25 |
26 | int mlua_draw_font(lua_State* L);
27 | int mlua_draw_plain_font(lua_State* L);
28 | int mlua_load_font(lua_State* L);
29 | int mlua_sizeof_font(lua_State* L);
30 | int mlua_sizeof_plain_font(lua_State* L);
31 | int mlua_free_font(lua_State* L);
32 |
33 |
--------------------------------------------------------------------------------
/src/utils/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "api.h"
19 |
20 | extern int json_encode(lua_State* L);
21 | extern int json_decode(lua_State* L);
22 | extern void lua_cjson_init();
23 |
24 | BEGIN_MODULE(utils)
25 | lua_cjson_init();
26 |
27 | lua_pushcfunction(L, json_encode);
28 | lua_setfield(L, -2, "tojson");
29 |
30 | lua_pushcfunction(L, json_decode);
31 | lua_setfield(L, -2, "fromjson");
32 | END_MODULE()
33 |
34 |
--------------------------------------------------------------------------------
/tests/graphics/image.json:
--------------------------------------------------------------------------------
1 | {"frames": {
2 |
3 | "block.png":
4 | {
5 | "frame": {"x":2,"y":2,"w":32,"h":32},
6 | "rotated": false,
7 | "trimmed": false,
8 | "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
9 | "sourceSize": {"w":32,"h":32}
10 | },
11 | "bonus.png":
12 | {
13 | "frame": {"x":36,"y":2,"w":32,"h":32},
14 | "rotated": false,
15 | "trimmed": false,
16 | "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
17 | "sourceSize": {"w":32,"h":32}
18 | },
19 | "character.png":
20 | {
21 | "frame": {"x":70,"y":2,"w":32,"h":32},
22 | "rotated": false,
23 | "trimmed": false,
24 | "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
25 | "sourceSize": {"w":32,"h":32}
26 | },
27 | "logo.png":
28 | {
29 | "frame": {"x":104,"y":2,"w":1023,"h":324},
30 | "rotated": false,
31 | "trimmed": false,
32 | "spriteSourceSize": {"x":0,"y":0,"w":1023,"h":324},
33 | "sourceSize": {"w":1023,"h":324}
34 | }},
35 | "meta": {
36 | "app": "http://www.texturepacker.com",
37 | "version": "1.0",
38 | "image": "image.png",
39 | "format": "RGBA8888",
40 | "size": {"w":2048,"h":512},
41 | "scale": "1",
42 | "smartupdate": "$TexturePacker:SmartUpdate:1a3d32f49cf3ed1fcd8cfad8d8f9df74$"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/graphics/sprites.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(600, 400)
4 |
5 | local spritesheet = assert(drystal.fromjson(io.open('image.json'):read('*all')))
6 | local sprite = spritesheet.frames['character.png'].frame
7 |
8 | image = assert(drystal.load_surface(spritesheet.meta.image))
9 | image:draw_from()
10 |
11 | local sprites = {}
12 |
13 | function drystal.update(dt)
14 | for _, s in ipairs(sprites) do
15 | s:update(dt)
16 | end
17 | end
18 |
19 | function drystal.draw()
20 | drystal.set_color(20, 20, 20)
21 | drystal.draw_background()
22 |
23 | for _, s in ipairs(sprites) do
24 | s:draw()
25 | end
26 | end
27 |
28 | local s1 = drystal.new_sprite(sprite, 300, 200, 40, 40)
29 | s1.color = drystal.colors.red
30 | s1.update = function(self, dt)
31 | self.angle = self.angle + dt * math.pi * 2
32 | end
33 |
34 | local s2 = drystal.new_sprite(sprite, 150, 200, 100, 100)
35 | s2.update=function(self, dt)
36 | self.angle = self.angle + dt * math.pi * 2
37 | self.color[1] = self.color[1] + dt * 255 * 2
38 | if self.color[1] > 255 then
39 | self.color[1] = 0
40 | end
41 | end
42 |
43 | table.insert(sprites, s1)
44 | table.insert(sprites, s2)
45 |
46 |
--------------------------------------------------------------------------------
/src/audio/music_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "music.h"
22 | #include "lua_util.h"
23 |
24 | DECLARE_PUSHPOP(Music, music)
25 |
26 | int mlua_load_music(lua_State *L);
27 | int mlua_play_music(lua_State *L);
28 | int mlua_stop_music(lua_State *L);
29 | int mlua_pause_music(lua_State *L);
30 | int mlua_free_music(lua_State *L);
31 | int mlua_set_pitch_music(lua_State *L);
32 | int mlua_set_volume_music(lua_State *L);
33 |
34 |
--------------------------------------------------------------------------------
/src/event/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "event_bind.h"
19 | #include "event.h"
20 | #include "api.h"
21 |
22 | BEGIN_MODULE(event)
23 | DECLARE_FUNCTION(set_relative_mode)
24 | BEGIN_ENUM()
25 | ADD_CONSTANT("left", BUTTON_LEFT)
26 | ADD_CONSTANT("middle", BUTTON_MIDDLE)
27 | ADD_CONSTANT("right", BUTTON_RIGHT)
28 | ADD_CONSTANT("wheel_up", WHEEL_UP)
29 | ADD_CONSTANT("wheel_down", WHEEL_DOWN)
30 | REGISTER_ENUM("buttons")
31 | END_MODULE()
32 |
33 |
--------------------------------------------------------------------------------
/src/graphics/buffer_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "buffer.h"
23 |
24 | DECLARE_PUSHPOP(Buffer, buffer)
25 |
26 | int mlua_new_buffer(lua_State* L);
27 | int mlua_use_buffer(lua_State* L);
28 | int mlua_use_default_buffer(lua_State* L);
29 | int mlua_draw_buffer(lua_State* L);
30 | int mlua_reset_buffer(lua_State* L);
31 | int mlua_upload_and_free_buffer(lua_State* L);
32 | int mlua_free_buffer(lua_State* L);
33 |
34 |
--------------------------------------------------------------------------------
/tests/font/position.lua:
--------------------------------------------------------------------------------
1 | local drystal = require "drystal"
2 |
3 | local arial
4 | function drystal.init()
5 | drystal.resize(600, 400);
6 | arial = assert(drystal.load_font('arial.ttf', 25))
7 | end
8 | local time = 0
9 |
10 | function drystal.update(dt)
11 | time = time + dt
12 | end
13 |
14 | local shadowx = 0
15 | local shadowy = 0
16 | function drystal.draw()
17 | drystal.set_color(255, 255, 255)
18 | drystal.draw_background()
19 |
20 | drystal.set_color(0, 0, 0)
21 | local text = '{outline|outg:%f|yeah it\'s c{outg:0|o}ol!}'
22 | text = text:format((math.sin(time) / 2 + .5)*255)
23 | local y = 20
24 | local x = 20
25 |
26 | local w, h = arial:sizeof_plain(text)
27 | drystal.draw_square(x, y, w, h)
28 | arial:draw_plain(text, x, y)
29 |
30 | y = y + h + 5
31 | local w, h = arial:sizeof(text)
32 | drystal.draw_square(x, y, w, h)
33 | drystal.set_color(255, 255, 255)
34 | arial:draw(text, x, y)
35 |
36 | drystal.set_color(0, 0, 0)
37 | local shadowed = 'Oh {shadowx:%.2f|shadowy:%.2f|outline|r:200|waw!}'
38 | shadowed = shadowed:format(shadowx, shadowy)
39 | arial:draw(shadowed, 300, 200, 2)
40 | end
41 |
42 | function drystal.mouse_motion(x, y)
43 | shadowx = (300 - x) / 300 * 5
44 | shadowy = (200 - y) / 200 * 5
45 | end
46 |
--------------------------------------------------------------------------------
/src/audio/sound.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | typedef struct Sound Sound;
23 |
24 | struct Sound {
25 | ALuint alBuffer;
26 | char* filename;
27 | bool free_me;
28 | int ref;
29 | };
30 |
31 | void sound_play(Sound *sound, float volume, float x, float y, float pitch);
32 | void sound_free(Sound *sound);
33 |
34 | int sound_load_from_file(const char *filepath, Sound **sound);
35 | Sound *sound_load(unsigned int len, const float* buffer, int samplesrate);
36 |
37 |
--------------------------------------------------------------------------------
/src/engine.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | int engine_init(const char *filename, unsigned int target_fps);
22 | void engine_free(void);
23 | void engine_load(void);
24 | void engine_loop(void);
25 | void engine_update(void);
26 | bool engine_is_loaded(void);
27 | void engine_stop(void);
28 | void engine_toggle_update(void);
29 | void engine_toggle_draw(void);
30 | #ifdef BUILD_LIVECODING
31 | void engine_wait_next_reload(void);
32 | void engine_add_file_to_reloadqueue(const char* filename);
33 | #endif
34 |
35 |
--------------------------------------------------------------------------------
/src/physics/raycast.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.raw_raycast = drystal.raycast
4 |
5 | local function any(body, fraction)
6 | return 0, true
7 | end
8 |
9 | local function closest(body, fraction)
10 | return fraction, true
11 | end
12 |
13 | local function farthest(destx, desty)
14 | local distance
15 |
16 | return function(body, fraction, x, y)
17 | local d = math.distance(destx, desty, x, y)
18 | if not distance or d < distance then
19 | distance = d
20 | return 1, true
21 | end
22 | return 1, false
23 | end
24 | end
25 |
26 | local function all(bodies, points)
27 | return function(body, fraction, x, y)
28 | table.insert(bodies, body)
29 | table.insert(points, {x, y})
30 | return 1, fraction
31 | end
32 | end
33 |
34 | function drystal.raycast(x1, y1, x2, y2, method)
35 | if method == 'any' then
36 | method = any
37 | elseif method == 'closest' then
38 | method = closest
39 | elseif method == 'farthest' or method == 'furthest' then
40 | method = farthest(x2, y2)
41 | elseif method == 'all' then
42 | local bodies = {}
43 | local points = {}
44 | drystal.raw_raycast(x1, y1, x2, y2, all(bodies, points))
45 | return bodies, points
46 | end
47 | return drystal.raw_raycast(x1, y1, x2, y2, method)
48 | end
49 |
50 |
--------------------------------------------------------------------------------
/misc/shell-completion/zsh/_drystaljs:
--------------------------------------------------------------------------------
1 | #compdef drystaljs
2 |
3 | _drystaljs_publish() {
4 | _arguments \
5 | {-h,--help}'[Show this help message and exit]' \
6 | {-n,--no-push}'[Do not push after commiting]'
7 | }
8 |
9 | _drystaljs_pack() {
10 | _arguments \
11 | {-h,--help}'[Show this help message and exit]' \
12 | {-l,--local=}'[Use a local javascript file]:javascript file:_files'
13 | }
14 |
15 | (( $+functions[_drystaljs_command] )) || _drystaljs_command()
16 | {
17 | local -a _drystaljs_cmds
18 | _drystaljs_cmds=(
19 | "init:Initialize configuration"
20 | "clean:Clean directory"
21 | "run:Run in a browser"
22 | "pack:Pack"
23 | "publish:Publish"
24 | )
25 | if (( CURRENT == 1 )); then
26 | _describe -t commands 'drystaljs command' _drystaljs_cmds || compadd "$@"
27 | else
28 | local curcontext="$curcontext"
29 | cmd="${${_drystaljs_cmds[(r)$words[1]:*]%%:*}}"
30 | if (( $+functions[_drystaljs_$cmd] )); then
31 | _drystaljs_$cmd
32 | else
33 | _message "no more options"
34 | fi
35 | fi
36 | }
37 |
38 | _arguments \
39 | {-h,--help}'[Show this help message and exit]' \
40 | '*::drystaljs command:_drystaljs_command'
41 |
--------------------------------------------------------------------------------
/spec/audio_spec.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | describe 'audio', ->
4 | describe 'music', ->
5 | it 'loads ogg', ->
6 | with m = drystal.load_music 'tests/audio/test.ogg'
7 | assert.not_nil m
8 |
9 | it 'returns an error if the file does not exist', ->
10 | with ok, err = drystal.load_music 'does_not_exist.ogg'
11 | assert.nil ok
12 | assert.string err
13 |
14 | it 'returns an error if the file is not an ogg', ->
15 | with ok, err = drystal.load_music 'spec/surface_spec.moon'
16 | assert.nil ok
17 | assert.string err
18 | with ok, err = drystal.load_music 'tests/audio/test.wav'
19 | assert.nil ok
20 | assert.string err
21 |
22 | describe 'sound', ->
23 | it 'loads wav', ->
24 | with s = drystal.load_sound 'tests/audio/test.wav'
25 | assert.not_nil s
26 |
27 | it 'returns an error if the file does not exist', ->
28 | with ok, err = drystal.load_sound 'does_not_exist.wav'
29 | assert.nil ok
30 | assert.string err
31 |
32 | it 'returns an error if the file is not an wav', ->
33 | with ok, err = drystal.load_sound 'spec/surface_spec.moon'
34 | assert.nil ok
35 | assert.string err
36 | with ok, err = drystal.load_sound 'tests/audio/test.ogg'
37 | assert.nil ok
38 | assert.string err
39 |
40 |
--------------------------------------------------------------------------------
/src/graphics/camera.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | typedef struct Camera Camera;
22 |
23 | struct Camera {
24 | float dx;
25 | float dy;
26 | float zoom;
27 | float angle;
28 | float matrix[4];
29 | };
30 |
31 | Camera *camera_new(void);
32 | void camera_free(Camera *c);
33 |
34 | void camera_update_matrix(Camera *c, int width, int height);
35 | void camera_reset(Camera *c);
36 | void camera_push(Camera *c);
37 | void camera_pop(Camera *c);
38 | bool camera_stack_is_full(void);
39 | bool camera_stack_is_empty(void);
40 |
41 |
--------------------------------------------------------------------------------
/src/particle/particle.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | typedef struct Particle Particle;
22 |
23 | #include "system.h"
24 |
25 | struct Particle {
26 | bool dead;
27 |
28 | float x, y;
29 | float vel;
30 | float accel;
31 | float dir_angle;
32 |
33 | float life, lifetime;
34 |
35 | int size_state;
36 | float sizeseed;
37 |
38 | int color_state;
39 | float rseed;
40 | float gseed;
41 | float bseed;
42 |
43 | int alpha_state;
44 | float alphaseed;
45 | };
46 |
47 | void particle_update(Particle *p, System *sys, float dt);
48 |
49 |
--------------------------------------------------------------------------------
/src/font/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "font_bind.h"
19 | #include "font.h"
20 | #include "api.h"
21 |
22 | BEGIN_MODULE(font)
23 | DECLARE_FUNCTION(load_font)
24 |
25 | BEGIN_CLASS(font)
26 | ADD_METHOD(font, draw)
27 | ADD_METHOD(font, draw_plain)
28 | ADD_METHOD(font, sizeof)
29 | ADD_METHOD(font, sizeof_plain)
30 | ADD_GC(free_font)
31 | REGISTER_CLASS(font, "Font")
32 |
33 | BEGIN_ENUM()
34 | ADD_CONSTANT("left", ALIGN_LEFT)
35 | ADD_CONSTANT("center", ALIGN_CENTER)
36 | ADD_CONSTANT("right", ALIGN_RIGHT)
37 | REGISTER_ENUM("aligns")
38 | END_MODULE()
39 |
40 |
--------------------------------------------------------------------------------
/spec/color_spec.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | describe 'color', ->
4 |
5 | it 'has W3C colors', ->
6 | assert.same {255, 0, 0}, {table.unpack drystal.colors.red}
7 | assert.same {0, 0, 0}, {table.unpack drystal.colors.black}
8 |
9 | it 'supports hexadecimal formatting', ->
10 | assert.same {0, 0, 0}, {table.unpack drystal.colors['#000000']}
11 | assert.same {255, 255, 255}, {table.unpack drystal.colors['#ffffff']}
12 | assert.same {15, 15, 15}, {table.unpack drystal.colors['#0f0f0f']}
13 | assert.same {16, 16, 16}, {table.unpack drystal.colors['#101010']}
14 | assert.same {255, 255, 255}, {table.unpack drystal.colors['#fff']}
15 |
16 | it 'is case insensitive', ->
17 | assert.same {table.unpack drystal.colors.Blue }, {0, 0, 255}
18 | assert.same {table.unpack drystal.colors['#0000Ff']}, {0, 0, 255}
19 |
20 | it 'throws an error if the color is unknown', ->
21 | assert.error -> drystal.colors.flava
22 |
23 | it 'can be made darker', ->
24 | c = drystal.colors.gray
25 | c2 = c\darker!
26 | assert.is_true c2.r < c.r
27 | assert.is_true c2.g < c.g
28 | assert.is_true c2.b < c.b
29 |
30 | it 'can be made lighter', ->
31 | c = drystal.colors.gray
32 | c2 = c\lighter!
33 | assert.is_true c2.r > c.r
34 | assert.is_true c2.g > c.g
35 | assert.is_true c2.b > c.b
36 |
37 | -- TODO: conversions, operators
38 |
39 |
--------------------------------------------------------------------------------
/tests/particle/blood.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local squish = assert(drystal.load_sound('squish2.wav'))
4 | tex = assert(drystal.load_surface('spritesheet.png'))
5 | local sys_blood = drystal.new_system(300, 600)
6 |
7 | sys_blood:set_sizes {
8 | [0]=50,
9 | [0.25] = 75,
10 | [0.5] = 55,
11 | [0.75] = 25,
12 | [1] = 15,
13 | }
14 | sys_blood:set_colors {
15 | [0]=drystal.colors.white,
16 | }
17 |
18 | sys_blood:set_lifetime(0.5)
19 | sys_blood:set_direction(-math.pi, math.pi)
20 | sys_blood:set_initial_velocity(50, 150)
21 | sys_blood:set_initial_acceleration(-100, 0)
22 | sys_blood:set_offset(0, 0, 0, 0)
23 | sys_blood:set_texture(tex, 128, 0)
24 |
25 | function drystal.init()
26 | drystal.resize(800, 600)
27 | end
28 |
29 | local time = 0
30 | function drystal.update(dt)
31 | time = time + dt
32 | sys_blood:update(dt)
33 | end
34 |
35 | function drystal.draw()
36 | drystal.set_color('black')
37 | drystal.draw_background()
38 |
39 | sys_blood:draw()
40 | end
41 |
42 | local last_splash = 0
43 | function drystal.mouse_press(x, y, b)
44 | if time - last_splash > 0.03 then
45 | sys_blood:emit(60)
46 | squish:play()
47 | end
48 | last_splash = time
49 | end
50 |
51 | function drystal.mouse_motion(x, y)
52 | sys_blood:set_position(x, y)
53 | end
54 |
55 | function drystal.key_press(k)
56 | if k == 'a' then
57 | drystal.stop()
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/external/zlibCMakeLists.cmake:
--------------------------------------------------------------------------------
1 | add_definitions(-DZ_HAVE_UNISTD_H -DHAVE_FSEEKO -DHAVE_SYS_TYPES_H -DHAVE_STDDEF_H -DHAVE_STDINT_H)
2 | configure_file( zlib/zconf.h.cmakein
3 | ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
4 | include_directories(${CMAKE_CURRENT_BINARY_DIR} zlib/)
5 |
6 | set(ZLIB_PUBLIC_HDRS
7 | ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
8 | zlib/zlib.h
9 | )
10 | set(ZLIB_PRIVATE_HDRS
11 | zlib/crc32.h
12 | zlib/deflate.h
13 | zlib/gzguts.h
14 | zlib/inffast.h
15 | zlib/inffixed.h
16 | zlib/inflate.h
17 | zlib/inftrees.h
18 | zlib/trees.h
19 | zlib/zutil.h
20 | )
21 | set(ZLIB_SRCS
22 | zlib/adler32.c
23 | zlib/compress.c
24 | zlib/crc32.c
25 | zlib/deflate.c
26 | zlib/gzclose.c
27 | zlib/gzlib.c
28 | zlib/gzread.c
29 | zlib/gzwrite.c
30 | zlib/inflate.c
31 | zlib/infback.c
32 | zlib/inftrees.c
33 | zlib/inffast.c
34 | zlib/trees.c
35 | zlib/uncompr.c
36 | zlib/zutil.c
37 | )
38 |
39 | # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
40 | file(READ zlib/zlib.h _zlib_h_contents)
41 | string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
42 | "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
43 |
44 | add_library(zlib STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
45 | set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
46 |
--------------------------------------------------------------------------------
/src/physics/shape_bind.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "lua_util.h"
20 |
21 | struct lua_State;
22 | struct b2FixtureDef;
23 |
24 | struct Shape {
25 | b2FixtureDef* fixtureDef;
26 | int ref;
27 | };
28 |
29 | DECLARE_PUSHPOP(Shape, shape)
30 |
31 | int mlua_new_shape(lua_State* L);
32 | int mlua_set_sensor_shape(lua_State* L);
33 | int mlua_gc_shape(lua_State* L);
34 |
35 | #define __SHAPE_GET_SET(value) \
36 | int mlua_set_##value##_shape(lua_State* L); \
37 | int mlua_get_##value##_shape(lua_State* L);
38 |
39 | __SHAPE_GET_SET(density)
40 | __SHAPE_GET_SET(restitution)
41 | __SHAPE_GET_SET(friction)
42 |
43 | #undef __SHAPE_GET_SET
44 |
45 |
--------------------------------------------------------------------------------
/src/physics/world_bind.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | struct lua_State;
20 |
21 | extern float pixels_per_meter;
22 |
23 | int mlua_init_physics(lua_State* L);
24 | int mlua_set_gravity(lua_State* L);
25 | int mlua_get_gravity(lua_State* L);
26 | int mlua_set_pixels_per_meter(lua_State* L);
27 | int mlua_get_pixels_per_meter(lua_State* L);
28 | int mlua_update_physics(lua_State* L);
29 | int mlua_on_collision(lua_State* L);
30 | int mlua_raycast(lua_State* L);
31 | int mlua_query(lua_State* L);
32 | int mlua_new_body(lua_State* L);
33 | int mlua_destroy_body(lua_State* L);
34 | int mlua_new_joint(lua_State* L);
35 | int mlua_destroy_joint(lua_State* L);
36 |
37 |
--------------------------------------------------------------------------------
/src/graphics/opengl_util.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifndef EMSCRIPTEN
20 | #include
21 | #include
22 | #else
23 | #include
24 | #include
25 | #endif
26 |
27 | #include
28 |
29 | #include "log.h"
30 |
31 | void check_opengl_oom(void);
32 |
33 | #ifndef NDEBUG
34 | const char* getGLError(GLenum error);
35 |
36 | #define GLDEBUG(x) \
37 | x; \
38 | { \
39 | GLenum e; \
40 | while((e = glGetError()) != GL_NO_ERROR) \
41 | { \
42 | log_debug("%s for call %s", getGLError(e), #x); \
43 | exit(1); \
44 | } \
45 | }
46 | #else
47 | #define GLDEBUG(x) \
48 | x;
49 | #endif
50 |
51 |
--------------------------------------------------------------------------------
/tests/audio/create.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local w = 800
4 | local h = 500
5 | local x = w/2
6 | local y = h/2
7 | local RATE = 44100
8 |
9 | local current = 0
10 |
11 | function play(time, ...)
12 | local freqs = {...}
13 | print("gen...")
14 | local new = drystal.load_sound(function(i)
15 | local s = 0
16 | for _, f in ipairs(freqs) do
17 | s = s + math.sin(i*f*math.pi / RATE)
18 | end
19 | s = s / #freqs
20 | return s
21 | end, time*RATE)
22 | new:play(0.15)
23 | print("play at", ...)
24 | end
25 |
26 | local cursor = 0
27 | function music_callback(data, len)
28 | local freq = 1800 * x / w
29 | local tone = freq * math.pi / RATE
30 | for i = 1, len do
31 | data[i] = math.sin(cursor * tone)
32 | cursor = cursor + 1
33 | end
34 | return len
35 | end
36 |
37 | local music
38 | function drystal.init()
39 | drystal.resize(w, h)
40 | drystal.set_music_volume(.2)
41 | music = drystal.load_music(music_callback, RATE)
42 | music:play()
43 | end
44 |
45 | function drystal.mouse_motion(xx, yy)
46 | x = xx
47 | y = yy
48 | music:set_pitch(3.5 * y / h + 0.5)
49 | end
50 |
51 | function drystal.key_press(k)
52 | if k == 'p' then
53 | music:stop()
54 | elseif k == 'o' then
55 | music:play()
56 | elseif k == 'a' then
57 | drystal.stop()
58 | elseif k == 's' then
59 | local f = {}
60 | for i = 1, 10 do
61 | f[i] = 1000 + i * 10.52
62 | end
63 | play(1, unpack(f))
64 | end
65 | end
66 |
67 |
--------------------------------------------------------------------------------
/src/audio/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "audio_bind.h"
19 | #include "music_bind.h"
20 | #include "sound_bind.h"
21 | #include "api.h"
22 |
23 | BEGIN_MODULE(audio)
24 | DECLARE_FUNCTION(load_music)
25 | DECLARE_FUNCTION(set_music_volume)
26 |
27 | DECLARE_FUNCTION(load_sound)
28 | DECLARE_FUNCTION(set_sound_volume)
29 |
30 | BEGIN_CLASS(sound)
31 | ADD_METHOD(sound, play)
32 | ADD_GC(free_sound)
33 | REGISTER_CLASS(sound, "Sound")
34 |
35 | BEGIN_CLASS(music)
36 | ADD_METHOD(music, play)
37 | ADD_METHOD(music, stop)
38 | ADD_METHOD(music, pause)
39 | ADD_METHOD(music, set_pitch)
40 | ADD_METHOD(music, set_volume)
41 | ADD_GC(free_music)
42 | REGISTER_CLASS(music, "Music")
43 | END_MODULE()
44 |
45 |
--------------------------------------------------------------------------------
/src/event/event.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #ifndef EMSCRIPTEN
22 | #include
23 | #else
24 | #include
25 | #endif
26 |
27 | enum Button {
28 | BUTTON_LEFT = SDL_BUTTON_LEFT,
29 | BUTTON_MIDDLE = SDL_BUTTON_MIDDLE,
30 | BUTTON_RIGHT = SDL_BUTTON_RIGHT,
31 | BUTTON_EXTRA_LEFT = SDL_BUTTON_X1,
32 | BUTTON_EXTRA_RIGHT = SDL_BUTTON_X2,
33 | // There is no more WHEEL_UP constant in SDL2 so we create ours
34 | WHEEL_UP = 4,
35 | WHEEL_DOWN = 5,
36 | };
37 | typedef enum Button Button;
38 |
39 | void event_update(void);
40 | void event_small_update(void);
41 | void event_destroy(void);
42 | int event_init(void);
43 |
44 | void event_set_relative_mode(bool relative);
45 |
46 |
--------------------------------------------------------------------------------
/src/audio/audio_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 |
21 | #include "audio_bind.h"
22 | #include "lua_util.h"
23 | #include "audio.h"
24 |
25 | int mlua_set_sound_volume(lua_State *L)
26 | {
27 | assert(L);
28 |
29 | float volume = luaL_checknumber(L, 1);
30 |
31 | assert_lua_error(L, volume >= 0 && volume <= 1, "set_sound_volume: must be >= 0 and <= 1");
32 |
33 | audio_set_sound_volume(volume);
34 | return 0;
35 | }
36 |
37 | int mlua_set_music_volume(lua_State *L)
38 | {
39 | assert(L);
40 |
41 | float volume = luaL_checknumber(L, 1);
42 |
43 | assert_lua_error(L, volume >= 0 && volume <= 1, "set_music_volume: must be >= 0 and <= 1");
44 |
45 | audio_set_music_volume(volume);
46 | return 0;
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/src/dlua.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #include
24 | #include
25 |
26 | void dlua_init(const char *filename);
27 | void dlua_add_arg(const char*);
28 |
29 | lua_State *dlua_get_lua_state(void);
30 |
31 | bool dlua_load_code(void);
32 | bool dlua_reload_code(void);
33 |
34 | void dlua_call_init(void);
35 | void dlua_call_update(float dt);
36 | void dlua_call_draw(void);
37 | void dlua_call_atexit(void);
38 | bool dlua_foreach(const char* type, bool(*callback)(void* data, const void* callback_arg), const void* callback_arg);
39 |
40 | void dlua_get_drystal_field(const char* name);
41 | bool dlua_get_function(const char* name);
42 | void dlua_free(void);
43 |
44 | #ifdef __cplusplus
45 | }
46 | #endif
47 |
48 |
--------------------------------------------------------------------------------
/src/particle/particle.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 |
21 | #include "particle.h"
22 | #include "system.h"
23 |
24 | void particle_update(Particle *p, System *s, float dt)
25 | {
26 | assert(p);
27 | assert(s);
28 |
29 | p->life -= dt;
30 |
31 | p->vel += p->accel * dt;
32 | p->x += p->vel * cosf(p->dir_angle) * dt;
33 | p->y += p->vel * sinf(p->dir_angle) * dt;
34 |
35 | float liferatio = 1 - p->life / p->lifetime;
36 | if (liferatio > s->sizes[p->size_state + 1].at && p->size_state < s->cur_size) {
37 | p->size_state += 1;
38 | }
39 | if (liferatio > s->colors[p->color_state + 1].at && p->color_state < s->cur_color) {
40 | p->color_state += 1;
41 | }
42 | if (liferatio > s->alphas[p->alpha_state + 1].at && p->alpha_state < s->cur_alpha) {
43 | p->alpha_state += 1;
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/graphics/opengl_util.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #ifndef EMSCRIPTEN
18 | #include
19 | #include
20 | #else
21 | #include
22 | #include
23 | #endif
24 |
25 | #include "opengl_util.h"
26 | #include "log.h"
27 |
28 | void check_opengl_oom(void)
29 | {
30 | GLenum e;
31 |
32 | e = glGetError();
33 | if (e == GL_OUT_OF_MEMORY)
34 | log_oom_and_exit();
35 | }
36 |
37 | #ifndef NDEBUG
38 | const char* getGLError(GLenum error)
39 | {
40 | #define casereturn(x) case x: return #x
41 | switch (error) {
42 | casereturn(GL_INVALID_ENUM);
43 | casereturn(GL_INVALID_VALUE);
44 | casereturn(GL_INVALID_OPERATION);
45 | casereturn(GL_INVALID_FRAMEBUFFER_OPERATION);
46 | casereturn(GL_OUT_OF_MEMORY);
47 | default:
48 | case GL_NO_ERROR:
49 | return "";
50 | }
51 | #undef casereturn
52 | }
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Emscripten-Generated Code
7 |
15 |
16 |
17 |
18 |
19 |
20 |
36 | {{{DRYSTAL_ADD_ARGUMENTS}}}
37 | {{{DRYSTAL_LOAD}}}
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/web/web_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 | #ifdef EMSCRIPTEN
21 | #include
22 | #endif
23 |
24 | #include "web.h"
25 | #include "web_bind.h"
26 | #include "log.h"
27 |
28 | int mlua_run_js(lua_State* L)
29 | {
30 | assert(L);
31 |
32 | #ifdef EMSCRIPTEN
33 | const char* script = luaL_checkstring(L, 1);
34 | char *ret = run_js(script);
35 | lua_pushstring(L, ret);
36 | free(ret);
37 | return 1;
38 | #else
39 | return luaL_error(L, "run_js isn't available in native build");
40 | #endif
41 | }
42 |
43 | int mlua_wget(lua_State *L)
44 | {
45 | assert(L);
46 |
47 | #ifdef EMSCRIPTEN
48 | const char *url = luaL_checkstring(L, 1);
49 | const char *filename = luaL_checkstring(L, 2);
50 | wget(url, filename);
51 | return 0;
52 | #else
53 | return luaL_error(L, "wget isn't available in native build");
54 | #endif
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/tests/graphics/filter.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local spritesheet = assert(drystal.fromjson(io.open('image.json'):read('*all')))
4 | local image = assert(drystal.load_surface(spritesheet.meta.image))
5 |
6 | drystal.resize(600, 400)
7 | image:draw_from()
8 |
9 | local spritesrc = spritesheet.frames['character.png'].frame
10 | local sprite = drystal.new_sprite(spritesrc, 300, 180)
11 | sprite.angle = math.pi/3
12 | local sprite2 = drystal.new_sprite(spritesrc, 220, 180, spritesrc.w*2, spritesrc.h*2)
13 | sprite2.angle = math.pi/2
14 | local sprite3 = drystal.new_sprite(spritesrc, 350, 180, spritesrc.w*2, spritesrc.h*2)
15 | sprite3.angle = math.pi/2
16 |
17 | function drystal.draw()
18 | drystal.draw_background()
19 |
20 | sprite:draw()
21 | sprite2:draw()
22 | sprite3:draw()
23 | local t = {
24 | angle=0,
25 | wfactor=1,
26 | hfactor=1,
27 | }
28 | drystal.draw_sprite({x=spritesrc.x, y=spritesrc.y, w=spritesrc.w, h=spritesrc.h}, 300, 220, t)
29 | end
30 |
31 | function drystal.key_press(k)
32 | if k == '[1]' then
33 | image:set_filter(drystal.filters.nearest)
34 | elseif k == '[2]' then
35 | image:set_filter(drystal.filters.linear)
36 | elseif k == '[3]' then
37 | image:set_filter(drystal.filters.bilinear)
38 | elseif k == '[4]' then
39 | image:set_filter(drystal.filters.trilinear)
40 | elseif k == 'a' then
41 | drystal.stop()
42 | end
43 | end
44 |
45 | function drystal.mouse_press(x, y, b)
46 | if b == drystal.WHEEL_UP then
47 | drystal.camera.zoom = drystal.camera.zoom * 1.2
48 | elseif b == drystal.WHEEL_DOWN then
49 | drystal.camera.zoom = drystal.camera.zoom / 1.2
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/spec/tools.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | say = require 'say'
4 | assert = require 'luassert'
5 | util = require 'luassert.util'
6 |
7 | fmt_color = (arg) ->
8 | if type(arg) == 'table' and arg.color
9 | if arg.name
10 | if arg[4]
11 | ('{%q, %d}')\format(arg.name, arg[4])
12 | else
13 | ('%q')\format(arg.name)
14 | elseif #arg == 3
15 | ('{%d, %d, %d}')\format table.unpack arg
16 | elseif #arg == 4
17 | ('{%d, %d, %d, %d}')\format table.unpack arg
18 |
19 | is_color = (state, args) ->
20 | surface, x, y, color, alpha = table.unpack args
21 | alpha = alpha or 255
22 |
23 | assert(#args >= 4, say("assertion.internal.argtolittle", { "is_color", 4, #args }))
24 | assert(type(surface) == 'userdata' and surface.__type == 'surface', say("assertion.internal.badargtype", { 1, "is_color", "surface", surface or 'nil' }))
25 |
26 | c = color
27 | if type(color) ~= 'table'
28 | c = { table.unpack drystal.colors[color] }
29 | c.name = color
30 | else
31 | c = { table.unpack c }
32 | c[4] = alpha
33 | c.color = true
34 |
35 | old_on = drystal.current_draw_on == surface
36 | other = surface == drystal.screen and drystal.new_surface(x, y) or drystal.screen
37 | other\draw_on! if old_on
38 | r, g, b, a = surface\get_pixel x, y
39 | surface\draw_on! if old_on
40 |
41 | args[1] = c
42 | args[2] = {r, g, b, a, color: true}
43 |
44 | r == c[1] and g == c[2] and b == c[3] and a == alpha
45 |
46 | say\set_namespace "en"
47 | say\set "assertion.color.positive", "Expected surface to be %s, was %s"
48 |
49 | assert\register "assertion", "color", is_color, "assertion.color.positive"
50 | assert\add_formatter fmt_color
51 |
52 |
--------------------------------------------------------------------------------
/src/font/parser.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | typedef struct TextState TextState;
23 |
24 | struct TextState {
25 | float size;
26 | float italic;
27 |
28 | int r;
29 | int g;
30 | int b;
31 | int alpha;
32 |
33 | bool outlined;
34 | bool shadow;
35 |
36 | int outr;
37 | int outg;
38 | int outb;
39 |
40 | float shadow_x;
41 | float shadow_y;
42 | };
43 |
44 | static inline void textstate_reset(TextState *t)
45 | {
46 | assert(t);
47 |
48 | t->size = 1.0;
49 | t->italic = 0.0;
50 | t->r = 0;
51 | t->g = 0;
52 | t->b = 0;
53 | t->alpha = 255;
54 | t->outlined = false;
55 | t->outr = 0;
56 | t->outg = 0;
57 | t->outb = 0;
58 | t->shadow = false;
59 | t->shadow_x = 0;
60 | t->shadow_y = 0;
61 | }
62 |
63 | TextState* push_parser(void);
64 | bool parse(TextState **state, const char **text, const char **end);
65 | void pop_parser(void);
66 |
67 |
--------------------------------------------------------------------------------
/src/font/font.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | typedef struct Font Font;
22 |
23 | #include "graphics/surface.h"
24 |
25 | enum Alignment {
26 | ALIGN_LEFT = 1,
27 | ALIGN_CENTER = 2,
28 | ALIGN_RIGHT = 3
29 | };
30 | typedef enum Alignment Alignment;
31 |
32 | struct Font {
33 | Surface* surface;
34 | float font_size;
35 | int first_char;
36 | int num_chars;
37 | int ref;
38 | stbtt_bakedchar* char_data;
39 | };
40 |
41 | void font_free(Font *font);
42 | void font_draw(const Font *f, const char* text, float x, float y, Alignment align);
43 | void font_draw_plain(const Font *f, const char* text, float x, float y);
44 | void font_get_textsize(const Font *f, const char* text, float* w, float* h, int nblines);
45 | void font_get_textsize_plain(const Font *f, const char* text, float* w, float* h);
46 |
47 | Font* font_load(const char* filename, float size, int first_char, int num_chars);
48 |
49 |
--------------------------------------------------------------------------------
/tests/graphics/fx.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | drystal.resize(800, 600)
4 |
5 | local gray = false
6 | local multiply = false
7 | local distortion = false
8 | local blur = false
9 | local vignette = false
10 | local pixelate = false
11 |
12 | local time = 0
13 | function drystal.update(dt)
14 | time = time + dt
15 | end
16 |
17 | function drystal.draw(dt)
18 | drystal.set_alpha(255)
19 | drystal.set_color(255, 255, 255)
20 | drystal.draw_background()
21 |
22 | drystal.set_color(255, 0, 0)
23 | drystal.draw_rect(50, 50, 300, 200)
24 |
25 | drystal.set_color(0, 0, 100)
26 | drystal.set_alpha(200)
27 | drystal.draw_rect(10, 10, 100, 100)
28 |
29 | drystal.set_color(0, 255, 100)
30 | drystal.set_alpha(255)
31 | drystal.draw_rect(100, 100, 100, 100)
32 |
33 | if vignette then
34 | drystal.postfx('vignette', .7, (math.sin(time)/2 + 0.5) * .2 + .2)
35 | end
36 | if multiply then
37 | drystal.postfx('multiply', 1.9, .8, .7)
38 | end
39 | if gray then
40 | drystal.postfx('gray', math.sin(time)/2 + .5)
41 | end
42 | if distortion then
43 | drystal.postfx('distortion', time, 20, 0)
44 | end
45 | if pixelate then
46 | local s = (math.sin(time / 10) / 2 + .5) * 16
47 | drystal.postfx('pixelate', s, s)
48 | end
49 | if blur then
50 | drystal.postfx('blur', 90)
51 | end
52 | end
53 |
54 | function drystal.key_press(k)
55 | if k == 'a' then
56 | drystal.stop()
57 | elseif k == 'g' then
58 | gray = not gray
59 | elseif k == 'm' then
60 | multiply = not multiply
61 | elseif k == 'd' then
62 | distortion = not distortion
63 | elseif k == 'b' then
64 | blur = not blur
65 | elseif k == 'v' then
66 | vignette = not vignette
67 | elseif k == 'p' then
68 | pixelate = not pixelate
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | NATIVE_CMAKE_BUILD_TYPE ?= Debug
2 | WEB_CMAKE_BUILD_TYPE ?= Release
3 | BUILD_DIRS = $(dir $(wildcard ./build-*/))
4 | SUBDIRSCLEAN = $(addsuffix .clean,$(BUILD_DIRS))
5 | EMSCRIPTEN = /usr/lib/emscripten/
6 |
7 | CMAKE_FLAGS ?=
8 |
9 | # from the Makefile of neovim
10 | BUILD_TYPE ?= $(shell (type ninja > /dev/null 2>&1 && echo "Ninja") || \
11 | echo "Unix Makefiles")
12 | ifeq (,$(BUILD_TOOL))
13 | ifeq (Ninja,$(BUILD_TYPE))
14 | ifneq ($(shell cmake --help 2>/dev/null | grep Ninja),)
15 | BUILD_TOOL := ninja
16 | else
17 | # User's version of CMake doesn't support Ninja
18 | BUILD_TOOL = $(MAKE)
19 | BUILD_TYPE := Unix Makefiles
20 | endif
21 | else
22 | BUILD_TOOL = $(MAKE)
23 | endif
24 | endif
25 |
26 | all: native
27 |
28 | native:
29 | mkdir -p build-native-$(NATIVE_CMAKE_BUILD_TYPE)
30 | cd build-native-$(NATIVE_CMAKE_BUILD_TYPE) && cmake .. -G '$(BUILD_TYPE)' -DCMAKE_BUILD_TYPE=$(NATIVE_CMAKE_BUILD_TYPE) $(CMAKE_FLAGS)
31 | +$(BUILD_TOOL) -C build-native-$(NATIVE_CMAKE_BUILD_TYPE)
32 |
33 | install-native: native
34 | +$(BUILD_TOOL) -C build-native-$(NATIVE_CMAKE_BUILD_TYPE) install
35 |
36 | install: install-native
37 |
38 | web:
39 | mkdir -p build-web-$(WEB_CMAKE_BUILD_TYPE)
40 | cd build-web-$(WEB_CMAKE_BUILD_TYPE) && cmake .. -G '$(BUILD_TYPE)' -DCMAKE_BUILD_TYPE=$(WEB_CMAKE_BUILD_TYPE) -DCMAKE_TOOLCHAIN_FILE=$(EMSCRIPTEN)/cmake/Modules/Platform/Emscripten.cmake $(CMAKE_FLAGS)
41 | +$(BUILD_TOOL) -C build-web-$(WEB_CMAKE_BUILD_TYPE)
42 |
43 | clean: $(SUBDIRSCLEAN)
44 |
45 | $(SUBDIRSCLEAN):
46 | $(BUILD_TOOL) -C $(basename $@) clean || true
47 |
48 | distclean: clean
49 | rm -rf $(BUILD_DIRS)
50 |
51 | .PHONY: clean distclean $(SUBDIRSCLEAN) install native web install-native
52 |
--------------------------------------------------------------------------------
/tests/graphics/shaders.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local shader
4 |
5 | local vert = [[
6 | #ifdef GL_ES
7 | precision highp float;
8 | #endif
9 |
10 | attribute vec2 position;
11 | attribute vec4 color;
12 | attribute vec2 texCoord;
13 | attribute float pointSize;
14 |
15 | varying vec4 fColor;
16 | varying vec2 fTexCoord;
17 |
18 | uniform vec2 destinationSize;
19 | uniform vec2 sourceSize;
20 |
21 | uniform float mx;
22 | uniform float my;
23 |
24 | void main()
25 | {
26 | gl_PointSize = pointSize;
27 | vec2 pos = 2. * position / destinationSize - 1.;
28 | gl_Position = vec4(pos, mx*my+pos.x*pos.y, 1.0);
29 | vec3 offcolor = vec3(pos, pos.x + pos.y) - vec3(mx, my, mx*my);
30 | fColor = color - vec4(offcolor, 0.);
31 | fTexCoord = texCoord / sourceSize;
32 | }
33 | ]]
34 | local fragcolor = [[
35 | ]]
36 | local fragtex = [[
37 | ]]
38 |
39 | local mx, my
40 | local width = 1024
41 | local height = 768
42 |
43 | function drystal.init()
44 | drystal.resize(width, height)
45 | shader = assert(drystal.new_shader(vert, fragcolor, fragtex))
46 | end
47 |
48 | function drystal.draw()
49 | drystal.set_alpha(255)
50 | drystal.set_color(0, 0, 0)
51 | drystal.draw_background()
52 |
53 | shader:use()
54 | drystal.set_color(255, 255, 255)
55 | drystal.draw_rect(0, 0, width, height)
56 | for ii = 0, 5 do
57 | local i = ii / 10
58 | drystal.draw_rect(width*i, height*i, width*(1-i*2), height*(1-i*2))
59 | end
60 |
61 | drystal.use_default_shader()
62 | end
63 |
64 | function drystal.key_press(key)
65 | if key == 'a' then
66 | drystal.stop()
67 | end
68 | end
69 |
70 | function drystal.mouse_motion(x, y)
71 | mx, my = x, y
72 | shader:feed('mx', (mx/width) * 2 - 1)
73 | shader:feed('my', (1-my/height) * 2 - 1)
74 | end
75 |
76 |
--------------------------------------------------------------------------------
/src/web/web.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #ifdef EMSCRIPTEN
18 | #include
19 | #include
20 | #include
21 |
22 | #include "web.h"
23 | #include "dlua.h"
24 | #include "lua_util.h"
25 | #include "util.h"
26 |
27 | char *run_js(const char* script)
28 | {
29 | char *ret = emscripten_run_script_string(script);
30 | return xstrdup(ret);
31 | }
32 |
33 | static void onsuccess(const char* filename)
34 | {
35 | assert(filename);
36 |
37 | if (dlua_get_function("on_wget_success")) {
38 | lua_State* L = dlua_get_lua_state();
39 | lua_pushstring(L, filename);
40 | call_lua_function(L, 1, 0);
41 | }
42 | }
43 |
44 | static void onerror(const char* filename)
45 | {
46 | assert(filename);
47 |
48 | if (dlua_get_function("on_wget_error")) {
49 | lua_State* L = dlua_get_lua_state();
50 | lua_pushstring(L, filename);
51 | call_lua_function(L, 1, 0);
52 | }
53 | }
54 |
55 | void wget(const char* url, const char* filename)
56 | {
57 | emscripten_async_wget(url, filename, onsuccess, onerror);
58 | }
59 | #endif
60 |
61 |
--------------------------------------------------------------------------------
/cmake/BuildCoverage.cmake:
--------------------------------------------------------------------------------
1 | if(BUILD_ENABLE_COVERAGE)
2 | find_program(COVERAGE_GCOV gcov)
3 | find_program(COVERAGE_LCOV lcov)
4 | find_program(COVERAGE_GENHTML genhtml)
5 | if (NOT COVERAGE_GCOV)
6 | message(FATAL_ERROR "Unable to find gcov")
7 | endif()
8 | if (NOT COVERAGE_LCOV)
9 | message(FATAL_ERROR "Unable to find lcov")
10 | endif()
11 | if (NOT COVERAGE_GENHTML)
12 | message(FATAL_ERROR "Unable to find genhtml")
13 | endif()
14 |
15 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
16 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
17 | set(CMAKE_LD_FLAGS_DEBUG "${CMAKE_LD_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
18 |
19 | add_custom_target(coverage-reset DEPENDS ${DRYSTAL_OUT})
20 | add_custom_command(TARGET coverage-reset
21 | COMMAND mkdir -p coverage
22 | COMMAND ${COVERAGE_LCOV} --directory . --zerocounters
23 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
24 | )
25 | add_custom_target(coverage-report DEPENDS ${DRYSTAL_OUT})
26 | add_custom_command(TARGET coverage-report
27 | COMMAND ${COVERAGE_LCOV} --directory . --capture --output-file ./coverage/drystal.lcov
28 | COMMAND ${COVERAGE_LCOV} --remove ./coverage/drystal.lcov --output-file ./coverage/drystal_clean.lcov '/usr/*' 'box2d/*'
29 | COMMAND ${COVERAGE_GENHTML} -t "drystal coverage" -p "${CMAKE_SOURCE_DIR}" -o ./coverage ./coverage/drystal_clean.lcov
30 | COMMAND echo "Open ${CMAKE_BINARY_DIR}/coverage/index.html to view the coverage analysis results."
31 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
32 | )
33 | target_link_libraries(${DRYSTAL_OUT} gcov)
34 | endif(BUILD_ENABLE_COVERAGE)
35 |
36 |
--------------------------------------------------------------------------------
/spec/camera_spec.moon:
--------------------------------------------------------------------------------
1 | drystal = require 'drystal'
2 |
3 | describe 'camera', ->
4 | camera = drystal.camera
5 | screen = drystal.screen
6 |
7 | before_each ->
8 | pcall ->
9 | while true
10 | camera.pop!
11 | camera.reset!
12 |
13 | it 'initializes the fields', ->
14 | assert.equals 0, camera.x
15 | assert.equals 0, camera.y
16 | assert.equals 0, camera.angle
17 | assert.equals 1, camera.zoom
18 |
19 | it 'resets properly', ->
20 | camera.x = 10
21 | assert.not_equals 0, camera.x
22 | camera.reset!
23 | assert.equals 0, camera.x
24 |
25 | it 'can move', ->
26 | camera.x = 10
27 | camera.y = 15
28 | assert.equals 10, camera.x
29 | assert.equals 15, camera.y
30 |
31 | it 'can rotate', ->
32 | a = math.pi
33 | camera.angle = a
34 | assert.equals a, camera.angle
35 |
36 | it 'can zoom', ->
37 | z = 1.1
38 | camera.zoom = z
39 | assert.equals z, camera.zoom
40 |
41 | it 'throws an error when the stack is empty', ->
42 | assert.error -> camera.pop!
43 |
44 | it 'throws an error when the stack is full', ->
45 | assert.error ->
46 | while true
47 | camera.push!
48 |
49 | it 'copies values when pushing', ->
50 | camera.x = 10
51 | assert.equals 10, camera.x
52 | camera.push!
53 | assert.equals 10, camera.x
54 |
55 | it 'restores values when popping', ->
56 | camera.x = 5
57 | camera.push!
58 | camera.x = 10
59 | camera.pop!
60 | assert.equals 5, camera.x
61 |
62 | describe 'screen2scene', ->
63 |
64 | it 'is correct when simple', ->
65 | x, y = drystal.screen2scene 0, 0
66 | assert.equals 0, x
67 | assert.equals 0, y
68 |
69 | x, y = drystal.screen2scene screen.w, screen.h
70 | assert.equals screen.w, x
71 | assert.equals screen.h, y
72 |
73 | -- TODO: moved, rotated, zoomed
74 |
75 |
--------------------------------------------------------------------------------
/tests/audio/play.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local piou = assert(drystal.load_sound("test.wav"))
4 |
5 | function drystal.init()
6 | print("press p to play a wav sound")
7 | print("press i to play a ogg music")
8 | print("press o to pause a ogg music")
9 | print("press u to stop a ogg music")
10 | print("press b to toggle looping")
11 | print("press l to lower the volume of every music")
12 | print("press z to lower the volume of every sound")
13 | print("press t to set the music volume to 0.5")
14 | print("press - to decrease the pitch")
15 | print("press + to increase the pitch")
16 | drystal.resize(40, 40)
17 | end
18 |
19 | local music = assert(drystal.load_music("test.ogg"))
20 |
21 | local pitch = 1.0
22 | local sound_volume = 1.0
23 | local music_volume = 1.0
24 | local loop = false
25 | function drystal.key_press(key)
26 | if key == 'a' then
27 | drystal.stop()
28 | elseif key == 'p' then
29 | piou:play(1, 0, 0, pitch)
30 | print('play sound')
31 | elseif key == '[+]' then
32 | pitch = pitch + 0.10
33 | music:set_pitch(pitch)
34 | print('pitch: ', pitch)
35 | elseif key == '[-]' then
36 | pitch = pitch - 0.10
37 | music:set_pitch(pitch)
38 | print('pitch: ', pitch)
39 | elseif key == 't' then
40 | music:set_volume(0.5)
41 | elseif key == 'l' then
42 | music_volume = music_volume - 0.3
43 | drystal.set_music_volume(music_volume)
44 | elseif key == 'z' then
45 | sound_volume = sound_volume - 0.3
46 | drystal.set_sound_volume(sound_volume)
47 | elseif key == 'i' then
48 | music:play(loop, function()
49 | print "music ended"
50 | end)
51 | print('play music')
52 | elseif key == 'o' then
53 | music:pause()
54 | print('pause music')
55 | elseif key == 'u' then
56 | music:stop()
57 | print('stop music')
58 | elseif key == 'b' then
59 | loop = not loop
60 | print('loop:', loop)
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/src/graphics/display_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "surface.h"
23 |
24 | DECLARE_PUSHPOP(Surface, surface)
25 |
26 | int mlua_set_color(lua_State* L);
27 | int mlua_set_alpha(lua_State* L);
28 | int mlua_set_title(lua_State* L);
29 | int mlua_set_blend_mode(lua_State* L);
30 |
31 | int mlua_show_cursor(lua_State* L);
32 | int mlua_resize(lua_State* L);
33 | int mlua_set_fullscreen(lua_State* L);
34 | int mlua_screen2scene(lua_State* L);
35 |
36 | int mlua_surface_class_index(lua_State* L);
37 | int mlua_load_surface(lua_State* L);
38 | int mlua_new_surface(lua_State* L);
39 | int mlua_free_surface(lua_State* L);
40 | int mlua_draw_on_surface(lua_State* L);
41 | int mlua_draw_from_surface(lua_State* L);
42 | int mlua_set_filter_surface(lua_State* L);
43 | int mlua_get_pixel_surface(lua_State* L);
44 |
45 | int mlua_draw_background(lua_State *L);
46 | int mlua_draw_point(lua_State* L);
47 | int mlua_draw_point_tex(lua_State* L);
48 | int mlua_draw_line(lua_State* L);
49 | int mlua_draw_triangle(lua_State* L);
50 | int mlua_draw_surface(lua_State* L);
51 | int mlua_draw_quad(lua_State* L);
52 |
53 |
--------------------------------------------------------------------------------
/src/particle/api.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include "module.h"
18 | #include "system_bind.h"
19 | #include "api.h"
20 |
21 | BEGIN_MODULE(particle)
22 | DECLARE_FUNCTION(new_system)
23 |
24 | BEGIN_CLASS(system)
25 | ADD_METHOD(system, emit)
26 | ADD_METHOD(system, start)
27 | ADD_METHOD(system, stop)
28 | ADD_METHOD(system, reset)
29 |
30 | ADD_METHOD(system, draw)
31 | ADD_METHOD(system, update)
32 | ADD_METHOD(system, add_size)
33 | ADD_METHOD(system, add_color)
34 | ADD_METHOD(system, add_alpha)
35 | ADD_METHOD(system, clear_sizes)
36 | ADD_METHOD(system, clear_colors)
37 | ADD_METHOD(system, clear_alphas)
38 | ADD_METHOD(system, set_texture)
39 |
40 | ADD_GETSET(system, position)
41 | ADD_GETSET(system, offset)
42 | ADD_GETSET(system, emission_rate)
43 |
44 | #define ADD_MINMAX(name) \
45 | ADD_GETSET(system, min_##name) \
46 | ADD_GETSET(system, max_##name)
47 | ADD_MINMAX(lifetime)
48 | ADD_MINMAX(direction)
49 | ADD_MINMAX(initial_acceleration)
50 | ADD_MINMAX(initial_velocity)
51 | #undef ADD_GETSET
52 |
53 | ADD_METHOD(system, clone)
54 | ADD_GC(free_system)
55 | REGISTER_CLASS(system, "System")
56 | END_MODULE()
57 |
58 |
--------------------------------------------------------------------------------
/src/audio/music.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | typedef struct Music Music;
23 | typedef struct MusicCallback MusicCallback;
24 |
25 | #include "audio.h"
26 |
27 | #define STREAM_NUM_BUFFERS 3
28 |
29 | struct MusicCallback {
30 | unsigned int (*feed_buffer)(MusicCallback *mc, unsigned short *buffer, unsigned int len);
31 | void (*rewind)(MusicCallback *mc);
32 | void (*free)(MusicCallback *mc);
33 | };
34 |
35 | struct Music {
36 | Source* source;
37 | ALuint alBuffers[STREAM_NUM_BUFFERS];
38 | bool ended;
39 | bool loop;
40 | MusicCallback* callback;
41 | ALenum format;
42 | int samplesrate;
43 | unsigned int buffersize;
44 | int ref;
45 | int onend_clb;
46 | float pitch;
47 | float volume;
48 | };
49 |
50 | void music_play(Music *m, bool loop, int onend_clb);
51 | void music_update(Music *m);
52 | void music_stop(Music *m);
53 | void music_pause(Music *m);
54 | void music_free(Music *m);
55 | void music_set_pitch(Music *m, float pitch);
56 | void music_set_volume(Music *m, float volume);
57 |
58 | Music *music_load(MusicCallback* callback, int samplesrate, int num_channels);
59 | Music *music_load_from_file(const char* filename);
60 |
61 |
--------------------------------------------------------------------------------
/src/audio/audio.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | typedef struct Source Source;
23 | typedef enum SourceType {
24 | SOURCE_MUSIC,
25 | SOURCE_SOUND
26 | } SourceType;
27 |
28 | #include "sound.h"
29 | #include "music.h"
30 | #include "log.h"
31 |
32 | #define DEFAULT_SAMPLES_RATE 44100
33 |
34 | struct Source {
35 | ALuint alSource;
36 | bool used;
37 | bool paused;
38 | union {
39 | Sound* currentSound;
40 | Music* currentMusic;
41 | };
42 | SourceType type;
43 | float desiredVolume;
44 | };
45 |
46 | #ifndef NDEBUG
47 | #define audio_check_error() do { \
48 | ALint error; \
49 | while ((error = alGetError()) != AL_NO_ERROR) { \
50 | log_debug("[ALerr] %s", alGetString(error)); \
51 | } \
52 | } while (false)
53 | #else
54 | #define audio_check_error()
55 | #endif
56 |
57 | bool audio_init_if_needed(void);
58 | void audio_update(float dt);
59 | void audio_free(void);
60 |
61 | void audio_set_music_volume(float volume);
62 | void audio_set_sound_volume(float volume);
63 | float audio_get_music_volume(void);
64 | float audio_get_sound_volume(void);
65 | bool audio_try_free_sound(Sound* sound);
66 |
67 | Source* audio_get_free_source(void);
68 |
69 |
--------------------------------------------------------------------------------
/src/storage/storage_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #ifndef EMSCRIPTEN
20 | #include
21 | #endif
22 |
23 | #include "lua_util.h"
24 | #include "storage_bind.h"
25 | #include "storage.h"
26 |
27 | extern int json_encode(lua_State* L);
28 | extern int json_decode(lua_State* L);
29 |
30 | int mlua_store(lua_State* L)
31 | {
32 | assert(L);
33 |
34 | const char* key = luaL_checkstring(L, 1);
35 |
36 | lua_pushcfunction(L, json_encode);
37 | lua_pushvalue(L, 2);
38 |
39 | call_lua_function(L, 1, 1); // table in param, returns json
40 |
41 | const char* value = luaL_checkstring(L, -1);
42 |
43 | storage_store(key, value);
44 | return 0;
45 | }
46 |
47 | int mlua_fetch(lua_State* L)
48 | {
49 | assert(L);
50 |
51 | const char* key = luaL_checkstring(L, 1);
52 | char* value = storage_fetch(key);
53 |
54 | if (!value || !value[0]) {
55 | #ifndef EMSCRIPTEN
56 | free(value);
57 | #endif
58 | lua_pushnil(L);
59 | return 1;
60 | }
61 |
62 | lua_pushcfunction(L, json_decode);
63 | lua_pushstring(L, value);
64 | call_lua_function(L, 1, 1);
65 |
66 | #ifndef EMSCRIPTEN
67 | free(value);
68 | #endif
69 | // table is returned by json_decode
70 | return 1;
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/tests/graphics/precise.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local w, h = 32, 32
4 | local surface
5 | local image
6 | local image_sprite = {x=16, y=16, w=32, h=32}
7 | function drystal.init()
8 | drystal.resize(800, 600)
9 | drystal.camera.reset()
10 |
11 | image = assert(drystal.load_surface('precise.png'))
12 | image:set_filter(drystal.filters.nearest)
13 |
14 | surface = drystal.new_surface(w, h)
15 | surface:set_filter(drystal.filters.nearest)
16 | surface:draw_on()
17 | drystal.set_color(255, 0, 0)
18 | drystal.draw_rect(0, 0, w, h)
19 |
20 | local s2 = assert(drystal.new_surface(w-2, h-2))
21 | s2:set_filter(drystal.filters.nearest)
22 | s2:draw_on()
23 | drystal.set_color(0, 255, 0)
24 | drystal.draw_rect(1, 1, w-2, h-2)
25 |
26 | s2:draw_from()
27 | surface:draw_on()
28 | drystal.set_color(255, 255, 255)
29 | drystal.draw_sprite({x=0, y=0, w=w-2, h=h-2}, 1, 1)
30 |
31 | drystal.screen:draw_on()
32 | end
33 |
34 | function drystal.draw()
35 | drystal.set_alpha(255)
36 | drystal.set_color(255, 255, 255)
37 | drystal.draw_background()
38 |
39 | drystal.set_color(0, 0, 0)
40 | drystal.draw_rect(300, 300, 50, 50)
41 | drystal.draw_rect(200, 200, 1, 1)
42 | drystal.draw_rect(204, 204, 2, 2)
43 |
44 | drystal.draw_rect(150-w, 150, w, h)
45 |
46 | surface:draw_from()
47 | drystal.set_color(255, 255, 255)
48 | drystal.draw_sprite({x=0, y=0, w=w, h=h}, 150, 150)
49 |
50 | image:draw_from()
51 | drystal.set_color(255, 255, 255)
52 | drystal.draw_sprite(image_sprite, 150+w, 150)
53 | end
54 |
55 | function drystal.mouse_motion(x, y)
56 | drystal.camera.x = 400 - x
57 | drystal.camera.y = 300 - y
58 | end
59 | function drystal.mouse_press(x, y, b)
60 | if b == drystal.buttons.wheel_up then
61 | drystal.camera.zoom = drystal.camera.zoom * 1.3
62 | elseif b == drystal.buttons.wheel_down then
63 | drystal.camera.zoom = drystal.camera.zoom / 1.3
64 | end
65 | end
66 |
67 | function drystal.key_press(k)
68 | if k == 'a' then
69 | drystal.stop()
70 | end
71 | end
72 |
73 |
--------------------------------------------------------------------------------
/src/physics/body_bind.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "lua_util.h"
20 |
21 | struct lua_State;
22 | class b2Body;
23 |
24 | struct Body {
25 | b2Body* body;
26 | Body* nextdestroy;
27 | bool getting_destroyed;
28 | int ref;
29 | };
30 |
31 | DECLARE_PUSHPOP(Body, body)
32 | Body* pop_body_secure(lua_State* L, int index);
33 |
34 | int mlua_get_center_position_body(lua_State* L);
35 | int mlua_set_active_body(lua_State* L);
36 | int mlua_set_bullet_body(lua_State* L);
37 | int mlua_get_mass_body(lua_State* L);
38 | int mlua_set_mass_center_body(lua_State* L);
39 | int mlua_apply_force_body(lua_State* L);
40 | int mlua_apply_linear_impulse_body(lua_State* L);
41 | int mlua_apply_angular_impulse_body(lua_State* L);
42 | int mlua_apply_torque_body(lua_State* L);
43 | int mlua_dump_body(lua_State* L);
44 | int mlua_free_body(lua_State* L);
45 |
46 | #define __BODY_GET_SET(value) \
47 | int mlua_set_##value##_body(lua_State* L); \
48 | int mlua_get_##value##_body(lua_State* L);
49 |
50 | __BODY_GET_SET(position)
51 | __BODY_GET_SET(linear_velocity)
52 | __BODY_GET_SET(angle)
53 | __BODY_GET_SET(angular_velocity)
54 | __BODY_GET_SET(linear_damping)
55 | __BODY_GET_SET(angular_damping)
56 | __BODY_GET_SET(linearvelocity)
57 | __BODY_GET_SET(fixed_rotation)
58 |
59 | #undef __BODY_GET_SET
60 |
61 |
--------------------------------------------------------------------------------
/src/lua_util.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "engine.h"
24 | #include "lua_util.h"
25 | #include "util.h"
26 | #include "livecoding.h"
27 | #include "log.h"
28 |
29 | log_category("lua");
30 |
31 | int traceback(lua_State *L)
32 | {
33 | lua_getglobal(L, "debug");
34 | lua_getfield(L, -1, "newtraceback");
35 | lua_insert(L, 1);
36 | lua_pop(L, 1);
37 |
38 | lua_pushinteger(L, 1);
39 | lua_pushboolean(L, stderr_use_colors());
40 |
41 | lua_call(L, lua_gettop(L) - 1, 1);
42 | fprintf(stderr, "%s\n", lua_tostring(L, -1));
43 | return 0;
44 | }
45 |
46 | void call_lua_function(lua_State *L, int num_args, int num_ret)
47 | {
48 | assert(L);
49 | assert(num_args >= 0);
50 | assert(num_ret >= 0);
51 |
52 | #ifdef EMSCRIPTEN
53 | lua_call(L, num_args, num_ret);
54 | #else
55 | /* from lua/src/lua.c */
56 | int base = lua_gettop(L) - num_args;
57 | lua_pushcfunction(L, traceback);
58 | lua_insert(L, base);
59 | if (lua_pcall(L, num_args, num_ret, base)) {
60 | #ifdef BUILD_LIVECODING
61 | if (livecoding_is_running()) {
62 | engine_wait_next_reload();
63 | lua_pop(L, 1);
64 | } else
65 | #endif
66 | {
67 | engine_free();
68 | exit(EXIT_FAILURE);
69 | }
70 | }
71 | lua_remove(L, base);
72 | #endif
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/external/libpngCMakeLists.cmake:
--------------------------------------------------------------------------------
1 | set(PNGLIB_MAJOR 1)
2 | set(PNGLIB_MINOR 6)
3 | set(PNGLIB_RELEASE 17)
4 | set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
5 | set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
6 |
7 | set(ZLIB_LIBRARY zlib)
8 | set(ZLIB_INCLUDE_DIR ../zlib/)
9 |
10 | # SET LIBNAME
11 | set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
12 | set(PNG_LIBRARY ${PNG_LIB_NAME} PARENT_SCOPE)
13 |
14 | # Use the prebuilt pnglibconf.h file from the scripts folder
15 | # TODO: fix this by building with awk; without this no cmake build can be
16 | # configured directly (to do so indirectly use your local awk to build a
17 | # pnglibconf.h in the build directory.)
18 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng/scripts/pnglibconf.h.prebuilt
19 | ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
20 | include_directories(${CMAKE_CURRENT_BINARY_DIR})
21 |
22 | set(libpng_public_hdrs
23 | libpng/png.h
24 | libpng/pngconf.h
25 | ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h
26 | )
27 | set(libpng_sources
28 | ${libpng_public_hdrs}
29 | libpng/pngdebug.h
30 | libpng/pnginfo.h
31 | libpng/pngpriv.h
32 | libpng/pngstruct.h
33 | libpng/png.c
34 | libpng/pngerror.c
35 | libpng/pngget.c
36 | libpng/pngmem.c
37 | libpng/pngpread.c
38 | libpng/pngread.c
39 | libpng/pngrio.c
40 | libpng/pngrtran.c
41 | libpng/pngrutil.c
42 | libpng/pngset.c
43 | libpng/pngtrans.c
44 | libpng/pngwio.c
45 | libpng/pngwrite.c
46 | libpng/pngwtran.c
47 | libpng/pngwutil.c
48 | )
49 |
50 | # NOW BUILD OUR TARGET
51 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/libpng/" ${ZLIB_INCLUDE_DIR})
52 |
53 | add_library(${PNG_LIB_NAME} STATIC ${libpng_sources})
54 | target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY})
55 |
56 | # Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set
57 | IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
58 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
59 | ENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
60 |
61 | set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES
62 | OUTPUT_NAME ${PNG_LIB_NAME}
63 | CLEAN_DIRECT_OUTPUT 1)
64 |
--------------------------------------------------------------------------------
/tests/particle/smoke.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | tex = drystal.load_surface('spritesheet.png')
4 | local sys_smoke = drystal.new_system(200, 596)
5 |
6 | sys_smoke:set_sizes {
7 | [0]=100,
8 | [0.25] = 75,
9 | [0.5] = 55,
10 | [1] = 25,
11 | }
12 | sys_smoke:set_colors {
13 | [0]=drystal.colors.white,
14 | [0.4]=drystal.colors.gray,
15 | [0.7]=drystal.colors.gray:darker(),
16 | [1]='black',
17 | }
18 | sys_smoke:set_alphas {
19 | [0]=20,
20 | [0.2]=100,
21 | [1]=0,
22 | }
23 |
24 | sys_smoke:set_lifetime(3)
25 | sys_smoke:set_direction(-math.pi / 2 - math.pi/8, -math.pi/2 + math.pi/8)
26 | sys_smoke:set_initial_velocity(100, 150)
27 | sys_smoke:set_initial_acceleration(0)
28 | sys_smoke:set_offset(-10, 20, 0, 10)
29 | sys_smoke:set_emission_rate(16)
30 | sys_smoke:set_texture(tex, 0, 0)
31 |
32 | local sys_smoke_opaque = drystal.new_system(600, 600)
33 |
34 | sys_smoke_opaque:set_sizes {
35 | [0]=100,
36 | [0.25] = 75,
37 | [0.5] = 55,
38 | [1] = 25,
39 | }
40 | sys_smoke_opaque:set_colors {
41 | [0]=drystal.colors.white,
42 | [0.4]=drystal.colors.white:darker(),
43 | [0.9]='black',
44 | }
45 |
46 | sys_smoke_opaque:set_lifetime(3)
47 | sys_smoke_opaque:set_direction(-math.pi / 2 - math.pi/8, -math.pi/2 + math.pi/8)
48 | sys_smoke_opaque:set_initial_velocity(100, 150)
49 | sys_smoke_opaque:set_initial_acceleration(0)
50 | sys_smoke_opaque:set_emission_rate(25)
51 | sys_smoke_opaque:set_texture(tex, 0, 0)
52 |
53 | function drystal.init()
54 | drystal.resize(800, 600)
55 | sys_smoke:start()
56 | sys_smoke_opaque:start()
57 | end
58 |
59 | function drystal.update(dt)
60 | if dt > .06 then
61 | dt = .06
62 | end
63 | sys_smoke:update(dt)
64 | sys_smoke_opaque:update(dt)
65 | end
66 |
67 | function drystal.draw()
68 | drystal.set_blend_mode(drystal.blends.default)
69 | drystal.set_color('black')
70 | drystal.set_alpha(255)
71 | drystal.draw_background()
72 |
73 | sys_smoke_opaque:draw()
74 |
75 | drystal.set_blend_mode(drystal.blends.add)
76 | sys_smoke:draw()
77 | end
78 |
79 | function drystal.key_press(k)
80 | if k == 'a' then
81 | drystal.stop()
82 | end
83 | end
84 |
85 |
--------------------------------------------------------------------------------
/src/graphics/shader.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #define GL_GLEXT_PROTOTYPES
20 | #ifndef EMSCRIPTEN
21 | #include
22 | #else
23 | #include
24 | #endif
25 |
26 | typedef struct Shader Shader;
27 |
28 | extern const char* SHADER_PREFIX;
29 | extern const char* DEFAULT_VERTEX_SHADER;
30 | extern const char* DEFAULT_FRAGMENT_SHADER_COLOR;
31 | extern const char* DEFAULT_FRAGMENT_SHADER_TEX;
32 |
33 | typedef enum AttrLocationIndex {
34 | // WebGL wants 0 as an attribute, so here it is
35 | ATTR_LOCATION_POSITION = 0,
36 | ATTR_LOCATION_COLOR,
37 | ATTR_LOCATION_TEXCOORD,
38 | } AttrLocationIndex;
39 |
40 | enum VarLocationIndex {
41 | VAR_LOCATION_COLOR,
42 | VAR_LOCATION_TEX,
43 | };
44 | typedef enum VarLocationIndex VarLocationIndex;
45 |
46 | struct Shader {
47 | GLuint prog_color;
48 | GLuint prog_tex;
49 | GLuint vert;
50 | GLuint frag_color;
51 | GLuint frag_tex;
52 |
53 | struct {
54 | GLuint dxLocation;
55 | GLuint dyLocation;
56 | GLuint zoomLocation;
57 | GLuint rotationMatrixLocation;
58 | GLuint destinationSizeLocation;
59 | GLuint sourceSizeLocation;
60 | } vars[2];
61 | int ref;
62 |
63 | };
64 | Shader *shader_new(GLuint prog_color, GLuint prog_tex, GLuint vert, GLuint frag_color, GLuint frag_tex);
65 | void shader_free(Shader *s);
66 |
67 | void shader_feed(const Shader *s, const char* name, float value);
68 |
69 |
--------------------------------------------------------------------------------
/src/log.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #include
24 |
25 | #include "macro.h"
26 | #include "util.h"
27 |
28 | typedef enum LogLevel
29 | {
30 | LOG_ERROR,
31 | LOG_WARNING,
32 | LOG_INFO,
33 | LOG_DEBUG,
34 | } LogLevel;
35 |
36 | /*
37 | * Before using the logging API you must call log_category() at the beginning
38 | * of your file, like this:
39 | * log_category("display");
40 | * [...]
41 | * if (r < 0) {
42 | * log_error("an error happenned"");
43 | * }
44 | */
45 | #define log_category(cat) \
46 | static _unused_ const char *_log_category = cat
47 |
48 | void log_internal(LogLevel level, const char *category, const char *format, ...) _printf_(3,4);
49 |
50 | #ifndef NDEBUG
51 | #define log_debug(msg, ...) \
52 | log_internal(LOG_DEBUG, _log_category, "[%s:%d %s()] " msg, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
53 | #define log_info(msg, ...) \
54 | log_internal(LOG_INFO, _log_category, msg, ##__VA_ARGS__)
55 | #else
56 | #define log_debug(msg, ...)
57 | #define log_info(msg, ...)
58 | #endif
59 |
60 | #define log_warning(msg, ...) \
61 | log_internal(LOG_WARNING, _log_category, msg, ##__VA_ARGS__)
62 |
63 | #define log_error(msg, ...) \
64 | log_internal(LOG_ERROR, _log_category, msg, ##__VA_ARGS__)
65 |
66 | __attribute__((noreturn)) void log_oom_and_exit(void);
67 |
68 | #ifdef __cplusplus
69 | }
70 | #endif
71 |
72 |
--------------------------------------------------------------------------------
/src/log.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 |
21 | #include "log.h"
22 |
23 | _printf_(3, 0) static void log_message(const char *level, const char *category, const char *format, va_list ap)
24 | {
25 | fprintf(stderr, "[%s|%10s] ", level, category);
26 | vfprintf(stderr, format, ap);
27 | fprintf(stderr, "\n");
28 | }
29 |
30 | _printf_(3, 0) static void log_internalv(LogLevel level, const char *category, const char *format, va_list ap)
31 | {
32 | switch (level) {
33 | case LOG_ERROR:
34 | log_message(stderr_use_colors() ? ANSI_HIGHLIGHT_RED_ON "ERR " ANSI_RESET : "ERR ", category, format, ap);
35 | break;
36 | case LOG_WARNING:
37 | log_message(stderr_use_colors() ? ANSI_HIGHLIGHT_YELLOW_ON "WARN" ANSI_RESET : "WARN", category, format, ap);
38 | break;
39 | case LOG_INFO:
40 | log_message(stderr_use_colors() ? ANSI_HIGHLIGHT_ON "INFO" ANSI_RESET : "INFO", category, format, ap);
41 | break;
42 | case LOG_DEBUG:
43 | log_message(stderr_use_colors() ? ANSI_HIGHLIGHT_GRAY_ON "DBG " ANSI_RESET : "DBG ", category, format, ap);
44 | break;
45 | }
46 | }
47 |
48 | void log_oom_and_exit(void)
49 | {
50 | fprintf(stderr, "Out of memory. Exiting.");
51 | exit(EXIT_FAILURE);
52 | }
53 |
54 | void log_internal(LogLevel level, const char *category, const char *format, ...)
55 | {
56 | va_list ap;
57 |
58 | va_start(ap, format);
59 | log_internalv(level, category, format, ap);
60 | va_end(ap);
61 | }
62 |
--------------------------------------------------------------------------------
/src/graphics/sprite.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local Sprite = {
4 | x=0,
5 | y=0,
6 | angle=0,
7 | w=0,
8 | h=0,
9 | source=nil,
10 | color={255, 255, 255},
11 | alpha=255,
12 | }
13 | local sprite_is_update_with = {
14 | x=true,
15 | y=true,
16 | w=true,
17 | h=true,
18 | angle=true,
19 | source=true,
20 | }
21 | Sprite.__index = function(self, key)
22 | return rawget(self.data, key) or rawget(self, key) or rawget(Sprite, key)
23 | end
24 | Sprite.__newindex = function(self, key, value)
25 | if sprite_is_update_with[key] then
26 | rawset(self.data, key, value)
27 | self._updated = true
28 | else
29 | rawset(self, key, value)
30 | end
31 | end
32 |
33 | drystal.Sprite = Sprite
34 |
35 | function drystal.new_sprite(source, x, y, w, h)
36 | local sprite = setmetatable({data={}}, Sprite)
37 | sprite.source = source
38 | sprite.data.x = x or 0
39 | sprite.data.y = y or 0
40 | sprite.data.w = w or source.w
41 | sprite.data.h = h or source.h
42 | return sprite
43 | end
44 |
45 | function Sprite:_update()
46 | local cos = math.cos(self.angle)
47 | local sin = math.sin(self.angle)
48 | local x = self.x
49 | local y = self.y
50 | local w = self.w
51 | local h = self.h
52 | local function rot(_x, _y)
53 | return x + _x*cos - _y*sin + w/2,
54 | y + _y*cos + _x*sin + h/2
55 | end
56 | self._x1, self._y1 = rot(-w/2, -h/2)
57 | self._x2, self._y2 = rot(w/2, -h/2)
58 | self._x3, self._y3 = rot(w/2, h/2)
59 | self._x4, self._y4 = rot(-w/2, h/2)
60 | self._updated = false
61 | end
62 |
63 | function Sprite:draw()
64 | drystal.set_color(self.color)
65 | drystal.set_alpha(self.alpha)
66 | if self._updated then
67 | self:_update()
68 | end
69 |
70 | local x1, y1 = self._x1, self._y1
71 | local x2, y2 = self._x2, self._y2
72 | local x3, y3 = self._x3, self._y3
73 | local x4, y4 = self._x4, self._y4
74 | local xi = self.source.x
75 | local yi = self.source.y
76 | local xi2 = self.source.x + self.source.w
77 | local yi2 = self.source.y + self.source.h
78 |
79 | if self.w < 0 then
80 | xi, xi2 = xi2, xi
81 | end
82 | if self.h < 0 then
83 | yi, yi2 = yi2, yi
84 | end
85 |
86 | drystal.draw_quad(xi, yi, xi2, yi, xi2, yi2, xi, yi2,
87 | x1, y1, x2, y2, x3, y3, x4, y4)
88 | end
89 |
90 |
--------------------------------------------------------------------------------
/src/build.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef BUILD_AUDIO
20 | #define _AUDIO_FEATURE_ "+AUDIO"
21 | #else
22 | #define _AUDIO_FEATURE_ "-AUDIO"
23 | #endif
24 |
25 | #ifdef BUILD_FONT
26 | #define _FONT_FEATURE_ "+FONT"
27 | #else
28 | #define _FONT_FEATURE_ "-FONT"
29 | #endif
30 |
31 | #ifdef BUILD_GRAPHICS
32 | #define _GRAPHICS_FEATURE_ "+GRAPHICS"
33 | #else
34 | #define _GRAPHICS_FEATURE_ "-GRAPHICS"
35 | #endif
36 |
37 | #ifdef BUILD_LIVECODING
38 | #define _LIVECODING_FEATURE_ "+LIVECODING"
39 | #else
40 | #define _LIVECODING_FEATURE_ "-LIVECODING"
41 | #endif
42 |
43 | #ifdef BUILD_PHYSICS
44 | #define _PHYSICS_FEATURE_ "+PHYSICS"
45 | #else
46 | #define _PHYSICS_FEATURE_ "-PHYSICS"
47 | #endif
48 |
49 | #ifdef BUILD_PARTICLE
50 | #define _PARTICLE_FEATURE_ "+PARTICLE"
51 | #else
52 | #define _PARTICLE_FEATURE_ "-PARTICLE"
53 | #endif
54 |
55 | #ifdef BUILD_STORAGE
56 | #define _STORAGE_FEATURE_ "+STORAGE"
57 | #else
58 | #define _STORAGE_FEATURE_ "-STORAGE"
59 | #endif
60 |
61 | #ifdef BUILD_UTILS
62 | #define _UTILS_FEATURE_ "+UTILS"
63 | #else
64 | #define _UTILS_FEATURE_ "-UTILS"
65 | #endif
66 |
67 | #ifdef BUILD_WEB
68 | #define _WEB_FEATURE_ "+WEB"
69 | #else
70 | #define _WEB_FEATURE_ "-WEB"
71 | #endif
72 |
73 | #define DRYSTAL_FEATURES \
74 | _AUDIO_FEATURE_ " " \
75 | _FONT_FEATURE_ " " \
76 | _GRAPHICS_FEATURE_ " " \
77 | _LIVECODING_FEATURE_ " " \
78 | _PHYSICS_FEATURE_ " " \
79 | _PARTICLE_FEATURE_ " " \
80 | _STORAGE_FEATURE_ " " \
81 | _UTILS_FEATURE_ " " \
82 | _WEB_FEATURE_ " "
83 |
--------------------------------------------------------------------------------
/src/graphics/camera.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 |
20 | #include "camera.h"
21 | #include "util.h"
22 |
23 | #define CAMERA_STACK_SIZE (64)
24 | static Camera cameraStack[CAMERA_STACK_SIZE];
25 | static size_t cameraStackIndex;
26 |
27 | Camera *camera_new()
28 | {
29 | Camera *c = new0(Camera, 1);
30 | c->zoom = 1;
31 |
32 | return c;
33 | }
34 |
35 | void camera_free(Camera *c)
36 | {
37 | if (!c)
38 | return;
39 |
40 | free(c);
41 | }
42 |
43 | void camera_update_matrix(Camera *c, int width, int height)
44 | {
45 | float ratio;
46 | float angle;
47 |
48 | assert(c);
49 | assert(width > 0);
50 | assert(height > 0);
51 |
52 | angle = c->angle;
53 | ratio = (float) width / height;
54 | c->matrix[0] = cosf(angle);
55 | c->matrix[1] = sinf(angle) * ratio;
56 | c->matrix[2] = -sinf(angle) / ratio;
57 | c->matrix[3] = cosf(angle);
58 | }
59 |
60 | void camera_reset(Camera *c)
61 | {
62 | assert(c);
63 |
64 | c->dx = 0;
65 | c->dy = 0;
66 | c->angle = 0;
67 | c->zoom = 1;
68 | }
69 |
70 | void camera_push(Camera *c)
71 | {
72 | assert(c);
73 | assert(!camera_stack_is_full());
74 |
75 | cameraStack[cameraStackIndex++] = *c;
76 | }
77 |
78 | void camera_pop(Camera *c)
79 | {
80 | assert(c);
81 | assert(!camera_stack_is_empty());
82 |
83 | *c = cameraStack[--cameraStackIndex];
84 | }
85 |
86 | bool camera_stack_is_full(void)
87 | {
88 | return cameraStackIndex == CAMERA_STACK_SIZE;
89 | }
90 |
91 | bool camera_stack_is_empty(void)
92 | {
93 | return cameraStackIndex == 0;
94 | }
95 |
96 |
--------------------------------------------------------------------------------
/src/particle/system_bind.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 |
21 | #include "lua_util.h"
22 | #include "system.h"
23 |
24 | DECLARE_PUSHPOP(System, system)
25 |
26 | int mlua_new_system(lua_State* L);
27 | int mlua_set_position_system(lua_State* L);
28 | int mlua_get_position_system(lua_State* L);
29 | int mlua_set_offset_system(lua_State* L);
30 | int mlua_get_offset_system(lua_State* L);
31 | int mlua_update_system(lua_State* L);
32 | int mlua_draw_system(lua_State* L);
33 | int mlua_add_size_system(lua_State* L);
34 | int mlua_add_color_system(lua_State* L);
35 | int mlua_add_alpha_system(lua_State* L);
36 | int mlua_clear_sizes_system(lua_State* L);
37 | int mlua_clear_colors_system(lua_State* L);
38 | int mlua_clear_alphas_system(lua_State* L);
39 | int mlua_set_texture_system(lua_State* L);
40 | int mlua_clone_system(lua_State* L);
41 | int mlua_free_system(lua_State* L);
42 |
43 | #define __SYSTEM_GET_SET(attr) \
44 | int mlua_get_##attr##_system(lua_State* L); \
45 | int mlua_set_##attr##_system(lua_State* L);
46 |
47 | __SYSTEM_GET_SET(min_lifetime)
48 | __SYSTEM_GET_SET(max_lifetime)
49 | __SYSTEM_GET_SET(min_direction)
50 | __SYSTEM_GET_SET(max_direction)
51 | __SYSTEM_GET_SET(min_initial_acceleration)
52 | __SYSTEM_GET_SET(max_initial_acceleration)
53 | __SYSTEM_GET_SET(min_initial_velocity)
54 | __SYSTEM_GET_SET(max_initial_velocity)
55 | __SYSTEM_GET_SET(emission_rate)
56 |
57 | #undef __SYSTEM_GET_SET
58 |
59 | #define __ACTION(action) \
60 | int mlua_##action##_system(lua_State* L);
61 | __ACTION(emit)
62 | __ACTION(start)
63 | __ACTION(stop)
64 | __ACTION(reset)
65 |
66 | #undef __ACTION
67 |
68 |
--------------------------------------------------------------------------------
/tests/particle/simple.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | local sys1 = drystal.new_system(200, 300, 5)
4 | sys1:add_size(0, 6)
5 | sys1:add_size(1, 6)
6 | sys1:add_color(0, 0, 255, 0, 255, 0, 255)
7 | sys1:add_color(1, 0, 255, 0, 255, 0, 255)
8 | local running
9 |
10 | local scrolling = false
11 | local scrollx, scrolly = 0, 0
12 |
13 | local systems = {
14 | drystal.new_system(400, 300),
15 | }
16 |
17 | function drystal.init()
18 | drystal.resize(600, 600)
19 | sys1:start()
20 | running = true
21 | for _, s in ipairs(systems) do
22 | s:start()
23 | end
24 | end
25 |
26 | function drystal.update(dt)
27 | if dt > .06 then
28 | dt = .06
29 | end
30 | sys1:update(dt)
31 | for _, s in ipairs(systems) do
32 | s:update(dt)
33 | end
34 | end
35 |
36 | function drystal.draw()
37 | drystal.set_color(0, 0, 0)
38 | drystal.draw_background()
39 |
40 | sys1:draw(scrollx, scrolly)
41 | for _, s in ipairs(systems) do
42 | s:draw(scrollx, scrolly)
43 | end
44 | end
45 |
46 | function drystal.mouse_motion(x, y, dx, dy)
47 | sys1:set_position(x - scrollx, y - scrolly)
48 | if scrolling then
49 | scrollx = scrollx + dx
50 | scrolly = scrolly + dy
51 | end
52 | end
53 |
54 | function drystal.mouse_press(x, y, b)
55 | if b == drystal.buttons.left then
56 | local s = drystal.new_system(x - scrollx, y - scrolly)
57 | s:set_direction(0, math.pi/2)
58 | s:add_size(0, 6)
59 | s:add_size(1, 6)
60 | s:add_color(0, 0, 0, 0)
61 | s:add_color(1, 255, 255, 255)
62 | s:start()
63 | table.insert(systems, s)
64 | local s = s:clone()
65 | s:set_direction(math.pi, math.pi + math.pi/2)
66 | table.insert(systems, s)
67 | elseif b == drystal.buttons.right then
68 | scrolling = true
69 | elseif b == drystal.buttons.wheel_up then
70 | sys1:set_emission_rate(sys1:get_emission_rate() + 1)
71 | elseif b == drystal.buttons.wheel_down then
72 | sys1:set_emission_rate(sys1:get_emission_rate() - 1)
73 | end
74 | end
75 |
76 | function drystal.mouse_release(_, _, b)
77 | if b == drystal.buttons.right then
78 | scrolling = false
79 | end
80 | end
81 |
82 | function drystal.key_press(k)
83 | if k == 'space' then
84 | if running then
85 | sys1:stop()
86 | else
87 | sys1:start()
88 | end
89 | running = not running
90 | elseif k == 'c' then
91 | systems = {}
92 | elseif k == 'a' then
93 | drystal.stop()
94 | end
95 | end
96 |
97 |
--------------------------------------------------------------------------------
/cmake/GenerateLuaFiles.cmake:
--------------------------------------------------------------------------------
1 | # put all .lua files into a single .cpp files
2 | # the function load_luafiles runs those codes and return 1 if success
3 | set(LUAFILES_LIST "drystal.lua" "traceback.lua")
4 | if(BUILD_WEB)
5 | list(APPEND LUAFILES_LIST "web/web.lua")
6 | endif()
7 | if(BUILD_PARTICLE)
8 | list(APPEND LUAFILES_LIST "particle/particle.lua")
9 | endif()
10 | if(BUILD_PHYSICS)
11 | list(APPEND LUAFILES_LIST "physics/raycast.lua")
12 | endif()
13 | if(BUILD_GRAPHICS)
14 | list(APPEND LUAFILES_LIST "graphics/postfx.lua" "graphics/draw.lua" "graphics/sprite.lua" "graphics/colors.lua")
15 | endif()
16 | if(BUILD_LIVECODING)
17 | list(APPEND LUAFILES_LIST "reload.lua")
18 | endif()
19 |
20 | set(LUAFILES_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/luafiles.c)
21 |
22 | # generate luafiles.c
23 | file(WRITE ${LUAFILES_OUTPUT} "
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include \"luafiles.h\"
30 | #include \"lua_util.h\"
31 | #include \"log.h\"
32 | log_category(\"luafiles\");
33 |
34 | int load_luafiles(lua_State* L, int traceback_index)
35 | {
36 | (void) L;")
37 | foreach (luacode ${LUAFILES_LIST})
38 | file(READ ${luacode} FILE_CONTENT)
39 | get_filename_component(luacode_short ${luacode} NAME)
40 | # \\ => \\\\
41 | string(REGEX REPLACE "\\\\\\\\" "\\\\\\\\\\\\\\\\" FILE_CONTENT "${FILE_CONTENT}")
42 | # \n => \\n
43 | string(REGEX REPLACE "\\\\\\n" "\\\\\\\\n" FILE_CONTENT "${FILE_CONTENT}")
44 | # " => \"
45 | string(REGEX REPLACE "\\\"" "\\\\\"" FILE_CONTENT "${FILE_CONTENT}")
46 | # => \n\
47 | string(REGEX REPLACE "\n" "\\\\n\\\\\n" FILE_CONTENT "${FILE_CONTENT}")
48 | file(APPEND ${LUAFILES_OUTPUT} "
49 | {
50 | const char* file = \"${luacode_short}\";
51 | const char* code = \"${FILE_CONTENT}\";
52 | if (luaL_loadbuffer(L, code, strlen(code), file)) {
53 | log_error(\"%s\", lua_tostring(L, -1));
54 | return 0;
55 | }
56 | if (lua_pcall(L, 0, 0, traceback_index)) {
57 | return 0;
58 | }
59 | }
60 | ")
61 | endforeach (luacode)
62 | file(APPEND ${LUAFILES_OUTPUT} "
63 | return 1;
64 | }")
65 |
66 | add_custom_command(
67 | OUTPUT ${LUAFILES_OUTPUT}
68 | COMMAND cmake .. # re-run code generation
69 | DEPENDS ${LUAFILES_LIST}
70 | VERBATIM)
71 | list(APPEND SOURCES ${LUAFILES_OUTPUT})
72 |
73 |
--------------------------------------------------------------------------------
/tests/graphics/buffer.lua:
--------------------------------------------------------------------------------
1 | local drystal = require "drystal"
2 |
3 | -- test sizes
4 | buffer = drystal.new_buffer(6)
5 | buffer:use()
6 | drystal.draw_point(1,1,4)
7 | drystal.draw_point(1,1,4)
8 | drystal.draw_point(1,1,4)
9 | drystal.draw_point(1,1,4)
10 | drystal.draw_point(1,1,4)
11 | drystal.draw_point(1,1,4)
12 |
13 | buffer = assert(drystal.new_buffer(4))
14 | buffer:use()
15 | drystal.draw_line(1,1,1,1)
16 | drystal.draw_line(1,1,1,1)
17 |
18 | buffer = assert(drystal.new_buffer(10))
19 | buffer:use()
20 | drystal.draw_triangle(1,1,1,1,1,1)
21 | drystal.draw_triangle(1,1,1,1,1,1)
22 | drystal.draw_triangle(1,1,1,1,1,1)
23 |
24 | drystal.use_default_buffer()
25 |
26 | local spritesheet = assert(drystal.fromjson(io.open('image.json'):read('*all')))
27 |
28 | function drystal.init()
29 | drystal.resize(600, 400)
30 | image = assert(drystal.load_surface(spritesheet.meta.image))
31 | image:draw_from()
32 | print('b to toggle buffer')
33 | end
34 |
35 | local bufferize = true
36 | local buffer
37 | local number = 3000
38 | local tick = 0
39 | function drystal.draw()
40 | tick = tick + 1
41 |
42 | drystal.set_alpha(255)
43 | drystal.set_color(10, 10, 30)
44 | drystal.draw_background()
45 |
46 | local sprite = spritesheet.frames['character.png'].frame
47 | drystal.set_color(0, 255, 0)
48 | drystal.set_alpha(255)
49 | drystal.draw_sprite(sprite, 300, 200)
50 |
51 | drystal.set_color(255, 0, 0)
52 | drystal.set_alpha(105)
53 |
54 | if bufferize then
55 | if not buffer then
56 | buffer = assert(drystal.new_buffer(number * 6 / 2))
57 | buffer:use()
58 | heavy_draw(number)
59 | buffer:upload_and_free()
60 | drystal.use_default_buffer()
61 | end
62 | buffer:draw(math.sin(tick/10)*sprite.w)
63 | else
64 | heavy_draw(number)
65 | end
66 |
67 | drystal.set_color(255, 0, 0)
68 | drystal.set_alpha(255)
69 | drystal.draw_sprite(sprite, 332, 200)
70 | drystal.draw_line(0, 0, 600, 400)
71 | end
72 |
73 | function heavy_draw(number)
74 | local sprite = spritesheet.frames['character.png'].frame
75 | for x = 0, number-1 do
76 | drystal.set_color(200, 200, 200)
77 | drystal.set_alpha(255)
78 | drystal.draw_sprite(sprite, x, (x%30)*30)
79 | end
80 | end
81 |
82 | function drystal.key_press(key)
83 | if key == 'a' then
84 | drystal.stop()
85 | elseif key == 'b' then
86 | bufferize = not bufferize
87 | elseif key == 'f' then
88 | drystal.set_fullscreen(true)
89 | end
90 | end
91 |
92 |
--------------------------------------------------------------------------------
/src/drystal.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | function drystal.file_exists(name)
4 | local f = io.open(name, "r")
5 | if f then
6 | f:close(f)
7 | return true
8 | end
9 | return false
10 | end
11 |
12 | local function remove_userpackages()
13 | local keep = {
14 | _G=true,
15 | coroutine=true,
16 | table=true,
17 | io=true,
18 | os=true,
19 | string=true,
20 | utf8=true,
21 | bit32=true,
22 | math=true,
23 | debug=true,
24 | package=true,
25 | drystal=true,
26 | }
27 | for name, value in pairs(package.loaded) do
28 | if not keep[name] then
29 | package.loaded[name] = nil
30 | end
31 | end
32 | end
33 | function drystal.reload()
34 | if drystal.prereload then
35 | drystal.prereload()
36 | end
37 | remove_userpackages()
38 | local ok = drystal._load_code()
39 | if ok then
40 | if drystal.init then
41 | drystal.init()
42 | end
43 | if drystal.postreload then
44 | drystal.postreload()
45 | end
46 | end
47 | collectgarbage()
48 | return ok
49 | end
50 |
51 | function table.print(t)
52 | local str = {}
53 | for k, v in pairs(t) do
54 | table.insert(str, ('%s=%s'):format(k, v))
55 | end
56 | print(table.concat(str, ','))
57 | end
58 |
59 | function math.distance(x1, y1, x2, y2)
60 | return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2))
61 | end
62 |
63 | function math.clamp(v, min, max)
64 | return math.min(math.max(v, min), max)
65 | end
66 |
67 | function math.aabb(o1, o2)
68 | local x1 = o1.x
69 | local y1 = o1.y
70 | local x2 = o2.x
71 | local y2 = o2.y
72 | return x2 <= x1 + o1.w
73 | and x2 + o2.w >= x1
74 | and y2 <= y1 + o1.h
75 | and y2 + o2.h >= y1
76 | end
77 |
78 | function math.inside(o, x, y)
79 | local xo = o.x
80 | local yo = o.y
81 | return x >= xo and y >= yo
82 | and x < xo + o.w and y < yo + o.h
83 | end
84 |
85 | drystal.Timer = {
86 | time=0,
87 | update=function(self, dt)
88 | if self.finished then return end
89 | self.time = self.time + dt
90 | if self.time >= self.duration then
91 | self.finished = true
92 | if self.callback then
93 | self.callback()
94 | end
95 | end
96 | end,
97 | }
98 | drystal.Timer.__index = drystal.Timer
99 | function drystal.new_timer(duration, callback)
100 | return setmetatable({
101 | duration=duration,
102 | callback=callback,
103 | }, drystal.Timer)
104 | end
105 |
106 |
--------------------------------------------------------------------------------
/src/macro.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
24 | #define BEGIN_DISABLE_WARNINGS \
25 | _Pragma("GCC diagnostic push")
26 |
27 | #define DISABLE_WARNING_EFFCPP \
28 | _Pragma("GCC diagnostic ignored \"-Weffc++\"")
29 | #define DISABLE_WARNING_STRICT_ALIASING \
30 | _Pragma("GCC diagnostic ignored \"-Wstrict-aliasing\"")
31 |
32 | #define END_DISABLE_WARNINGS \
33 | _Pragma("GCC diagnostic pop")
34 | #else
35 | #ifdef __clang__
36 | #define BEGIN_DISABLE_WARNINGS \
37 | _Pragma("clang diagnostic push")
38 |
39 | #define DISABLE_WARNING_EFFCPP \
40 | _Pragma("clang diagnostic ignored \"-Weffc++\"")
41 | #define DISABLE_WARNING_STRICT_ALIASING \
42 | _Pragma("clang diagnostic ignored \"-Wstrict-aliasing\"")
43 |
44 | #define END_DISABLE_WARNINGS \
45 | _Pragma("clang diagnostic pop")
46 | #else
47 | #define BEGIN_DISABLE_WARNINGS
48 | #define DISABLE_WARNING_EFFCPP
49 | #define DISABLE_WARNING_STRICT_ALIASING
50 | #define END_DISABLE_WARNINGS
51 | #endif
52 | #endif
53 |
54 | #define _malloc_ __attribute__ ((malloc))
55 | #define _sentinel_ __attribute__ ((sentinel))
56 | #define _unused_ __attribute__ ((unused))
57 | #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
58 |
59 | #define USEC_PER_SEC 1000000ULL
60 | #define MSEC_PER_SEC 1000ULL
61 | #define NSEC_PER_USEC 1000ULL
62 |
63 | #define MAX(a,b) \
64 | ({ \
65 | __typeof__ (a) _a = (a); \
66 | __typeof__ (b) _b = (b); \
67 | _a > _b ? _a : _b; \
68 | })
69 |
70 | /* Assert with Side Effects */
71 | #ifdef NDEBUG
72 | #define assert_se(x) (x)
73 | #else
74 | #define assert_se(x) assert(x)
75 | #endif
76 |
77 | #ifdef __cplusplus
78 | }
79 | #endif
80 |
81 |
--------------------------------------------------------------------------------
/cmake/Utils.cmake:
--------------------------------------------------------------------------------
1 | include(CheckCCompilerFlag)
2 | include(CheckCXXCompilerFlag)
3 |
4 | function(check_compilers_unknown)
5 | if (NOT CMAKE_CXX_COMPILER)
6 | message(FATAL_ERROR "The C++ compiler was not found. Please add the C++ compiler in your $PATH and re-run CMake.")
7 | endif()
8 | if (NOT CMAKE_C_COMPILER)
9 | message(FATAL_ERROR "The C compiler was not found. Please add the C++ compiler in your $PATH and re-run CMake.")
10 | endif()
11 | endfunction()
12 |
13 | function(check_git_submodules_initialized)
14 | if (NOT EXISTS "${PROJECT_SOURCE_DIR}/external/box2d/.git" OR
15 | NOT EXISTS "${PROJECT_SOURCE_DIR}/external/libpng/.git" OR
16 | NOT EXISTS "${PROJECT_SOURCE_DIR}/external/lua/.git" OR
17 | NOT EXISTS "${PROJECT_SOURCE_DIR}/external/lua-cjson/.git" OR
18 | NOT EXISTS "${PROJECT_SOURCE_DIR}/external/zlib/.git")
19 | message(FATAL_ERROR "The git submodules are not available. Please run
20 | git submodule update --init --recursive")
21 | endif()
22 | endfunction()
23 |
24 | function(add_c_flag_if_supported flags flag has)
25 | check_c_compiler_flag("${flag}" ${has}_C)
26 | if (${${has}_C})
27 | set(${has} TRUE PARENT_SCOPE)
28 | set(${flags} "${${flags}} ${flag}" PARENT_SCOPE)
29 | endif()
30 | endfunction()
31 |
32 | function(add_cxx_flag_if_supported flags flag has)
33 | check_cxx_compiler_flag("${flag}" ${has}_CXX)
34 | if (${${has}_CXX})
35 | set(${has} TRUE PARENT_SCOPE)
36 | set(${flags} "${${flags}} ${flag}" PARENT_SCOPE)
37 | endif()
38 | endfunction()
39 |
40 | function(add_c_cxx_flag_if_supported flags flag has)
41 | check_c_compiler_flag("${flag}" ${has}_C)
42 | if (${${has}_C})
43 | check_cxx_compiler_flag("${flag}" ${has}_CXX)
44 | if (${${has}_CXX})
45 | set(${has} TRUE PARENT_SCOPE)
46 | set(${flags} "${${flags}} ${flag}" PARENT_SCOPE)
47 | endif()
48 | endif()
49 | endfunction()
50 |
51 | if (CMAKE_CXX_COMPILER MATCHES ".*clang")
52 | set(CMAKE_COMPILER_IS_CLANGXX 1)
53 | endif()
54 | if (CMAKE_C_COMPILER MATCHES ".*clang")
55 | set(CMAKE_COMPILER_IS_CLANGC 1)
56 | endif()
57 |
58 | add_custom_target(astyle COMMAND
59 | astyle --indent=tab --indent-preprocessor --style=kr
60 | --pad-oper --pad-header --unpad-paren -S -n
61 | --exclude="api.hpp" --exclude="api.cpp"
62 | --exclude="api.h" --exclude="api.c"
63 | --recursive ${CMAKE_SOURCE_DIR}"/src/*.cpp"
64 | ${CMAKE_SOURCE_DIR}"/src/*.hpp"
65 | ${CMAKE_SOURCE_DIR}"/src/*.c"
66 | ${CMAKE_SOURCE_DIR}"/src/*.h"
67 | )
68 |
69 |
--------------------------------------------------------------------------------
/src/graphics/shader_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "display.h"
24 | #include "shader_bind.h"
25 | #include "shader.h"
26 | #include "log.h"
27 |
28 | log_category("shader");
29 |
30 | IMPLEMENT_PUSHPOP(Shader, shader)
31 |
32 | int mlua_new_shader(lua_State* L)
33 | {
34 | assert(L);
35 |
36 | const char *vert = NULL, *frag_color = NULL, *frag_tex = NULL;
37 | // strings can be nil
38 | if (lua_gettop(L) >= 1) { // one argument, it's the vertex shader
39 | vert = lua_tostring(L, 1);
40 | }
41 | if (lua_gettop(L) >= 2) {
42 | frag_color = lua_tostring(L, 2);
43 | }
44 | if (lua_gettop(L) >= 3) {
45 | frag_tex = lua_tostring(L, 3);
46 | }
47 | char* error;
48 | Shader* shader = display_new_shader(vert, frag_color, frag_tex, &error);
49 | if (shader) {
50 | push_shader(L, shader);
51 | return 1;
52 | } else {
53 | lua_pushnil(L);
54 | lua_pushstring(L, error);
55 | free(error);
56 | return 2;
57 | }
58 | }
59 |
60 | int mlua_use_shader(lua_State* L)
61 | {
62 | assert(L);
63 |
64 | Shader* shader = pop_shader(L, -1);
65 | display_use_shader(shader);
66 | return 0;
67 | }
68 |
69 | int mlua_use_default_shader(_unused_ lua_State* L)
70 | {
71 | display_use_default_shader();
72 | return 0;
73 | }
74 |
75 | int mlua_feed_shader(lua_State* L)
76 | {
77 | assert(L);
78 |
79 | Shader* shader = pop_shader(L, 1);
80 | const char* name = luaL_checkstring(L, 2);
81 | lua_Number value = luaL_checknumber(L, 3);
82 | shader_feed(shader, name, value);
83 | return 0;
84 | }
85 |
86 | int mlua_free_shader(lua_State* L)
87 | {
88 | assert(L);
89 |
90 | Shader* shader = pop_shader(L, 1);
91 | display_free_shader(shader);
92 | return 0;
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/src/particle/particle.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 | local System = drystal.System
3 |
4 | local function is_getset(funcname)
5 | if funcname:sub(1, string.len('set_min_')) == 'set_min_' then
6 | return true
7 | end
8 | return false
9 | end
10 |
11 | local funcs = {}
12 | for k, v in pairs(System) do
13 | if is_getset(k) then
14 | local attr = k:sub(string.len('get_min_') + 1)
15 | local getmin = System['get_min_' .. attr]
16 | local getmax = System['get_max_' .. attr]
17 | local setmin = System['set_min_' .. attr]
18 | local setmax = System['set_max_' .. attr]
19 | local get_both = function(data)
20 | return getmin(data), getmax(data)
21 | end
22 | local set_both = function(data, min, max)
23 | setmin(data, min)
24 | setmax(data, max or min)
25 | end
26 | funcs['set_' .. attr] = set_both
27 | funcs['get_' .. attr] = get_both
28 | end
29 | end
30 |
31 | for k, v in pairs(funcs) do
32 | System[k] = v
33 | end
34 |
35 | local function preprocess(data)
36 | local s = {}
37 | for at, value in pairs(data) do
38 | table.insert(s, {at=at, value=value})
39 | end
40 | table.sort(s, function(a, b) return a.at < b.at end)
41 | if s[1].at ~= 0 then
42 | table.insert(s, 1, {at=0, value=s[1].value})
43 | end
44 | if s[#s].at ~= 1 then
45 | table.insert(s, {at=1, value=s[#s].value})
46 | end
47 | return s
48 | end
49 |
50 | function System:set_sizes(sizes)
51 | self:clear_sizes()
52 | local s = preprocess(sizes)
53 | for _, data in ipairs(s) do
54 | if type(data.value) == 'table' then
55 | self:add_size(data.at, unpack(data.value))
56 | else
57 | self:add_size(data.at, data.value)
58 | end
59 | end
60 | end
61 |
62 | function System:set_colors(colors)
63 | self:clear_colors()
64 | local c = preprocess(colors)
65 | for _, data in ipairs(c) do
66 | local c1, c2 = data.value, data.value
67 | if type(data.value[1]) == 'table' or type(data.value[1]) == 'string' then
68 | c1 = data.value[1]
69 | c2 = data.value[2]
70 | end
71 | if type(c1) == 'string' then
72 | c1 = drystal.colors[c1]
73 | end
74 | if type(c2) == 'string' then
75 | c2 = drystal.colors[c2]
76 | end
77 | self:add_color(data.at, c1[1], c2[1], c1[2], c2[2], c1[3], c1[3])
78 | end
79 | end
80 |
81 | function System:set_alphas(alphas)
82 | self:clear_alphas()
83 | local a = preprocess(alphas)
84 | for _, data in ipairs(a) do
85 | if type(data.value) == 'table' then
86 | self:add_alpha(data.at, unpack(data.value))
87 | else
88 | self:add_alpha(data.at, data.value)
89 | end
90 | end
91 | end
92 |
93 |
--------------------------------------------------------------------------------
/tests/graphics/camera.lua:
--------------------------------------------------------------------------------
1 | local drystal = require 'drystal'
2 |
3 | if test == nil then
4 | test = false
5 | assert(drystal.camera.x == 0)
6 | assert(drystal.camera.y == 0)
7 | assert(drystal.camera.angle == 0)
8 | assert(drystal.camera.zoom == 1)
9 |
10 | assert(drystal.camera.blo == nil)
11 | drystal.camera.blo = "t"
12 | assert(drystal.camera.blo == "t")
13 | end
14 |
15 | function drystal.init()
16 | drystal.resize(600, 400)
17 | end
18 |
19 | local angle = 0
20 | local function setupcam()
21 | drystal.camera.reset()
22 | angle = angle + 0.01
23 | drystal.camera.zoom = 0.9
24 | drystal.camera.angle = angle
25 | drystal.camera.x = 300
26 | drystal.camera.y = 200
27 | end
28 |
29 | local mx, my = 0, 0
30 | local cx, cy = 0, 0
31 | function drystal.draw()
32 | drystal.set_color(0, 0, 0)
33 | drystal.draw_background()
34 |
35 | drystal.set_color(255, 255, 255)
36 | drystal.draw_circle(300, 200, 10)
37 |
38 | drystal.camera.push()
39 | drystal.camera.reset()
40 | drystal.set_color(255, 255, 255)
41 | drystal.draw_circle(300, 200, 10)
42 | drystal.camera.pop()
43 |
44 | drystal.camera.push()
45 | setupcam()
46 |
47 | local x1, y1 = drystal.screen2scene(100, 100)
48 | local x2, y2 = drystal.screen2scene(500, 100)
49 | local x3, y3 = drystal.screen2scene(500, 300)
50 | local x4, y4 = drystal.screen2scene(100, 300)
51 |
52 | drystal.set_color 'green'
53 | drystal.draw_circle(mx, my, 13/drystal.camera.zoom)
54 |
55 | drystal.set_color 'lime'
56 | drystal.camera.pop()
57 | drystal.camera.push()
58 | drystal.camera.reset()
59 | drystal.draw_line(x1, y1, x2, y2)
60 | drystal.draw_line(x2, y2, x3, y3)
61 | drystal.draw_line(x3, y3, x4, y4)
62 | drystal.draw_line(x4, y4, x1, y1)
63 | drystal.draw_circle(x1, y1, 10)
64 | drystal.set_color 'orange'
65 | drystal.draw_circle(x2, y2, 10)
66 | drystal.set_color 'chocolate'
67 | drystal.draw_circle(x3, y3, 10)
68 | drystal.set_color 'brown'
69 | drystal.draw_circle(x4, y4, 10)
70 | drystal.camera.pop()
71 |
72 | drystal.set_color 'blue'
73 | drystal.camera.push()
74 | drystal.camera.reset()
75 | drystal.draw_circle(cx, cy, 9)
76 | drystal.camera.pop()
77 | end
78 |
79 | function drystal.mouse_motion(x, y)
80 | drystal.camera.x = 300 - x
81 | drystal.camera.y = 200 - y
82 | drystal.camera.angle = drystal.camera.angle + math.pi/32
83 |
84 | mx = x
85 | my = y
86 |
87 | drystal.camera.push()
88 | setupcam()
89 | cx, cy = drystal.screen2scene(mx, my)
90 | drystal.camera.pop()
91 | end
92 |
93 | function drystal.key_press(k)
94 | if k == 'a' then
95 | drystal.stop()
96 | end
97 | end
98 |
99 |
--------------------------------------------------------------------------------
/src/util.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "macro.h"
29 |
30 | #define new(t, n) xmalloc(sizeof(t) * (n))
31 | #define new0(t, n) xcalloc((n), sizeof(t))
32 | #define newa(t, n) alloca(sizeof(t) * (n))
33 |
34 | #define XREALLOC(array, nmemb, need) \
35 | xrealloc((void **) &(array), &(nmemb), need, sizeof((array)[0]), 32)
36 |
37 | #define SWAP(a, b) { \
38 | typeof(a) _swaptmp = (a); \
39 | (a) = (b); \
40 | (b) = _swaptmp; \
41 | }
42 |
43 | #define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
44 | #define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m"
45 | #define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m"
46 | #define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m"
47 | #define ANSI_HIGHLIGHT_GRAY_ON "\x1B[1;90m"
48 | #define ANSI_HIGHLIGHT_PURPLE_ON "\x1B[1;35m"
49 | #define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;92m"
50 | #define ANSI_RESET "\x1B[0m"
51 |
52 | _malloc_ void *xmalloc(size_t size);
53 | _malloc_ void *xcalloc(size_t nmemb, size_t size);
54 | char *xstrdup(const char *s);
55 | int mkdir_p(const char *path);
56 | _sentinel_ char *strjoin(const char *s, ...);
57 | void msleep(unsigned long milisec);
58 | bool is_directory(const char *directory);
59 | bool files_are_same(const char *filea, const char *fileb);
60 | void *xrealloc(void **p, size_t *new_nmemb, size_t need, size_t size, unsigned min_nmemb);
61 | bool endswith(const char *s, const char *postfix);
62 | bool on_tty(int fd);
63 | bool stderr_use_colors(void);
64 |
65 | static inline bool startswith(const char *s, const char *prefix)
66 | {
67 | if (strncmp(s, prefix, strlen(prefix)) == 0) {
68 | return true;
69 | }
70 |
71 | return false;
72 | }
73 |
74 | static inline bool streq(const char *a, const char *b)
75 | {
76 | return strcmp(a, b) == 0;
77 | }
78 |
79 | #ifdef __cplusplus
80 | }
81 | #endif
82 |
83 |
--------------------------------------------------------------------------------
/src/physics/joint_bind.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include "lua_util.h"
20 |
21 | struct lua_State;
22 | class b2Joint;
23 |
24 | struct Joint {
25 | b2Joint* joint;
26 | Joint* nextdestroy;
27 | bool getting_destroyed;
28 | int ref;
29 | };
30 |
31 | typedef Joint RevoluteJoint;
32 | typedef Joint MouseJoint;
33 | typedef Joint DistanceJoint;
34 | typedef Joint RopeJoint;
35 | typedef Joint PrismaticJoint;
36 | typedef Joint GearJoint;
37 | typedef Joint FrictionJoint;
38 |
39 | DECLARE_PUSH(RopeJoint, rope_joint)
40 | DECLARE_PUSH(DistanceJoint, distance_joint)
41 | DECLARE_PUSH(RevoluteJoint, revolute_joint)
42 | DECLARE_PUSH(MouseJoint, mouse_joint)
43 | DECLARE_PUSH(PrismaticJoint, prismatic_joint)
44 | DECLARE_PUSH(GearJoint, gear_joint)
45 | DECLARE_PUSH(FrictionJoint, friction_joint)
46 |
47 | DECLARE_POP(Joint, joint)
48 | Joint* pop_joint_secure(lua_State* L, int index);
49 |
50 | int mlua_set_target_mouse_joint(lua_State* L);
51 |
52 | int mlua_set_length_distance_joint(lua_State* L);
53 | int mlua_set_frequency_distance_joint(lua_State* L);
54 |
55 | int mlua_set_max_length_rope_joint(lua_State* L);
56 |
57 | int mlua_set_angle_limits_revolute_joint(lua_State* L);
58 | int mlua_set_motor_speed_revolute_joint(lua_State* L);
59 |
60 | int mlua_set_enable_motor_prismatic_joint(lua_State* L);
61 | int mlua_set_motor_speed_prismatic_joint(lua_State* L);
62 | int mlua_set_enable_limit_prismatic_joint(lua_State* L);
63 | int mlua_set_max_motor_force_prismatic_joint(lua_State* L);
64 | int mlua_is_limit_enabled_prismatic_joint(lua_State* L);
65 | int mlua_is_motor_enabled_prismatic_joint(lua_State* L);
66 |
67 | int mlua_set_ratio_gear_joint(lua_State* L);
68 | int mlua_get_ratio_gear_joint(lua_State* L);
69 |
70 | int mlua_set_max_torque_friction_joint(lua_State* L);
71 | int mlua_get_max_torque_friction_joint(lua_State* L);
72 | int mlua_set_max_force_friction_joint(lua_State* L);
73 | int mlua_get_max_force_friction_joint(lua_State* L);
74 |
75 | int mlua_free_joint(lua_State* L);
76 |
--------------------------------------------------------------------------------
/tests/graphics/surface_manipulations.lua:
--------------------------------------------------------------------------------
1 | local drystal = require "drystal"
2 |
3 | local spritesheet = assert(drystal.fromjson(io.open('image.json'):read('*all')))
4 |
5 | vert = [[
6 | attribute vec2 position;
7 | attribute vec4 color;
8 | attribute vec2 texCoord;
9 |
10 | varying vec4 fColor;
11 | varying vec2 fTexCoord;
12 |
13 | uniform vec2 destinationSize;
14 | uniform vec2 sourceSize;
15 |
16 | #define pi ]]..math.pi..[[
17 |
18 | uniform float tick;
19 |
20 | float rand(vec2 co){
21 | return sin(dot(co.xy, vec2(12.9898,78.233)));
22 | }
23 |
24 | void main()
25 | {
26 | vec2 pos = (2. * position/destinationSize) - 1.;
27 | pos.x += rand(vec2(pos.x, tick/10.+100.)) * .01;
28 | pos.y += rand(vec2(pos.y, tick/10.)) * .01;
29 |
30 | gl_Position = vec4(pos, 0., 1.);
31 | fColor = color;
32 | fTexCoord = texCoord / sourceSize;
33 | }
34 | ]]
35 |
36 | local x = 0
37 | local y = 0
38 | local width = 0
39 | local height = 0
40 | local shader
41 |
42 | function drystal.init()
43 | drystal.resize(600, 400)
44 | image = assert(drystal.load_surface(spritesheet.meta.image))
45 | image:draw_from()
46 | drystal.set_alpha(0)
47 | surf = drystal.new_surface(64, 32)
48 | surf:draw_on()
49 | drystal.set_color(255, 0, 0)
50 | drystal.set_alpha(105)
51 | drystal.draw_rect(32, 0, 40, 40)
52 |
53 | drystal.set_color(200, 200, 200)
54 | drystal.set_alpha(255)
55 | local sprite = spritesheet.frames['character.png'].frame
56 | drystal.draw_sprite(sprite, 0, 0)
57 | drystal.screen:draw_on()
58 |
59 | shader = assert(drystal.new_shader(vert))
60 | end
61 |
62 | local tick = 0
63 | function drystal.update(dt)
64 | tick = tick + dt
65 | end
66 |
67 | function drystal.draw()
68 | image:draw_from()
69 | drystal.set_alpha(255)
70 | drystal.set_color(10, 10, 30)
71 | drystal.draw_background()
72 |
73 | shader:use()
74 | shader:feed('tick', tick)
75 | drystal.set_color(255, 0, 0)
76 | drystal.set_alpha(105)
77 | drystal.draw_rect(16, 64, 40, 40)
78 |
79 | local sprite = spritesheet.frames['character.png'].frame
80 | drystal.set_color(200, 200, 200)
81 | drystal.set_alpha(255)
82 | drystal.draw_sprite_rotated(sprite, 16, 16, math.sin(tick))
83 | drystal.use_default_shader()
84 |
85 | drystal.set_color(100, 0, 0)
86 | drystal.set_alpha(200)
87 | drystal.draw_sprite(sprite, 16+32, 16)
88 |
89 | drystal.set_color(255,255,255)
90 | drystal.set_alpha((math.sin(tick*5)/2+0.5)*255)
91 | surf:draw_from()
92 |
93 | drystal.draw_image(0, 0, 64, 32, 0, 256)
94 | end
95 |
96 | function drystal.key_press(key)
97 | if key == 'a' then
98 | drystal.stop()
99 | end
100 | end
101 |
102 | function drystal.key_release(key)
103 | end
104 |
105 | function drystal.mouse_motion(_x, _y)
106 | x = _x
107 | y = _y
108 | end
109 |
110 |
--------------------------------------------------------------------------------
/src/graphics/surface.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include
20 | #include
21 |
22 | #ifndef EMSCRIPTEN
23 | #include
24 | #else
25 | #include
26 | #endif
27 |
28 | typedef struct Surface Surface;
29 |
30 | enum FilterMode {
31 | FILTER_NEAREST = GL_NEAREST,
32 | FILTER_LINEAR = GL_LINEAR,
33 | FILTER_BILINEAR = GL_LINEAR_MIPMAP_NEAREST,
34 | FILTER_TRILINEAR = GL_LINEAR_MIPMAP_LINEAR,
35 |
36 | FILTER_DEFAULT = FILTER_LINEAR,
37 | };
38 | typedef enum FilterMode FilterMode;
39 |
40 | enum SurfaceFormat {
41 | FORMAT_LUMINANCE = GL_LUMINANCE,
42 | FORMAT_LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
43 | FORMAT_RGB = GL_RGB,
44 | FORMAT_RGBA = GL_RGBA,
45 | };
46 | typedef enum SurfaceFormat SurfaceFormat;
47 |
48 | struct Surface {
49 | char* filename;
50 | unsigned int w;
51 | unsigned int h;
52 | unsigned int texw;
53 | unsigned int texh;
54 | FilterMode filter;
55 | bool has_fbo;
56 | bool has_mipmap;
57 | bool npot;
58 | int ref;
59 |
60 | GLuint tex;
61 | GLuint fbo;
62 |
63 | unsigned char *pixels;
64 | bool pixels_valid;
65 | };
66 |
67 | Surface *surface_new(unsigned int w,
68 | unsigned int h,
69 | unsigned int texw,
70 | unsigned int texh,
71 | SurfaceFormat format,
72 | void *pixels,
73 | Surface *current_from,
74 | Surface *current_on);
75 | void surface_free(Surface *s);
76 | void surface_draw_on(Surface *s);
77 | void surface_draw_from(Surface *s);
78 | void surface_set_filter(Surface *s, FilterMode filter, Surface *current_surface);
79 | void surface_get_pixel(Surface *s, unsigned int x, unsigned int y,
80 | int *red, int *green, int *blue, int *alpha, Surface *current_on);
81 |
82 | static inline void surface_get_size(const Surface *s, unsigned int *w, unsigned int *h)
83 | {
84 | assert(w);
85 | assert(h);
86 | *w = s->w;
87 | *h = s->h;
88 | }
89 |
90 | int surface_load(const char* filename, Surface **surface, Surface *current_surface);
91 |
92 |
--------------------------------------------------------------------------------
/src/font/font_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 |
21 | #include "font.h"
22 | #include "font_bind.h"
23 | #include "lua_util.h"
24 |
25 | IMPLEMENT_PUSHPOP(Font, font)
26 |
27 | int mlua_draw_font(lua_State* L)
28 | {
29 | assert(L);
30 |
31 | Font* font = pop_font(L, 1);
32 | const char* text = luaL_checkstring(L, 2);
33 | lua_Number x = luaL_checknumber(L, 3);
34 | lua_Number y = luaL_checknumber(L, 4);
35 | Alignment alignment = (Alignment) luaL_optinteger(L, 5, ALIGN_LEFT);
36 | font_draw(font, text, x, y, alignment);
37 | return 0;
38 | }
39 |
40 | int mlua_draw_plain_font(lua_State* L)
41 | {
42 | assert(L);
43 |
44 | Font* font = pop_font(L, 1);
45 | const char* text = luaL_checkstring(L, 2);
46 | lua_Number x = luaL_checknumber(L, 3);
47 | lua_Number y = luaL_checknumber(L, 4);
48 | font_draw_plain(font, text, x, y);
49 | return 0;
50 | }
51 |
52 | int mlua_load_font(lua_State* L)
53 | {
54 | assert(L);
55 |
56 | const char* filename = luaL_checkstring(L, 1);
57 | lua_Number size = luaL_checknumber(L, 2);
58 | Font* font = font_load(filename, size, 32, 96);
59 | if (font) {
60 | push_font(L, font);
61 | return 1;
62 | }
63 | return luaL_fileresult(L, 0, filename);
64 | }
65 |
66 | int mlua_sizeof_font(lua_State* L)
67 | {
68 | assert(L);
69 |
70 | Font* font = pop_font(L, 1);
71 | const char* text = luaL_checkstring(L, 2);
72 | lua_Number w, h;
73 | font_get_textsize(font, text, &w, &h, -1);
74 | lua_pushnumber(L, w);
75 | lua_pushnumber(L, h);
76 | return 2;
77 | }
78 |
79 | int mlua_sizeof_plain_font(lua_State* L)
80 | {
81 | assert(L);
82 |
83 | Font* font = pop_font(L, 1);
84 | const char* text = luaL_checkstring(L, 2);
85 | lua_Number w, h;
86 | font_get_textsize_plain(font, text, &w, &h);
87 | lua_pushnumber(L, w);
88 | lua_pushnumber(L, h);
89 | return 2;
90 | }
91 |
92 | int mlua_free_font(lua_State* L)
93 | {
94 | assert(L);
95 |
96 | Font* font = pop_font(L, 1);
97 | font_free(font);
98 | return 0;
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR)
2 | project(drystal)
3 |
4 | set(DRYSTAL_VERSION "Drystal 1.1")
5 |
6 | set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
7 | include(Utils)
8 | include(CMakeDependentOption)
9 |
10 | check_compilers_unknown()
11 | check_git_submodules_initialized()
12 |
13 | option(BUILD_MANPAGES "Build manpages" ON)
14 | option(BUILD_ENABLE_COVERAGE "Enable code coverage" OFF)
15 | option(BUILD_PHYSICS "Enable physics module" ON)
16 | option(BUILD_WEB "Enable web module" ON)
17 | option(BUILD_AUDIO "Enable audio module" ON)
18 | option(BUILD_GRAPHICS "Enable graphics module" ON)
19 | option(BUILD_UTILS "Enable utils module" ON)
20 |
21 | cmake_dependent_option(BUILD_PARTICLE "Enable particle module (needs BUILD_GRAPHICS as dependency)" ON "BUILD_GRAPHICS" OFF)
22 | cmake_dependent_option(BUILD_STORAGE "Enable storage module (needs BUILD_UTILS as dependency)" ON "BUILD_UTILS" OFF)
23 | cmake_dependent_option(BUILD_FONT "Enable font module (needs BUILD_GRAPHICS as dependency)" ON "BUILD_GRAPHICS" OFF)
24 | cmake_dependent_option(BUILD_LIVECODING "Enable livecoding (available only on Linux)" ON "NOT EMSCRIPTEN" OFF)
25 |
26 | if(BUILD_LIVECODING AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
27 | message(FATAL_ERROR "Cannot enable BUILD_LIVECODING: Linux only")
28 | endif()
29 |
30 | if (EMSCRIPTEN)
31 | set(LINK_FLAGS "${LINK_FLAGS} -s TOTAL_MEMORY=67108864")
32 | set(LINK_FLAGS "${LINK_FLAGS} --memory-init-file 1")
33 | set(LINK_FLAGS "${LINK_FLAGS} -s NO_EXIT_RUNTIME=1")
34 | set(LINK_FLAGS "${LINK_FLAGS} -s ASM_JS=1")
35 | set(LINK_FLAGS "${LINK_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
36 |
37 | set(LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -s DISABLE_EXCEPTION_CATCHING=1")
38 | set(LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -s AGGRESSIVE_VARIABLE_ELIMINATION=1")
39 | set(LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -s ASSERTIONS=0")
40 |
41 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${LINK_FLAGS} ${LINK_FLAGS_RELEASE}")
42 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${LINK_FLAGS} ${LINK_FLAGS_RELEASE}")
43 | set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} ${LINK_FLAGS} ${LINK_FLAGS_RELEASE}")
44 | set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} ${LINK_FLAGS} ${LINK_FLAGS_RELEASE}")
45 | set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${LINK_FLAGS} ${LINK_FLAGS_DEBUG}")
46 | set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} ${LINK_FLAGS} ${LINK_FLAGS_DEBUG}")
47 | endif()
48 |
49 | if(BUILD_MANPAGES AND NOT EMSCRIPTEN)
50 | add_subdirectory(doc/man)
51 | endif()
52 | add_subdirectory(tools)
53 |
54 | add_subdirectory(external)
55 | add_subdirectory(src)
56 | add_subdirectory(misc/shell-completion/zsh/)
57 |
--------------------------------------------------------------------------------
/src/module.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | #include
24 |
25 | #define PUSH_FUNC(name, func) \
26 | lua_pushcfunction(L, mlua_##func); \
27 | lua_setfield(L, -2, name);
28 |
29 | #define DECLARE_MODULE(name) \
30 | void register_##name(lua_State* L);
31 |
32 | #define BEGIN_MODULE(name) \
33 | void register_##name(lua_State* L) {
34 | #define DECLARE_FUNCTION(name) \
35 | lua_pushcfunction(L, mlua_##name); \
36 | lua_setfield(L, -2, #name);
37 | #define DECLARE_BOOLEAN(name, value) \
38 | lua_pushboolean(L, value); \
39 | lua_setfield(L, -2, #name);
40 | #define END_MODULE() \
41 | }
42 |
43 | #define BEGIN_CLASS(name) \
44 | luaL_newmetatable(L, #name); \
45 | lua_pushliteral(L, #name); \
46 | lua_setfield(L, -2, "__type");
47 | #define ADD_GC(func) \
48 | PUSH_FUNC("__gc", func)
49 | #define ADD_METHOD(class, name) \
50 | PUSH_FUNC(#name, name##_##class)
51 | #define ADD_GETSET(class, name) \
52 | ADD_METHOD(class, get_##name) \
53 | ADD_METHOD(class, set_##name)
54 |
55 | #define REGISTER_CLASS(name, name_in_module) \
56 | lua_pushvalue(L, -1); \
57 | lua_setfield(L, -2, "__index"); \
58 | lua_setfield(L, -2, name_in_module);
59 |
60 | #define REGISTER_CLASS_WITH_INDEX(name, name_in_module) \
61 | PUSH_FUNC("__index", name##_class_index); \
62 | lua_setfield(L, -2, name_in_module);
63 |
64 | #define REGISTER_CLASS_WITH_INDEX_AND_NEWINDEX(name, name_in_module) \
65 | PUSH_FUNC("__index", name##_class_index); \
66 | PUSH_FUNC("__newindex", name##_class_newindex); \
67 | lua_setfield(L, -2, name_in_module);
68 |
69 | #define REGISTER_MODULE(name, L) \
70 | register_##name(L)
71 |
72 | #define DECLARE_CONSTANT_WITH_NAME(constant, constant_name) \
73 | lua_pushnumber(L, constant); \
74 | lua_setfield(L, -2, constant_name);
75 |
76 | #define BEGIN_ENUM() \
77 | lua_newtable(L);
78 | #define ADD_CONSTANT(name, value) \
79 | lua_pushnumber(L, value); \
80 | lua_setfield(L, -2, name);
81 | #define REGISTER_ENUM(name) \
82 | lua_setfield(L, -2, name);
83 |
84 | #define DECLARE_CONSTANT(constant) \
85 | DECLARE_CONSTANT_WITH_NAME(constant, #constant)
86 |
87 | #ifdef __cplusplus
88 | }
89 | #endif
90 |
91 |
--------------------------------------------------------------------------------
/src/graphics/buffer_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 |
21 | #include "display.h"
22 | #include "buffer_bind.h"
23 | #include "log.h"
24 |
25 | log_category("buffer");
26 |
27 | IMPLEMENT_PUSHPOP(Buffer, buffer)
28 |
29 | int mlua_new_buffer(lua_State* L)
30 | {
31 | assert(L);
32 |
33 | Buffer* buffer;
34 | if (lua_gettop(L) == 1) {
35 | lua_Integer size = luaL_checkinteger(L, 1);
36 | assert_lua_error(L, size > 0, "size should be positive");
37 | buffer = display_new_buffer(size);
38 | } else {
39 | buffer = display_new_auto_buffer(); // let Display choose a size
40 | }
41 | assert(buffer);
42 | push_buffer(L, buffer);
43 | return 1;
44 | }
45 |
46 | int mlua_use_buffer(lua_State* L)
47 | {
48 | assert(L);
49 |
50 | Buffer* buffer = pop_buffer(L, 1);
51 | assert_lua_error(L, !buffer_was_freed(buffer), "cannot use() a freed buffer");
52 | display_use_buffer(buffer);
53 | return 0;
54 | }
55 |
56 | int mlua_use_default_buffer(_unused_ lua_State* L)
57 | {
58 | display_use_default_buffer();
59 | return 0;
60 | }
61 |
62 | int mlua_draw_buffer(lua_State* L)
63 | {
64 | assert(L);
65 |
66 | Buffer* buffer = pop_buffer(L, 1);
67 | lua_Number dx = 0, dy = 0;
68 | if (lua_gettop(L) >= 2)
69 | dx = luaL_checknumber(L, 2);
70 | if (lua_gettop(L) >= 3)
71 | dy = luaL_checknumber(L, 3);
72 | display_draw_buffer(buffer, dx, dy);
73 | return 0;
74 | }
75 |
76 | int mlua_reset_buffer(lua_State* L)
77 | {
78 | assert(L);
79 |
80 | Buffer* buffer = pop_buffer(L, 1);
81 | assert_lua_error(L, !buffer_was_freed(buffer), "cannot reset() a freed buffer");
82 | buffer_reset(buffer);
83 | return 0;
84 | }
85 |
86 | int mlua_upload_and_free_buffer(lua_State* L)
87 | {
88 | assert(L);
89 |
90 | Buffer* buffer = pop_buffer(L, 1);
91 | assert_lua_error(L, !buffer_was_freed(buffer), "cannot upload_and_free() a freed buffer");
92 | buffer_upload_and_free(buffer);
93 | display_use_default_buffer();
94 | return 0;
95 | }
96 |
97 | int mlua_free_buffer(lua_State* L)
98 | {
99 | assert(L);
100 |
101 | Buffer* buffer = pop_buffer(L, 1);
102 | display_free_buffer(buffer);
103 | return 0;
104 | }
105 |
106 |
--------------------------------------------------------------------------------
/src/graphics/camera_bind.c:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option); any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #include
18 | #include
19 | #include
20 |
21 | #include "display.h"
22 | #include "camera_bind.h"
23 | #include "macro.h"
24 | #include "util.h"
25 | #include "lua_util.h"
26 |
27 | int mlua_camera__newindex(lua_State* L)
28 | {
29 | assert(L);
30 |
31 | const char * name = luaL_checkstring(L, 2);
32 | if (streq(name, "x")) {
33 | lua_Number dx = luaL_checknumber(L, 3);
34 | display_set_camera_position(dx, display_get_camera()->dy);
35 | } else if (streq(name, "y")) {
36 | lua_Number dy = luaL_checknumber(L, 3);
37 | display_set_camera_position(display_get_camera()->dx, dy);
38 | } else if (streq(name, "angle")) {
39 | lua_Number angle = luaL_checknumber(L, 3);
40 | display_set_camera_angle(angle);
41 | } else if (streq(name, "zoom")) {
42 | lua_Number zoom = luaL_checknumber(L, 3);
43 | display_set_camera_zoom(zoom);
44 | } else {
45 | lua_rawset(L, 1);
46 | }
47 |
48 | return 0;
49 | }
50 |
51 | int mlua_camera__index(lua_State* L)
52 | {
53 | assert(L);
54 |
55 | const char * name = luaL_checkstring(L, 2);
56 | if (streq(name, "x")) {
57 | lua_Number dx = display_get_camera()->dx;
58 | lua_pushnumber(L, dx);
59 | return 1;
60 | } else if (streq(name, "y")) {
61 | lua_Number dy = display_get_camera()->dy;
62 | lua_pushnumber(L, dy);
63 | return 1;
64 | } else if (streq(name, "angle")) {
65 | lua_Number angle = display_get_camera()->angle;
66 | lua_pushnumber(L, angle);
67 | return 1;
68 | } else if (streq(name, "zoom")) {
69 | lua_Number zoom = display_get_camera()->zoom;
70 | lua_pushnumber(L, zoom);
71 | return 1;
72 | }
73 | return 0;
74 | }
75 |
76 | int mlua_camera_reset(_unused_ lua_State *L)
77 | {
78 | display_reset_camera();
79 | return 0;
80 | }
81 |
82 | int mlua_camera_push(lua_State *L)
83 | {
84 | assert(L);
85 |
86 | assert_lua_error(L, !camera_stack_is_full(), "push: camera stack is full");
87 |
88 | display_push_camera();
89 | return 0;
90 | }
91 |
92 | int mlua_camera_pop(lua_State *L)
93 | {
94 | assert(L);
95 |
96 | assert_lua_error(L, !camera_stack_is_empty(), "push: camera stack is empty");
97 |
98 | display_pop_camera();
99 | return 0;
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/external/wavloader.c:
--------------------------------------------------------------------------------
1 | /* wavloader - public domain wav loader no warranty implied; use at your own risk
2 | * written in 2013 by kidanger
3 | * rewritten in 2014 by Ronny Chevalier
4 | */
5 | #ifndef WAVLOADER_INCLUDE
6 | #define WAVLOADER_INCLUDE
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 | #include
12 |
13 | struct wave_header {
14 | char header_id[4];
15 | uint32_t chunk_size;
16 | char format[4];
17 | char format_id[4];
18 | uint32_t format_size;
19 | uint16_t audio_format;
20 | uint16_t num_channels;
21 | uint32_t sample_rate;
22 | uint32_t byte_rate;
23 | uint16_t block_align;
24 | uint16_t bits_per_sample;
25 | char data_id[4];
26 | uint32_t data_size;
27 | };
28 |
29 | int load_wav(const char *filename, struct wave_header *wave_header, void **audio_data);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 |
35 | #endif // WAVLOADER_INCLUDE
36 |
37 | #ifndef WAVLOADER_HEADER_ONLY
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 | #include
42 | #include
43 | #include
44 | #include
45 |
46 | int load_wav(const char *filename, struct wave_header *wave_header, void **audio_data)
47 | {
48 | /* see https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
49 | FILE *file;
50 | void *tmp_buffer = NULL;
51 | int ret = 0;
52 | size_t r;
53 | long filesize;
54 |
55 | if (!filename || !wave_header || !audio_data) {
56 | return -EINVAL;
57 | }
58 |
59 | file = fopen(filename, "rb");
60 | if (!file) {
61 | return -errno;
62 | }
63 |
64 | r = fread(wave_header, sizeof(struct wave_header), 1, file);
65 | if (r != 1) {
66 | ret = -EIO;
67 | goto fail;
68 | }
69 |
70 | if (strncmp(wave_header->header_id, "RIFF", 4)) {
71 | ret = -ENOTSUP;
72 | goto fail;
73 | }
74 | if (strncmp(wave_header->format, "WAVE", 4)) {
75 | ret = -ENOTSUP;
76 | goto fail;
77 | }
78 | if (strncmp(wave_header->format_id, "fmt", 3)) {
79 | ret = -ENOTSUP;
80 | goto fail;
81 | }
82 | if (strncmp(wave_header->data_id, "data", 4)) {
83 | ret = -ENOTSUP;
84 | goto fail;
85 | }
86 | if (wave_header->format_size != 16) {
87 | ret = -ENOTSUP;
88 | goto fail;
89 | }
90 | if (wave_header->audio_format != 1) {
91 | ret = -ENOTSUP;
92 | goto fail;
93 | }
94 |
95 | fseek(file, 0L, SEEK_END);
96 | filesize = ftell(file);
97 | fseek(file, sizeof(struct wave_header), SEEK_SET);
98 |
99 | if (wave_header->data_size != filesize - sizeof(struct wave_header)) {
100 | ret = -EIO;
101 | goto fail;
102 | }
103 |
104 | tmp_buffer = malloc(wave_header->data_size);
105 | if (!tmp_buffer) {
106 | ret = -ENOMEM;
107 | goto fail;
108 | }
109 |
110 | r = fread(tmp_buffer, wave_header->data_size, 1, file);
111 | if (r != 1) {
112 | ret = -EIO;
113 | goto fail;
114 | }
115 |
116 | *audio_data = tmp_buffer;
117 | fclose(file);
118 |
119 | return ret;
120 | fail:
121 | free(tmp_buffer);
122 | fclose(file);
123 |
124 | return ret;
125 | }
126 | #ifdef __cplusplus
127 | }
128 | #endif
129 | #endif
130 |
131 |
--------------------------------------------------------------------------------
/src/particle/system.h:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Drystal.
3 | *
4 | * Drystal is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Lesser General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * Drystal is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public License
15 | * along with Drystal. If not, see .
16 | */
17 | #pragma once
18 |
19 | #include // random
20 |
21 | typedef struct Color Color;
22 | typedef struct Size Size;
23 | typedef struct Alpha Alpha;
24 | typedef struct System System;
25 |
26 | #include "graphics/surface.h"
27 | #include "particle.h"
28 |
29 | #define RAND(a, b) (((float) rand()/RAND_MAX) * ((b) - (a)) + (a))
30 |
31 | #define MAX_COLORS 16
32 | struct Color {
33 | float at;
34 | unsigned char min_r, max_r;
35 | unsigned char min_g, max_g;
36 | unsigned char min_b, max_b;
37 | };
38 |
39 | #define MAX_SIZES 16
40 | struct Size {
41 | float at;
42 | float min, max;
43 | };
44 |
45 | #define MAX_ALPHAS 16
46 | struct Alpha {
47 | float at;
48 | float min, max;
49 | };
50 |
51 | struct System {
52 | Particle* particles;
53 |
54 | int cur_size;
55 | Size sizes[MAX_SIZES];
56 |
57 | int cur_color;
58 | Color colors[MAX_COLORS];
59 |
60 | int cur_alpha;
61 | Alpha alphas[MAX_ALPHAS];
62 |
63 | Surface* texture;
64 | bool running;
65 |
66 | size_t size;
67 | size_t used;
68 |
69 | float x, y;
70 | float offx, offy;
71 |
72 | float min_direction, max_direction;
73 | float min_lifetime, max_lifetime;
74 |
75 | float min_initial_acceleration, max_initial_acceleration;
76 | float min_initial_velocity, max_initial_velocity;
77 |
78 | float emission_rate;
79 | float emit_counter;
80 |
81 | int sprite_x;
82 | int sprite_y;
83 |
84 | int ref;
85 | };
86 |
87 | System *system_new(float x, float y, size_t size);
88 | System *system_clone(System* s);
89 | void system_free(System *s);
90 |
91 | void system_start(System *s);
92 | void system_stop(System *s);
93 | void system_reset(System *s);
94 | void system_draw(System *s, float dx, float dy);
95 | void system_emit(System *s);
96 | void system_update(System *s, float dt);
97 | void system_add_size(System *s, float at, float min, float max);
98 | void system_add_color(System *s, float at, unsigned char min_r, unsigned char max_r, unsigned char min_g, unsigned char max_g, unsigned char min_b, unsigned char max_b);
99 | void system_add_alpha(System *s, float at, float min, float max);
100 | void system_clear_sizes(System *s);
101 | void system_clear_colors(System *s);
102 | void system_clear_alphas(System *s);
103 | void system_set_texture(System* s, Surface* tex, float x, float y);
104 |
105 |
--------------------------------------------------------------------------------