├── .gitignore ├── LICENSE ├── README.md ├── build.py ├── cembed.py ├── doc ├── building.md └── packaging.md ├── example ├── particles │ ├── config.lua │ ├── data │ │ └── image │ │ │ └── particle.png │ └── main.lua ├── tronic │ ├── config.lua │ └── main.lua └── xytone │ ├── config.lua │ └── main.lua └── src ├── embed ├── buffer.lua ├── debug.lua ├── font.ttf ├── graphics.lua ├── init.lua ├── keyboard.lua ├── mouse.lua └── time.lua ├── fs.c ├── fs.h ├── lib ├── jo_gif.c ├── lextlib_lua52.h ├── lua51 │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lcode.c │ ├── lcode.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.h │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── miniz.c ├── sera │ ├── sera.c │ └── sera.h ├── stb_image.h ├── stb_truetype.h ├── stb_vorbis.c └── vec │ ├── vec.c │ └── vec.h ├── luax.h ├── m_audio.c ├── m_buffer.c ├── m_buffer.h ├── m_bufferfx.c ├── m_data.c ├── m_data.h ├── m_font.c ├── m_fs.c ├── m_gif.c ├── m_graphics.c ├── m_juno.c ├── m_mouse.c ├── m_source.c ├── m_source.h ├── m_system.c ├── m_time.c ├── main.c ├── ttf.c ├── ttf.h ├── util.h ├── wav.c └── wav.h /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .tempsrc/ 3 | *.swp 4 | *.tmp 5 | *.pyc 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2015 rxi 3 | 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | 24 | =============================================================================== 25 | 26 | The project also includes 3rd party source files, the full licenses for these 27 | files can be found through their corresponding URL or in the files themselves. 28 | An overview of the source files are as follows: 29 | 30 | src/lib/lua51/* 31 | . Lua5.1 32 | . MIT license 33 | . http://www.lua.org/ 34 | 35 | src/lib/lextlib_lua52.h 36 | . Lua Extension Library header file for lua5.2 C API -> Lua5.1 37 | . MIT license 38 | . https://github.com/devurandom/lextlib/ 39 | 40 | src/lib/stb_image.h 41 | . Sean Barrett's image loading library 42 | . Public domain 43 | . https://github.com/nothings/stb 44 | 45 | src/lib/stb_truetype.h 46 | . Sean Barrett's true type font library 47 | . Public domain 48 | . https://github.com/nothings/stb 49 | 50 | src/lib/stb_vorbis.c 51 | . Sean Barrett's vorbis library 52 | . Public domain 53 | . https://github.com/nothings/stb 54 | 55 | src/lib/jo_gif.c 56 | . Jon Olick's minimalistic GIF writer 57 | . Public domain 58 | . http://www.jonolick.com/home/gif-writer 59 | 60 | src/lib/miniz.c 61 | . A lossless, high performance data compression library 62 | . Public domain 63 | . https://code.google.com/p/miniz/ 64 | 65 | src/lib/vec/* 66 | . Dynamic array implementation 67 | . MIT license 68 | . https://github.com/rxi/vec 69 | 70 | src/lib/sera/* 71 | . 2d software graphics lib 72 | . MIT license 73 | . https://github.com/rxi/sera 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Juno 2 | A tiny framework for making 2D games with chunky pixels in Lua. 3 | 4 | ![16007-shot1-1429493941](https://cloud.githubusercontent.com/assets/3920290/7380205/40f2b7e4-edf2-11e4-8ba1-3ed89c22aa9c.gif) 5 | 6 | # License 7 | This library is free software; you can redistribute it and/or modify it under 8 | the terms of the MIT license. See [LICENSE](LICENSE) for details. 9 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.7 2 | import os, sys, shutil, platform, time 3 | import cembed 4 | 5 | OUTPUT = "bin/juno" 6 | EMBED_DIR = "src/embed" 7 | TEMPSRC_DIR = ".tempsrc" 8 | COMPILER = "gcc" 9 | INCLUDE = [ TEMPSRC_DIR ] 10 | SOURCE = [ 11 | "src/*.c", 12 | "src/lib/sera/*.c", 13 | "src/lib/vec/*.c", 14 | "src/lib/stb_vorbis.c" 15 | ] 16 | FLAGS = [ "-Wall", "-Wextra", "--std=gnu99", "-fno-strict-aliasing" ] 17 | LINK = [ "m" ] 18 | DEFINE = [ ] 19 | EXTRA = "" 20 | 21 | if platform.system() == "Windows": 22 | OUTPUT += ".exe" 23 | LINK += [ "mingw32", "lua51", "SDLmain", "SDL" ] 24 | FLAGS += [ "-mwindows" ] 25 | 26 | if platform.system() == "Linux": 27 | LINK += [ "luajit-5.1", "SDLmain", "SDL" ] 28 | 29 | if platform.system() == "Darwin": 30 | LINK += [ "luajit-5.1" ] 31 | FLAGS += [ "-pagezero_size 10000", "-image_base 100000000" ] 32 | FLAGS += [ os.popen("sdl-config --cflags").read().strip() ] 33 | EXTRA += os.popen("sdl-config --libs").read().strip() 34 | DEFINE += [ "SR_MODE_ARGB" ] 35 | 36 | 37 | def fmt(fmt, dic): 38 | for k in dic: 39 | fmt = fmt.replace("{" + k + "}", str(dic[k])) 40 | return fmt 41 | 42 | 43 | def clearup(): 44 | if os.path.exists(TEMPSRC_DIR): 45 | shutil.rmtree(TEMPSRC_DIR) 46 | 47 | 48 | def main(): 49 | global FLAGS, SOURCE, LINK 50 | 51 | print "initing..." 52 | starttime = time.time() 53 | 54 | # Handle args 55 | build = "debug" if "debug" in sys.argv else "release" 56 | verbose = "verbose" in sys.argv 57 | 58 | # Handle build type 59 | if build == "debug": 60 | FLAGS += [ "-g" ] 61 | else: 62 | FLAGS += [ "-O3" ] 63 | 64 | # Handle "nojit" option -- compile with normal embedded Lua instead 65 | if "nojit" in sys.argv: 66 | LINK = filter(lambda x:"lua" not in x, LINK) 67 | SOURCE += ["src/lib/lua51/*.c"] 68 | 69 | print "building (" + build + ")..." 70 | 71 | # Make sure there arn't any temp files left over from a previous build 72 | clearup() 73 | 74 | # Create directories 75 | os.makedirs(TEMPSRC_DIR) 76 | outdir = os.path.dirname(OUTPUT) 77 | if not os.path.exists(outdir): 78 | os.makedirs(outdir) 79 | 80 | # Create embedded-file header files 81 | for filename in os.listdir(EMBED_DIR): 82 | fullname = EMBED_DIR + "/" + filename 83 | res = cembed.process(fullname) 84 | open(TEMPSRC_DIR + "/" + cembed.safename(fullname) + ".h", "wb").write(res) 85 | 86 | # Build 87 | cmd = fmt( 88 | "{compiler} -o {output} {flags} {source} {include} {link} {define} " + 89 | "{extra}", 90 | { 91 | "compiler" : COMPILER, 92 | "output" : OUTPUT, 93 | "source" : " ".join(SOURCE), 94 | "include" : " ".join(map(lambda x:"-I" + x, INCLUDE)), 95 | "link" : " ".join(map(lambda x:"-l" + x, LINK)), 96 | "define" : " ".join(map(lambda x:"-D" + x, DEFINE)), 97 | "flags" : " ".join(FLAGS), 98 | "extra" : EXTRA, 99 | }) 100 | 101 | if verbose: 102 | print cmd 103 | 104 | print "compiling..." 105 | res = os.system(cmd) 106 | 107 | if build == "release": 108 | print "stripping..." 109 | os.system("strip %s" % OUTPUT) 110 | 111 | print "clearing up..." 112 | clearup() 113 | 114 | if res == 0: 115 | print "done (%.2fs)" % (time.time() - starttime) 116 | else: 117 | print "done with errors" 118 | sys.exit(res) 119 | 120 | 121 | if __name__ == "__main__": 122 | main() 123 | 124 | -------------------------------------------------------------------------------- /cembed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.7 2 | import os, sys, random, re 3 | 4 | def fmt(fmt, dic): 5 | for k in dic: 6 | fmt = fmt.replace("{%s}" % k, str(dic[k])) 7 | return fmt 8 | 9 | 10 | def makeArray(data): 11 | i = [0] 12 | def fn(x): 13 | x = str(ord(x)) + "," 14 | if i[0] + len(x) > 78: 15 | i[0] = len(x) 16 | x = '\n' + x 17 | else: 18 | i[0] += len(x) 19 | return x 20 | return '{' + "".join(map(fn, data)).rstrip(",") + '}' 21 | 22 | 23 | def safename(filename): 24 | return re.sub("[^a-z0-9]", "_", os.path.basename(filename).lower()) 25 | 26 | 27 | def process(filenames): 28 | if type(filenames) is str: 29 | filenames = [filenames] 30 | 31 | strings = [] 32 | 33 | for filename in filenames: 34 | data = open(filename, "rb").read() 35 | strings.append( 36 | fmt("/* {filename} */\n" +\ 37 | "static const char {name}[] = \n{array};", 38 | { 39 | "filename" : os.path.basename(filename), 40 | "name" : safename(filename), 41 | "array" : makeArray(data), 42 | })) 43 | 44 | return "/* Automatically generated; do not edit */\n\n" +\ 45 | "\n\n".join(strings) 46 | 47 | 48 | def main(): 49 | if len(sys.argv) < 2: 50 | print "usage: embed FILENAMES" 51 | sys.exit(1) 52 | 53 | print process(sys.argv[1:]) 54 | 55 | 56 | if __name__ == "__main__": 57 | main() 58 | -------------------------------------------------------------------------------- /doc/building.md: -------------------------------------------------------------------------------- 1 | # Building Juno 2 | 3 | ## Requirements 4 | * `gcc` or `clang` is used to compile 5 | * `SDL1.2` is linked to dynamically 6 | * `LuaJIT` is linked to dynamically, although this is optional as non-JIT Lua can be used in its place 7 | * `Python2.7` is used by the build script 8 | 9 | These dependencies must be met before building. 10 | 11 | ## Building 12 | Juno can be built on Linux, Windows and OS X. To build you should first clone the repo and cd into it 13 | ```bash 14 | git clone https://github.com/rxi/juno.git 15 | cd juno 16 | ``` 17 | 18 | The build script should then be executed: 19 | ```bash 20 | ./build.py 21 | ``` 22 | 23 | On windows: 24 | ```bash 25 | build.py 26 | ``` 27 | 28 | When the build is finished an executable named `juno` (or `juno.exe` on windows) should exist in the `bin/` directory. 29 | 30 | You can test it works by executing one of the example projects: 31 | ```bash 32 | ./bin/juno example/particles 33 | ``` 34 | 35 | On windows: 36 | ```bash 37 | bin/juno example/particles 38 | ``` 39 | 40 | 41 | ## Build options 42 | The following arguments can be passed to the `build.py` script: 43 | * `debug` - compiles unoptimized and doesn't strip debug symbols 44 | * `nojit` - uses embedded Lua instead of linking to LuaJIT 45 | -------------------------------------------------------------------------------- /doc/packaging.md: -------------------------------------------------------------------------------- 1 | # Packaging a Juno game for distribution 2 | 3 | To package your game for distribution, you should create a zip archive containing the game's source code and assets. The game's `main.lua` file should be at the root of this archive. 4 | 5 | The zip file should be renamed to `pak0` (with no extension) and placed in the same directory as the Juno executable. When Juno runs it will search for the `pak0` file and load it if it exists. 6 | 7 | The dynamically linked libraries should also be included when distributing your game. On Windows these are `SDL.dll` and `lua51.dll`. The Juno executable can be renamed to the title of your game. This should result in the following files: 8 | 9 | ``` 10 | game_title.exe (juno executable) 11 | pak0 (zip archive of game) 12 | lua51.dll 13 | SDL.dll 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /example/particles/config.lua: -------------------------------------------------------------------------------- 1 | 2 | G = { 3 | width = 200, 4 | height = 120, 5 | scale = 3, 6 | } 7 | 8 | return { 9 | title = "Particles", 10 | width = G.width * G.scale, 11 | height = G.height * G.scale, 12 | } 13 | -------------------------------------------------------------------------------- /example/particles/data/image/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxi/juno/982d9bf91c8354b60eb9c4f49c1192238b2bef95/example/particles/data/image/particle.png -------------------------------------------------------------------------------- /example/particles/main.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | function juno.onLoad(dt) 4 | juno.debug.setVisible(true) 5 | G.screen = juno.Buffer.fromBlank(G.width, G.height) 6 | G.particle = juno.Buffer.fromFile("data/image/particle.png") 7 | G.particles = {} 8 | for i = 0, 200 do 9 | table.insert(G.particles, { 10 | x = 0, 11 | y = 0, 12 | vx = 0, 13 | vy = 0, 14 | t = 0, 15 | a = 0, 16 | s = math.random(), 17 | }) 18 | end 19 | end 20 | 21 | 22 | function juno.onUpdate(dt) 23 | for i, p in ipairs(G.particles) do 24 | p.x = p.x + p.vx * dt 25 | p.y = p.y + p.vy * dt 26 | if p.t > 0 then 27 | p.t = p.t - dt 28 | else 29 | p.a = p.a - dt * 3 30 | if p.a < 0 then 31 | local r = math.random() * math.pi * 2 32 | p.x = math.cos(r) * 20 33 | p.y = math.sin(r) * 20 34 | p.vx = (1 - math.random() * 2) * 90 35 | p.vy = (1 - math.random() * 2) * 90 36 | p.t = math.random() * 1 37 | p.a = 1 38 | end 39 | end 40 | end 41 | end 42 | 43 | 44 | function juno.onDraw() 45 | G.screen:clear(0, 0, 0, 1) 46 | G.screen:setBlend("add") 47 | G.screen:setColor(.2, .4, 1) 48 | for i, p in ipairs(G.particles) do 49 | G.screen:setAlpha(p.a) 50 | G.screen:draw(G.particle, G.width / 2 + p.x, G.height / 2 + p.y, 51 | nil, 0, p.s, p.s, 16, 16) 52 | end 53 | juno.graphics.copyPixels(G.screen, 0, 0, nil, G.scale) 54 | end 55 | -------------------------------------------------------------------------------- /example/tronic/config.lua: -------------------------------------------------------------------------------- 1 | 2 | G = { 3 | width = 120, 4 | height = 80, 5 | scale = 4, 6 | } 7 | 8 | return { 9 | title = "Tronic", 10 | width = G.width * G.scale, 11 | height = G.height * G.scale, 12 | } 13 | -------------------------------------------------------------------------------- /example/tronic/main.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | function juno.onLoad(dt) 4 | G.field = juno.Buffer.fromBlank(G.width, G.height) 5 | G.field:drawBox(0, 0, G.width, G.height) 6 | G.tickTimer = 0 7 | -- Initialise player 8 | G.player = { 9 | x = 20, 10 | y = G.height / 2, 11 | direction = "down", 12 | color = { 1, 1, 1 }, 13 | } 14 | -- Initialise AIs 15 | G.ai = {} 16 | for i = 1, 3 do 17 | table.insert(G.ai, { 18 | x = ((G.width - 40) / 3) * i + 20, 19 | y = G.height / 2, 20 | dead = false, 21 | direction = "down", 22 | turnTimer = 0, 23 | turnRate = 10 + math.random(20), 24 | color = ({ { 1, 0, 0 }, { 0, 1, 1 }, { 1, 1, 0 } })[i], 25 | }) 26 | end 27 | end 28 | 29 | 30 | function juno.onKeyDown(k) 31 | -- Handle player movement keys 32 | if k == "left" or k == "up" or k == "down" or k == "right" then 33 | G.player.direction = k 34 | end 35 | -- Handle game restart key 36 | if k == "r" then 37 | juno.onLoad() 38 | end 39 | end 40 | 41 | 42 | local function isPixelBlack(x, y) 43 | local r, g, b = G.field:getPixel(x, y) 44 | return r == 0 and g == 0 and b == 0 45 | end 46 | 47 | 48 | local function nextPosition(bike, steps) 49 | steps = steps or 1 50 | return ({ 51 | left = function() return bike.x - steps, bike.y end, 52 | right = function() return bike.x + steps, bike.y end, 53 | up = function() return bike.x, bike.y - steps end, 54 | down = function() return bike.x, bike.y + steps end, 55 | })[bike.direction]() 56 | end 57 | 58 | 59 | local function randomDirection() 60 | return ({ "left", "right", "up", "down" })[math.random(4)] 61 | end 62 | 63 | 64 | local function updateAi(ai, dt) 65 | -- Do random turn timer and random turn 66 | ai.turnTimer = ai.turnTimer - 1 67 | if ai.turnTimer <= 0 then 68 | ai.turnTimer = math.random(ai.turnRate) 69 | ai.direction = randomDirection() 70 | end 71 | -- Do obstacle avoidance 72 | for lookahead = 4, 1, -1 do 73 | for i = 1, 8 do 74 | if not isPixelBlack(nextPosition(ai, lookahead)) then 75 | ai.direction = randomDirection() 76 | end 77 | end 78 | end 79 | end 80 | 81 | 82 | local function updateBike(bike) 83 | -- Don't update the bike if its dead 84 | if bike.dead then 85 | return 86 | end 87 | -- Move bike 88 | bike.x, bike.y = nextPosition(bike) 89 | -- Kill the bike if it collided with something 90 | if not isPixelBlack(bike.x, bike.y) then 91 | bike.dead = true 92 | return 93 | end 94 | -- Draw bike 95 | G.field:setPixel(bike.x, bike.y, unpack(bike.color)) 96 | end 97 | 98 | 99 | local function onTick() 100 | -- Update AIs 101 | for i, ai in ipairs(G.ai) do 102 | updateAi(ai) 103 | updateBike(ai) 104 | end 105 | -- Update player 106 | updateBike(G.player) 107 | end 108 | 109 | 110 | function juno.onUpdate(dt) 111 | -- Update tick timer 112 | G.tickTimer = G.tickTimer - dt 113 | while G.tickTimer <= 0 do 114 | onTick() 115 | G.tickTimer = G.tickTimer + .03 116 | end 117 | -- Player is dead? Restart the game 118 | if G.player.dead then 119 | juno.onLoad() 120 | end 121 | end 122 | 123 | 124 | function juno.onDraw() 125 | juno.graphics.copyPixels(G.field, 0, 0, nil, G.scale) 126 | end 127 | -------------------------------------------------------------------------------- /example/xytone/config.lua: -------------------------------------------------------------------------------- 1 | return { 2 | title = "xytone", 3 | width = 600, 4 | height = 600, 5 | } 6 | -------------------------------------------------------------------------------- /example/xytone/main.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | function juno.onLoad() 4 | juno.debug.setVisible(true) 5 | 6 | vis = {} 7 | freq = 0 8 | gain = 0 9 | 10 | local delay = { idx = 0, max = 44100 * .4 } 11 | local phase = 0 12 | local xfreq = 0 13 | local xgain = 0 14 | 15 | juno.audio.master:setCallback(function(t) 16 | -- Clear visualisation table 17 | for i in ipairs(vis) do 18 | vis[i] = nil 19 | end 20 | -- Process audio 21 | for i = 1, #t, 2 do 22 | local dt = 1 / 44100 23 | -- Interp freq and gain (to avoid audible "steps" on high buffer size) 24 | xfreq = xfreq + (freq - xfreq) * .005 25 | xgain = xgain + (gain - xgain) * .005 26 | -- Increment phase 27 | phase = phase + dt * xfreq 28 | -- Generate sinewave 29 | local out = math.sin(phase * math.pi * 2) 30 | -- Apply gain 31 | out = out * xgain * .5 32 | -- Process delay 33 | out = out + (delay[delay.idx] or 0) * .5 34 | delay[delay.idx] = out 35 | delay.idx = (delay.idx + 1) % delay.max 36 | -- Write visualisation 37 | table.insert(vis, out) 38 | -- Write output 39 | t[i], t[i + 1] = out, out 40 | end 41 | end) 42 | end 43 | 44 | 45 | function juno.onMouseMove(x, y) 46 | gain = math.pow(1 - (y / juno.graphics.getWidth()), 1.8) 47 | freq = math.pow(x / juno.graphics.getHeight(), 2) * 3000 + 120 48 | end 49 | 50 | 51 | function juno.onDraw() 52 | -- Draw waveform 53 | juno.graphics.setColor(.7, .7, .7) 54 | local w, h = juno.graphics.getSize() 55 | local lastx, lasty 56 | for i, v in ipairs(vis) do 57 | local x, y = (i / #vis) * w, h / 2 + v * 100 58 | if i ~= 1 then 59 | juno.graphics.drawLine(lastx, lasty, x, y) 60 | end 61 | lastx, lasty = x, y 62 | end 63 | -- Draw x/y lines and info text 64 | juno.graphics.reset() 65 | local x, y = juno.mouse.getPosition() 66 | juno.graphics.drawLine(x, 0, x, juno.graphics.getHeight()) 67 | juno.graphics.drawLine(0, y, juno.graphics.getWidth(), y) 68 | juno.graphics.drawText(string.format("freq: %.2fhz\ngain: %.2f", 69 | freq, gain), x + 10, y + 10) 70 | end 71 | -------------------------------------------------------------------------------- /src/embed/buffer.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | local function checkArg(idx, cond, msg) 10 | if not cond then 11 | error("bad argument #" .. idx .. ", " .. msg, 3) 12 | end 13 | end 14 | 15 | 16 | function juno.Buffer:getSize() 17 | return self:getWidth(), self:getHeight() 18 | end 19 | 20 | 21 | local defaultFont = juno.Font.fromEmbedded() 22 | 23 | local fontTexCache = {} 24 | setmetatable(fontTexCache, { 25 | __index = function(t, k) 26 | fontTexCache[k] = {} 27 | return fontTexCache[k] 28 | end, 29 | __mode = "v", 30 | }) 31 | 32 | function juno.Buffer:drawText(font, text, x, y, width) 33 | if type(font) ~= "userdata" then 34 | return self:drawText(defaultFont, font, text, x, y, width) 35 | end 36 | checkArg(3, x == nil or type(x) == "number", "expected number") 37 | checkArg(4, y == nil or type(y) == "number", "expected number") 38 | checkArg(5, width == nil or type(width) == "number", "expected number") 39 | text = tostring(text) 40 | if width then 41 | -- Word wrapped multi line 42 | local height = font:getHeight() 43 | local line 44 | for word in text:gmatch("%S+") do 45 | local tmp = (line and (line .. " ") or "") .. word 46 | if font:getWidth(tmp) > width then 47 | juno.graphics.drawText(font, line, x, y) 48 | y = y + height 49 | line = word 50 | else 51 | line = tmp 52 | end 53 | end 54 | self:drawText(font, line, x, y) 55 | elseif text:find("\n") then 56 | -- Multi line 57 | local height = font:getHeight() 58 | for line in (text.."\n"):gmatch("(.-)\n") do 59 | self:drawText(font, line, x, y) 60 | y = y + height 61 | end 62 | else 63 | -- Single line 64 | local tex = fontTexCache[font][text] 65 | if not tex then 66 | tex = font:render(text) 67 | fontTexCache[font][text] = tex 68 | end 69 | self:drawBuffer(tex, x, y) 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /src/embed/debug.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | juno.debug = juno.debug or {} 10 | 11 | local font 12 | local inited = false 13 | local enabled = false 14 | local focused = false 15 | local indicators = {} 16 | local lines = {} 17 | local inputbuf = "" 18 | 19 | -- Override print 20 | local _print = print 21 | print = function(...) 22 | _print(...) 23 | -- Convert all arguments to string and store in table 24 | local t = {} 25 | for i = 1, select("#", ...) do 26 | t[#t + 1] = tostring(select(i, ...)) 27 | end 28 | local str = table.concat(t, " ") 29 | -- Multiple lines? Split and insert, else just insert the string 30 | if str:match("\n") then 31 | for line in (str .. "\n"):gmatch("(.-)\n") do 32 | table.insert(lines, line) 33 | end 34 | else 35 | table.insert(lines, str) 36 | end 37 | while #lines > 6 do 38 | table.remove(lines, 1) 39 | end 40 | end 41 | 42 | 43 | local indicatorIdx 44 | local textRegionWidth = 20 45 | 46 | local function newIndicator(fn, min, max) 47 | min = min or 0 48 | max = max or 0 49 | local trueMin, trueMax = min, max 50 | -- Get idx 51 | indicatorIdx = indicatorIdx and (indicatorIdx + 1) or 0 52 | -- Init 53 | local pad = 8 54 | local height = 26 55 | local maxBars = 16 56 | local barUpdatePeriod = 1 57 | local yoffset = pad + height * indicatorIdx 58 | local lastUpdate = juno.time.getNow() 59 | local bars = {} 60 | local lastMin = min 61 | local lastMax = max 62 | -- Fill bars with zeros 63 | for i = 1, maxBars do 64 | bars[i] = 0 65 | end 66 | -- Return draw function 67 | return function() 68 | local txt, val = fn() 69 | -- Resize text region? 70 | textRegionWidth = math.max(font:getWidth(txt) + 8, textRegionWidth) 71 | -- Update bars? 72 | if juno.time.getNow() > lastUpdate + barUpdatePeriod then 73 | table.remove(bars) 74 | table.insert(bars, 1, val) 75 | min = math.min(trueMin, unpack(bars)) 76 | max = math.max(trueMax, unpack(bars)) 77 | lastUpdate = juno.time.getNow() 78 | end 79 | -- Draw text 80 | local w = textRegionWidth 81 | juno.graphics.drawRect(pad / 2, yoffset - (pad / 2), 82 | w, height - 1, 0, 0, 0, .8) 83 | juno.graphics.drawText(font, txt, pad, yoffset) 84 | -- Draw bars 85 | juno.graphics.drawRect(pad / 2 + w + 1, yoffset - (pad / 2), 86 | 73, height - 1, 0, 0, 0, .8) 87 | for i, v in ipairs(bars) do 88 | local x = math.floor((bars[i] - min) / (max - min) * 16) 89 | juno.graphics.drawRect(pad / 2 + w + 1 + (i - 1) * 4 + 5, 90 | yoffset + 16 - x, 3, x, 91 | nil, nil, nil, (i == 1) and 1 or .4) 92 | end 93 | end 94 | end 95 | 96 | 97 | local function draw() 98 | -- Not enabled? Don't draw 99 | if not enabled then 100 | return 101 | end 102 | -- Draw 103 | juno.graphics.reset() 104 | -- Draw indicators 105 | for i, v in ipairs(indicators) do 106 | v() 107 | end 108 | -- Draw console input text 109 | local w = 300 110 | if focused then 111 | local h = font:getHeight() 112 | local y = juno.graphics.getHeight() - 8 - h 113 | local caret = (juno.time.getTime() % .6 < .3) and "_" or "" 114 | w = math.max(w, font:getWidth(inputbuf .. "_")) 115 | juno.graphics.drawRect(4, juno.graphics.getHeight() - h - 12, 116 | w + 8, h + 8, 117 | 0, 0, 0, .8) 118 | juno.graphics.drawText(font, inputbuf .. caret, 8, y) 119 | end 120 | -- Draw console output text 121 | if #lines > 0 then 122 | local h = font:getHeight() 123 | local rh = #lines * h + 8 124 | local oy = focused and (h + 9) or 0 125 | for i, v in ipairs(lines) do 126 | w = math.max(w, font:getWidth(v)) 127 | end 128 | juno.graphics.drawRect(4, juno.graphics.getHeight() - 4 - rh - oy, 129 | w + 8, rh, 130 | 0, 0, 0, .8) 131 | for i, v in ipairs(lines) do 132 | local y = juno.graphics.getHeight() - 8 - (#lines - i + 1) * h 133 | juno.graphics.drawText(font, v, 8, y - oy) 134 | end 135 | end 136 | end 137 | 138 | 139 | local function init() 140 | -- Init font 141 | font = juno.Font.fromEmbedded(12) 142 | -- Init indicators 143 | juno.debug.addIndicator(function() 144 | local r = juno.time.getFps() 145 | return r .. "fps", r 146 | end) 147 | juno.debug.addIndicator(function() 148 | local r = collectgarbage("count") 149 | return string.format("%.2fmb", r / 1024), r 150 | end) 151 | -- Override present function to draw the debug information before calling the 152 | -- proper present function 153 | local present = juno.graphics.present 154 | juno.graphics.present = function(...) 155 | draw() 156 | present(...) 157 | end 158 | -- Set init flag 159 | inited = true 160 | end 161 | 162 | 163 | local onError = function(msg) 164 | print("error: " .. msg:match("[^\n]+")) 165 | end 166 | 167 | function juno.debug._onEvent(e) 168 | -- Handle console's keyboard input 169 | if e.type == "keydown" and enabled and focused then 170 | if e.key == "backspace" then 171 | inputbuf = inputbuf:sub(1, #inputbuf - 1) 172 | elseif e.key == "return" then 173 | local fn, err = loadstring(inputbuf, "=input") 174 | if fn then 175 | xpcall(fn, onError) 176 | else 177 | onError(err) 178 | end 179 | inputbuf = "" 180 | elseif e.char then 181 | inputbuf = inputbuf .. e.char 182 | end 183 | end 184 | end 185 | 186 | 187 | function juno.debug._draw() 188 | draw() 189 | end 190 | 191 | 192 | function juno.debug.setVisible(x) 193 | enabled = x and true or false 194 | if enabled and not inited then 195 | init() 196 | end 197 | end 198 | 199 | function juno.debug.getVisible(x) 200 | return enabled 201 | end 202 | 203 | 204 | function juno.debug.setFocused(x) 205 | focused = x and true or false 206 | end 207 | 208 | function juno.debug.getFocused(x) 209 | return focused 210 | end 211 | 212 | 213 | function juno.debug.clear() 214 | while #lines > 0 do 215 | table.remove(lines) 216 | end 217 | end 218 | 219 | 220 | function juno.debug.addIndicator(fn, min, max) 221 | -- Error check 222 | local str, num = fn() 223 | if type(str) ~= "string" or type(num) ~= "number" then 224 | error("expected indicator function to return string and number", 2) 225 | end 226 | if min and type(min) ~= "number" then 227 | error("expected `min` to be a number", 2) 228 | end 229 | if max and type(max) ~= "number" then 230 | error("expected `max` to be a number", 2) 231 | end 232 | -- Create, add and return 233 | local indicator = newIndicator(fn, min, max) 234 | table.insert(indicators, indicator) 235 | return indicator 236 | end 237 | 238 | 239 | function juno.debug.removeIndicator(indicator) 240 | for i, v in ipairs(indicators) do 241 | if v == indicator then 242 | table.remove(indicators, i) 243 | return 244 | end 245 | end 246 | end 247 | -------------------------------------------------------------------------------- /src/embed/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxi/juno/982d9bf91c8354b60eb9c4f49c1192238b2bef95/src/embed/font.ttf -------------------------------------------------------------------------------- /src/embed/graphics.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | -- Override juno.graphics.init function 10 | local init = juno.graphics.init 11 | 12 | juno.graphics.init = function(...) 13 | -- Do init 14 | local screen = init(...) 15 | juno.graphics.screen = screen 16 | -- Bind the screen buffer's methods to the graphics module 17 | for k, v in pairs(juno.Buffer) do 18 | if not juno.graphics[k] then 19 | juno.graphics[k] = function(...) 20 | return v(screen, ...) 21 | end 22 | end 23 | end 24 | -- Unbind Buffer constructors (which make no sense bound) 25 | juno.graphics.fromBlank = nil 26 | juno.graphics.fromFile = nil 27 | juno.graphics.fromString = nil 28 | -- Override juno.graphics.clear() to use _clearColor if available 29 | local clear = juno.graphics.clear 30 | function juno.graphics.clear(r, g, b, a) 31 | local c = juno.graphics._clearColor 32 | r = r or (c and c[1]) 33 | g = g or (c and c[2]) 34 | b = b or (c and c[3]) 35 | clear(r, g, b, 1) 36 | end 37 | -- Return main screen buffer 38 | return screen 39 | end 40 | 41 | 42 | function juno.graphics.setClearColor(...) 43 | juno.graphics._clearColor = { ... } 44 | end 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/embed/keyboard.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | -- The table is checked and created here if it does not exist, at the time of 10 | -- writing this the juno.keyboard does not have a C module, and so the table 11 | -- won't exist yet. 12 | juno.keyboard = juno.keyboard or {} 13 | 14 | local keysDown = {} 15 | local keysPressed = {} 16 | 17 | 18 | function juno.keyboard._onEvent(e) 19 | if e.type == "keydown" then 20 | keysDown[e.key] = true 21 | keysPressed[e.key] = true 22 | elseif e.type == "keyup" then 23 | keysDown[e.key] = nil 24 | end 25 | end 26 | 27 | 28 | function juno.keyboard.reset() 29 | for k in pairs(keysPressed) do 30 | keysPressed[k] = nil 31 | end 32 | end 33 | 34 | 35 | function juno.keyboard.isDown(...) 36 | for i = 1, select("#", ...) do 37 | local k = select(i, ...) 38 | if keysDown[k] then 39 | return true 40 | end 41 | end 42 | return false 43 | end 44 | 45 | 46 | function juno.keyboard.wasPressed(...) 47 | for i = 1, select("#", ...) do 48 | local k = select(i, ...) 49 | if keysPressed[k] then 50 | return true 51 | end 52 | end 53 | return false 54 | end 55 | 56 | -------------------------------------------------------------------------------- /src/embed/mouse.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | local position = { x = 0, y = 0 } 10 | local buttonsDown = {} 11 | local buttonsPressed = {} 12 | 13 | 14 | function juno.mouse._onEvent(e) 15 | if e.type == "mousemove" then 16 | position.x, position.y = e.x, e.y 17 | elseif e.type == "mousebuttondown" then 18 | buttonsDown[e.button] = true 19 | buttonsPressed[e.button] = true 20 | elseif e.type == "mousebuttonup" then 21 | buttonsDown[e.button] = nil 22 | end 23 | end 24 | 25 | 26 | function juno.mouse.reset() 27 | for k in pairs(buttonsPressed) do 28 | buttonsPressed[k] = nil 29 | end 30 | end 31 | 32 | 33 | function juno.mouse.isDown(...) 34 | for i = 1, select("#", ...) do 35 | local b = select(i, ...) 36 | if buttonsDown[b] then 37 | return true 38 | end 39 | end 40 | return false 41 | end 42 | 43 | 44 | function juno.mouse.wasPressed(...) 45 | for i = 1, select("#", ...) do 46 | local b = select(i, ...) 47 | if buttonsPressed[b] then 48 | return true 49 | end 50 | end 51 | return false 52 | end 53 | 54 | 55 | function juno.mouse.getPosition() 56 | return position.x, position.y 57 | end 58 | 59 | 60 | function juno.mouse.getX() 61 | return position.x 62 | end 63 | 64 | 65 | function juno.mouse.getY() 66 | return position.y 67 | end 68 | -------------------------------------------------------------------------------- /src/embed/time.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2015 rxi 3 | -- 4 | -- This library is free software; you can redistribute it and/or modify it 5 | -- under the terms of the MIT license. See LICENSE for details. 6 | -- 7 | 8 | 9 | local last = 0 10 | local delta = 0 11 | local average = 0 12 | local avgTimer = 0 13 | local avgAcc = 1 14 | local avgCount = 1 15 | 16 | 17 | function juno.time.step() 18 | local now = juno.time.getTime() 19 | if last == 0 then last = now end 20 | delta = now - last 21 | last = now 22 | avgTimer = avgTimer - delta 23 | avgAcc = avgAcc + delta 24 | avgCount = avgCount + 1 25 | if avgTimer <= 0 then 26 | average = avgAcc / avgCount 27 | avgTimer = avgTimer + 1 28 | avgCount = 0 29 | avgAcc = 0 30 | end 31 | end 32 | 33 | 34 | function juno.time.getDelta() 35 | return delta 36 | end 37 | 38 | 39 | function juno.time.getAverage() 40 | return average 41 | end 42 | 43 | 44 | function juno.time.getFps() 45 | return math.floor(1 / average + .5) 46 | end 47 | 48 | -------------------------------------------------------------------------------- /src/fs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef FS_H 10 | #define FS_H 11 | 12 | typedef struct fs_FileListNode { 13 | char *name; 14 | struct fs_FileListNode *next; 15 | } fs_FileListNode; 16 | 17 | enum { 18 | FS_ESUCCESS = 0, 19 | FS_EFAILURE = -1, 20 | FS_EOUTOFMEM = -2, 21 | FS_EBADPATH = -3, 22 | FS_EBADFILENAME = -4, 23 | FS_ENOWRITEPATH = -5, 24 | FS_ECANTOPEN = -6, 25 | FS_ECANTREAD = -7, 26 | FS_ECANTWRITE = -8, 27 | FS_ECANTDELETE = -9, 28 | FS_ECANTMKDIR = -10, 29 | FS_ENOTEXIST = -11, 30 | }; 31 | 32 | const char *fs_errorStr(int err); 33 | void fs_deinit(void); 34 | int fs_mount(const char *path); 35 | int fs_unmount(const char *path); 36 | int fs_setWritePath(const char *path); 37 | int fs_exists(const char *filename); 38 | int fs_modified(const char *filename, unsigned *mtime); 39 | int fs_size(const char *filename, size_t *size); 40 | void *fs_read(const char *filename, size_t *size); 41 | int fs_isDir(const char *filename); 42 | fs_FileListNode *fs_listDir(const char *path); 43 | void fs_freeFileList(fs_FileListNode *list); 44 | int fs_write(const char *filename, const void *data, int size); 45 | int fs_append(const char *filename, const void *data, int size); 46 | int fs_delete(const char *filename); 47 | int fs_makeDirs(const char *path); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/lib/lextlib_lua52.h: -------------------------------------------------------------------------------- 1 | #ifndef LEXTLIB_LUA52_H 2 | #define LEXTLIB_LUA52_H 3 | 4 | /** 5 | * The original version of this file is located at 6 | * https://github.com/devurandom/lextlib/blob/master/lextlib_lua52.h 7 | * 8 | * Its license is as follows: 9 | * 10 | * Copyright (c) 2012 Dennis Schridde 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy 13 | * of this software and associated documentation files (the "Software"), to 14 | * deal in the Software without restriction, including without limitation the 15 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | * sell copies of the Software, and to permit persons to whom the Software is 17 | * furnished to do so, subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in 20 | * all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 28 | * IN THE SOFTWARE. 29 | */ 30 | 31 | 32 | #include 33 | 34 | //#include 35 | //#include 36 | 37 | 38 | #if LUA_VERSION_NUM < 502 39 | /* Error codes for lua_load: */ 40 | # define LUA_OK 0 41 | /* WARNING: This error does not exist in Lua 5.1 */ 42 | # define LUA_ERRGCMM (-1) 43 | 44 | /* Comparison types for lua_compare: */ 45 | # define LUA_OPEQ 0 46 | # define LUA_OPLT 1 47 | # define LUA_OPLE 2 48 | 49 | /* WARNING: Not entirely correct, but should work anyway */ 50 | # define lua_rawlen lua_objlen 51 | 52 | # define lua_absindex(L, i) (((i) > 0 || (i) < LUA_REGISTRYINDEX) ? (i) : lua_gettop(L)+(i)+1) 53 | 54 | /* WARNING: Something very different, but it might get your job done */ 55 | # define lua_getuservalue lua_getfenv 56 | # define lua_setuservalue lua_setfenv 57 | 58 | /* WARNING: Probably slower than Lua 5.2's implementation */ 59 | # define lua_compare luaX52_lua_compare 60 | 61 | # define lua_tonumberx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tonumber(L,(i))) : (*(b)=0, 0)) 62 | # define lua_tointegerx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tointeger(L,(i))) : (*(b)=0, 0)) 63 | 64 | # define luaL_getsubtable luaX52_luaL_getsubtable 65 | 66 | # define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 67 | 68 | # define luaL_newlibtable(L,l) (lua_createtable(L,0,sizeof(l))) 69 | 70 | # define luaL_requiref(L,l,f,g) luaX52_luaL_requiref(L,(l),(f),(g)) 71 | 72 | # define luaL_setfuncs luaX52_luaL_setfuncs 73 | 74 | # define luaL_setmetatable(L,t) (luaL_getmetatable(L,t), lua_setmetatable(L,-2)) 75 | 76 | # define luaL_testudata(L,i,t) luaX52_luaL_testudata(L,(i),(t)) 77 | 78 | static inline void luaX52_luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) { 79 | luaL_checkstack(L, nup, "too many upvalues"); 80 | for (; l->name != NULL; l++) { /* fill the table with given functions */ 81 | for (int i = 0; i < nup; i++) /* copy upvalues to the top */ 82 | lua_pushvalue(L, -nup); 83 | lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 84 | lua_setfield(L, -(nup + 2), l->name); 85 | } 86 | lua_pop(L, nup); /* remove upvalues */ 87 | } 88 | 89 | static inline int luaX52_lua_compare(lua_State *L, int index1, int index2, int op) { 90 | assert(op == LUA_OPEQ || op == LUA_OPLT || op == LUA_OPLE); 91 | switch (op) { 92 | case LUA_OPEQ: 93 | return lua_equal(L, index1, index2); 94 | case LUA_OPLT: 95 | return lua_lessthan(L, index1, index2); 96 | case LUA_OPLE: 97 | return lua_lessthan(L, index1, index2) || lua_equal(L, index1, index2); 98 | default: 99 | return luaL_error(L, "Call to lua_compare with unsupported operator %d", op); 100 | } 101 | } 102 | 103 | static inline int luaX52_luaL_getsubtable(lua_State *L, int idx, const char *fname) { 104 | lua_getfield(L, idx, fname); 105 | if (lua_istable(L, -1)) return 1; /* table already there */ 106 | else { 107 | lua_pop(L, 1); /* remove previous result */ 108 | idx = lua_absindex(L, idx); 109 | lua_newtable(L); 110 | lua_pushvalue(L, -1); /* copy to be left at top */ 111 | lua_setfield(L, idx, fname); /* assign new table to field */ 112 | return 0; /* false, because did not find table there */ 113 | } 114 | } 115 | 116 | static inline void luaX52_luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) { 117 | lua_pushcfunction(L, openf); 118 | lua_pushstring(L, modname); /* argument to open function */ 119 | lua_call(L, 1, 1); /* open module */ 120 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); 121 | lua_pushvalue(L, -2); /* make copy of module (call result) */ 122 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ 123 | lua_pop(L, 1); /* remove _LOADED table */ 124 | if (glb) { 125 | lua_pushvalue(L, -1); /* copy of 'mod' */ 126 | lua_setglobal(L, modname); /* _G[modname] = module */ 127 | } 128 | } 129 | 130 | static inline void *luaX52_luaL_testudata(lua_State *L, int ud, const char *tname) { 131 | void *p = lua_touserdata(L, ud); 132 | if (p != NULL) { /* value is a userdata? */ 133 | if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ 134 | luaL_getmetatable(L, tname); /* get correct metatable */ 135 | if (!lua_rawequal(L, -1, -2)) /* not the same? */ 136 | p = NULL; /* value is a userdata with wrong metatable */ 137 | lua_pop(L, 2); /* remove both metatables */ 138 | return p; 139 | } 140 | } 141 | return NULL; /* value is not a userdata with a metatable */ 142 | } 143 | 144 | #endif 145 | 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /src/lib/lua51/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/lib/lua51/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | #if defined(LUA_COMPAT_GETN) 19 | LUALIB_API int (luaL_getn) (lua_State *L, int t); 20 | LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); 21 | #else 22 | #define luaL_getn(L,i) ((int)lua_objlen(L, i)) 23 | #define luaL_setn(L,i,j) ((void)0) /* no op! */ 24 | #endif 25 | 26 | #if defined(LUA_COMPAT_OPENLIB) 27 | #define luaI_openlib luaL_openlib 28 | #endif 29 | 30 | 31 | /* extra error code for `luaL_load' */ 32 | #define LUA_ERRFILE (LUA_ERRERR+1) 33 | 34 | 35 | typedef struct luaL_Reg { 36 | const char *name; 37 | lua_CFunction func; 38 | } luaL_Reg; 39 | 40 | 41 | 42 | LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, 43 | const luaL_Reg *l, int nup); 44 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 45 | const luaL_Reg *l); 46 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 47 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48 | LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); 49 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 50 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 51 | size_t *l); 52 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 53 | const char *def, size_t *l); 54 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 55 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 56 | 57 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 58 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 59 | lua_Integer def); 60 | 61 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 62 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 63 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 64 | 65 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 66 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 67 | 68 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 69 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 70 | 71 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 72 | const char *const lst[]); 73 | 74 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 75 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 76 | 77 | LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); 78 | LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, 79 | const char *name); 80 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 81 | 82 | LUALIB_API lua_State *(luaL_newstate) (void); 83 | 84 | 85 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 86 | const char *r); 87 | 88 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, 89 | const char *fname, int szhint); 90 | 91 | 92 | 93 | 94 | /* 95 | ** =============================================================== 96 | ** some useful macros 97 | ** =============================================================== 98 | */ 99 | 100 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 101 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 102 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 103 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 104 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 105 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 106 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 107 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 108 | 109 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 110 | 111 | #define luaL_dofile(L, fn) \ 112 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 113 | 114 | #define luaL_dostring(L, s) \ 115 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 116 | 117 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 118 | 119 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 120 | 121 | /* 122 | ** {====================================================== 123 | ** Generic Buffer manipulation 124 | ** ======================================================= 125 | */ 126 | 127 | 128 | 129 | typedef struct luaL_Buffer { 130 | char *p; /* current position in buffer */ 131 | int lvl; /* number of strings in the stack (level) */ 132 | lua_State *L; 133 | char buffer[LUAL_BUFFERSIZE]; 134 | } luaL_Buffer; 135 | 136 | #define luaL_addchar(B,c) \ 137 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ 138 | (*(B)->p++ = (char)(c))) 139 | 140 | /* compatibility only */ 141 | #define luaL_putchar(B,c) luaL_addchar(B,c) 142 | 143 | #define luaL_addsize(B,n) ((B)->p += (n)) 144 | 145 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 146 | LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); 147 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 148 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 149 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 150 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 151 | 152 | 153 | /* }====================================================== */ 154 | 155 | 156 | /* compatibility with ref system */ 157 | 158 | /* pre-defined references */ 159 | #define LUA_NOREF (-2) 160 | #define LUA_REFNIL (-1) 161 | 162 | #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ 163 | (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) 164 | 165 | #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) 166 | 167 | #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) 168 | 169 | 170 | #define luaL_reg luaL_Reg 171 | 172 | #endif 173 | 174 | 175 | -------------------------------------------------------------------------------- /src/lib/lua51/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 28 | OPR_CONCAT, 29 | OPR_NE, OPR_EQ, 30 | OPR_LT, OPR_LE, OPR_GT, OPR_GE, 31 | OPR_AND, OPR_OR, 32 | OPR_NOBINOPR 33 | } BinOpr; 34 | 35 | 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 37 | 38 | 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) 40 | 41 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 42 | 43 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 44 | 45 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 46 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 47 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 48 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 49 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 50 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 51 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 52 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 53 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 54 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 55 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 56 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 57 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 58 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 59 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 60 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 61 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 62 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 63 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 64 | LUAI_FUNC int luaK_jump (FuncState *fs); 65 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 66 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 67 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 68 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 69 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 70 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 71 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 72 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); 73 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/lib/lua51/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); 24 | LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, 25 | const TValue *p2); 26 | LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, 27 | const TValue *p2); 28 | LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); 29 | LUAI_FUNC void luaG_errormsg (lua_State *L); 30 | LUAI_FUNC int luaG_checkcode (const Proto *pt); 31 | LUAI_FUNC int luaG_checkopenop (Instruction i); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/lib/lua51/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | #define luaD_checkstack(L,n) \ 17 | if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ 18 | luaD_growstack(L, n); \ 19 | else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); 20 | 21 | 22 | #define incr_top(L) {luaD_checkstack(L,1); L->top++;} 23 | 24 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 25 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 26 | 27 | #define saveci(L,p) ((char *)(p) - (char *)L->base_ci) 28 | #define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) 29 | 30 | 31 | /* results from luaD_precall */ 32 | #define PCRLUA 0 /* initiated a call to a Lua function */ 33 | #define PCRC 1 /* did a call to a C function */ 34 | #define PCRYIELD 2 /* C funtion yielded */ 35 | 36 | 37 | /* type of protected functions, to be ran by `runprotected' */ 38 | typedef void (*Pfunc) (lua_State *L, void *ud); 39 | 40 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); 41 | LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 45 | ptrdiff_t oldtop, ptrdiff_t ef); 46 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 47 | LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); 48 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 49 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 50 | 51 | LUAI_FUNC void luaD_throw (lua_State *L, int errcode); 52 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 53 | 54 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /src/lib/lua51/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define ldump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "lobject.h" 15 | #include "lstate.h" 16 | #include "lundump.h" 17 | 18 | typedef struct { 19 | lua_State* L; 20 | lua_Writer writer; 21 | void* data; 22 | int strip; 23 | int status; 24 | } DumpState; 25 | 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) 28 | 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) 30 | { 31 | if (D->status==0) 32 | { 33 | lua_unlock(D->L); 34 | D->status=(*D->writer)(D->L,b,size,D->data); 35 | lua_lock(D->L); 36 | } 37 | } 38 | 39 | static void DumpChar(int y, DumpState* D) 40 | { 41 | char x=(char)y; 42 | DumpVar(x,D); 43 | } 44 | 45 | static void DumpInt(int x, DumpState* D) 46 | { 47 | DumpVar(x,D); 48 | } 49 | 50 | static void DumpNumber(lua_Number x, DumpState* D) 51 | { 52 | DumpVar(x,D); 53 | } 54 | 55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) 56 | { 57 | DumpInt(n,D); 58 | DumpMem(b,n,size,D); 59 | } 60 | 61 | static void DumpString(const TString* s, DumpState* D) 62 | { 63 | if (s==NULL || getstr(s)==NULL) 64 | { 65 | size_t size=0; 66 | DumpVar(size,D); 67 | } 68 | else 69 | { 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ 71 | DumpVar(size,D); 72 | DumpBlock(getstr(s),size,D); 73 | } 74 | } 75 | 76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) 77 | 78 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D); 79 | 80 | static void DumpConstants(const Proto* f, DumpState* D) 81 | { 82 | int i,n=f->sizek; 83 | DumpInt(n,D); 84 | for (i=0; ik[i]; 87 | DumpChar(ttype(o),D); 88 | switch (ttype(o)) 89 | { 90 | case LUA_TNIL: 91 | break; 92 | case LUA_TBOOLEAN: 93 | DumpChar(bvalue(o),D); 94 | break; 95 | case LUA_TNUMBER: 96 | DumpNumber(nvalue(o),D); 97 | break; 98 | case LUA_TSTRING: 99 | DumpString(rawtsvalue(o),D); 100 | break; 101 | default: 102 | lua_assert(0); /* cannot happen */ 103 | break; 104 | } 105 | } 106 | n=f->sizep; 107 | DumpInt(n,D); 108 | for (i=0; ip[i],f->source,D); 109 | } 110 | 111 | static void DumpDebug(const Proto* f, DumpState* D) 112 | { 113 | int i,n; 114 | n= (D->strip) ? 0 : f->sizelineinfo; 115 | DumpVector(f->lineinfo,n,sizeof(int),D); 116 | n= (D->strip) ? 0 : f->sizelocvars; 117 | DumpInt(n,D); 118 | for (i=0; ilocvars[i].varname,D); 121 | DumpInt(f->locvars[i].startpc,D); 122 | DumpInt(f->locvars[i].endpc,D); 123 | } 124 | n= (D->strip) ? 0 : f->sizeupvalues; 125 | DumpInt(n,D); 126 | for (i=0; iupvalues[i],D); 127 | } 128 | 129 | static void DumpFunction(const Proto* f, const TString* p, DumpState* D) 130 | { 131 | DumpString((f->source==p || D->strip) ? NULL : f->source,D); 132 | DumpInt(f->linedefined,D); 133 | DumpInt(f->lastlinedefined,D); 134 | DumpChar(f->nups,D); 135 | DumpChar(f->numparams,D); 136 | DumpChar(f->is_vararg,D); 137 | DumpChar(f->maxstacksize,D); 138 | DumpCode(f,D); 139 | DumpConstants(f,D); 140 | DumpDebug(f,D); 141 | } 142 | 143 | static void DumpHeader(DumpState* D) 144 | { 145 | char h[LUAC_HEADERSIZE]; 146 | luaU_header(h); 147 | DumpBlock(h,LUAC_HEADERSIZE,D); 148 | } 149 | 150 | /* 151 | ** dump Lua function as precompiled chunk 152 | */ 153 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) 154 | { 155 | DumpState D; 156 | D.L=L; 157 | D.writer=w; 158 | D.data=data; 159 | D.strip=strip; 160 | D.status=0; 161 | DumpHeader(&D); 162 | DumpFunction(f,NULL,&D); 163 | return D.status; 164 | } 165 | -------------------------------------------------------------------------------- /src/lib/lua51/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lfunc_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lfunc.h" 16 | #include "lgc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { 24 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); 25 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 26 | c->c.isC = 1; 27 | c->c.env = e; 28 | c->c.nupvalues = cast_byte(nelems); 29 | return c; 30 | } 31 | 32 | 33 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { 34 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 35 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); 36 | c->l.isC = 0; 37 | c->l.env = e; 38 | c->l.nupvalues = cast_byte(nelems); 39 | while (nelems--) c->l.upvals[nelems] = NULL; 40 | return c; 41 | } 42 | 43 | 44 | UpVal *luaF_newupval (lua_State *L) { 45 | UpVal *uv = luaM_new(L, UpVal); 46 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); 47 | uv->v = &uv->u.value; 48 | setnilvalue(uv->v); 49 | return uv; 50 | } 51 | 52 | 53 | UpVal *luaF_findupval (lua_State *L, StkId level) { 54 | global_State *g = G(L); 55 | GCObject **pp = &L->openupval; 56 | UpVal *p; 57 | UpVal *uv; 58 | while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { 59 | lua_assert(p->v != &p->u.value); 60 | if (p->v == level) { /* found a corresponding upvalue? */ 61 | if (isdead(g, obj2gco(p))) /* is it dead? */ 62 | changewhite(obj2gco(p)); /* ressurect it */ 63 | return p; 64 | } 65 | pp = &p->next; 66 | } 67 | uv = luaM_new(L, UpVal); /* not found: create a new one */ 68 | uv->tt = LUA_TUPVAL; 69 | uv->marked = luaC_white(g); 70 | uv->v = level; /* current value lives in the stack */ 71 | uv->next = *pp; /* chain it in the proper position */ 72 | *pp = obj2gco(uv); 73 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 74 | uv->u.l.next = g->uvhead.u.l.next; 75 | uv->u.l.next->u.l.prev = uv; 76 | g->uvhead.u.l.next = uv; 77 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 78 | return uv; 79 | } 80 | 81 | 82 | static void unlinkupval (UpVal *uv) { 83 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 84 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ 85 | uv->u.l.prev->u.l.next = uv->u.l.next; 86 | } 87 | 88 | 89 | void luaF_freeupval (lua_State *L, UpVal *uv) { 90 | if (uv->v != &uv->u.value) /* is it open? */ 91 | unlinkupval(uv); /* remove from open list */ 92 | luaM_free(L, uv); /* free upvalue */ 93 | } 94 | 95 | 96 | void luaF_close (lua_State *L, StkId level) { 97 | UpVal *uv; 98 | global_State *g = G(L); 99 | while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { 100 | GCObject *o = obj2gco(uv); 101 | lua_assert(!isblack(o) && uv->v != &uv->u.value); 102 | L->openupval = uv->next; /* remove from `open' list */ 103 | if (isdead(g, o)) 104 | luaF_freeupval(L, uv); /* free upvalue */ 105 | else { 106 | unlinkupval(uv); 107 | setobj(L, &uv->u.value, uv->v); 108 | uv->v = &uv->u.value; /* now current value lives here */ 109 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 110 | } 111 | } 112 | } 113 | 114 | 115 | Proto *luaF_newproto (lua_State *L) { 116 | Proto *f = luaM_new(L, Proto); 117 | luaC_link(L, obj2gco(f), LUA_TPROTO); 118 | f->k = NULL; 119 | f->sizek = 0; 120 | f->p = NULL; 121 | f->sizep = 0; 122 | f->code = NULL; 123 | f->sizecode = 0; 124 | f->sizelineinfo = 0; 125 | f->sizeupvalues = 0; 126 | f->nups = 0; 127 | f->upvalues = NULL; 128 | f->numparams = 0; 129 | f->is_vararg = 0; 130 | f->maxstacksize = 0; 131 | f->lineinfo = NULL; 132 | f->sizelocvars = 0; 133 | f->locvars = NULL; 134 | f->linedefined = 0; 135 | f->lastlinedefined = 0; 136 | f->source = NULL; 137 | return f; 138 | } 139 | 140 | 141 | void luaF_freeproto (lua_State *L, Proto *f) { 142 | luaM_freearray(L, f->code, f->sizecode, Instruction); 143 | luaM_freearray(L, f->p, f->sizep, Proto *); 144 | luaM_freearray(L, f->k, f->sizek, TValue); 145 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 146 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 147 | luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 148 | luaM_free(L, f); 149 | } 150 | 151 | 152 | void luaF_freeclosure (lua_State *L, Closure *c) { 153 | int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : 154 | sizeLclosure(c->l.nupvalues); 155 | luaM_freemem(L, c, size); 156 | } 157 | 158 | 159 | /* 160 | ** Look for n-th local variable at line `line' in function `func'. 161 | ** Returns NULL if not found. 162 | */ 163 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 164 | int i; 165 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 166 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 167 | local_number--; 168 | if (local_number == 0) 169 | return getstr(f->locvars[i].varname); 170 | } 171 | } 172 | return NULL; /* not found */ 173 | } 174 | 175 | -------------------------------------------------------------------------------- /src/lib/lua51/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 28 | LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); 29 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); 30 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 31 | int pc); 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/lib/lua51/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | ** Possible states of the Garbage Collector 16 | */ 17 | #define GCSpause 0 18 | #define GCSpropagate 1 19 | #define GCSsweepstring 2 20 | #define GCSsweep 3 21 | #define GCSfinalize 4 22 | 23 | 24 | /* 25 | ** some userful bit tricks 26 | */ 27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 28 | #define setbits(x,m) ((x) |= (m)) 29 | #define testbits(x,m) ((x) & (m)) 30 | #define bitmask(b) (1<<(b)) 31 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 32 | #define l_setbit(x,b) setbits(x, bitmask(b)) 33 | #define resetbit(x,b) resetbits(x, bitmask(b)) 34 | #define testbit(x,b) testbits(x, bitmask(b)) 35 | #define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) 36 | #define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) 37 | #define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) 38 | 39 | 40 | 41 | /* 42 | ** Layout for bit use in `marked' field: 43 | ** bit 0 - object is white (type 0) 44 | ** bit 1 - object is white (type 1) 45 | ** bit 2 - object is black 46 | ** bit 3 - for userdata: has been finalized 47 | ** bit 3 - for tables: has weak keys 48 | ** bit 4 - for tables: has weak values 49 | ** bit 5 - object is fixed (should not be collected) 50 | ** bit 6 - object is "super" fixed (only the main thread) 51 | */ 52 | 53 | 54 | #define WHITE0BIT 0 55 | #define WHITE1BIT 1 56 | #define BLACKBIT 2 57 | #define FINALIZEDBIT 3 58 | #define KEYWEAKBIT 3 59 | #define VALUEWEAKBIT 4 60 | #define FIXEDBIT 5 61 | #define SFIXEDBIT 6 62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 63 | 64 | 65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) 67 | #define isgray(x) (!isblack(x) && !iswhite(x)) 68 | 69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) 71 | 72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 73 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 74 | 75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 76 | 77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 78 | 79 | 80 | #define luaC_checkGC(L) { \ 81 | condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ 82 | if (G(L)->totalbytes >= G(L)->GCthreshold) \ 83 | luaC_step(L); } 84 | 85 | 86 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 87 | luaC_barrierf(L,obj2gco(p),gcvalue(v)); } 88 | 89 | #define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ 90 | luaC_barrierback(L,t); } 91 | 92 | #define luaC_objbarrier(L,p,o) \ 93 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 94 | luaC_barrierf(L,obj2gco(p),obj2gco(o)); } 95 | 96 | #define luaC_objbarriert(L,t,o) \ 97 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } 98 | 99 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); 100 | LUAI_FUNC void luaC_callGCTM (lua_State *L); 101 | LUAI_FUNC void luaC_freeall (lua_State *L); 102 | LUAI_FUNC void luaC_step (lua_State *L); 103 | LUAI_FUNC void luaC_fullgc (lua_State *L); 104 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); 105 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); 106 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); 107 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); 108 | 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/lib/lua51/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Initialization of libraries for lua.c 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | #include "lua.h" 12 | 13 | #include "lualib.h" 14 | #include "lauxlib.h" 15 | 16 | 17 | static const luaL_Reg lualibs[] = { 18 | {"", luaopen_base}, 19 | {LUA_LOADLIBNAME, luaopen_package}, 20 | {LUA_TABLIBNAME, luaopen_table}, 21 | {LUA_IOLIBNAME, luaopen_io}, 22 | {LUA_OSLIBNAME, luaopen_os}, 23 | {LUA_STRLIBNAME, luaopen_string}, 24 | {LUA_MATHLIBNAME, luaopen_math}, 25 | {LUA_DBLIBNAME, luaopen_debug}, 26 | {NULL, NULL} 27 | }; 28 | 29 | 30 | LUALIB_API void luaL_openlibs (lua_State *L) { 31 | const luaL_Reg *lib = lualibs; 32 | for (; lib->func; lib++) { 33 | lua_pushcfunction(L, lib->func); 34 | lua_pushstring(L, lib->name); 35 | lua_call(L, 1, 0); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/lib/lua51/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | /* maximum length of a reserved word */ 17 | #define TOKEN_LEN (sizeof("function")/sizeof(char)) 18 | 19 | 20 | /* 21 | * WARNING: if you change the order of this enumeration, 22 | * grep "ORDER RESERVED" 23 | */ 24 | enum RESERVED { 25 | /* terminal symbols denoted by reserved words */ 26 | TK_AND = FIRST_RESERVED, TK_BREAK, 27 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 28 | TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 29 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 30 | /* other terminal symbols */ 31 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, 32 | TK_NAME, TK_STRING, TK_EOS 33 | }; 34 | 35 | /* number of reserved words */ 36 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 37 | 38 | 39 | /* array with token `names' */ 40 | LUAI_DATA const char *const luaX_tokens []; 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | TString *ts; 46 | } SemInfo; /* semantics information */ 47 | 48 | 49 | typedef struct Token { 50 | int token; 51 | SemInfo seminfo; 52 | } Token; 53 | 54 | 55 | typedef struct LexState { 56 | int current; /* current character (charint) */ 57 | int linenumber; /* input line counter */ 58 | int lastline; /* line of last token `consumed' */ 59 | Token t; /* current token */ 60 | Token lookahead; /* look ahead token */ 61 | struct FuncState *fs; /* `FuncState' is private to the parser */ 62 | struct lua_State *L; 63 | ZIO *z; /* input stream */ 64 | Mbuffer *buff; /* buffer for tokens */ 65 | TString *source; /* current source name */ 66 | char decpoint; /* locale decimal point */ 67 | } LexState; 68 | 69 | 70 | LUAI_FUNC void luaX_init (lua_State *L); 71 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 72 | TString *source); 73 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 74 | LUAI_FUNC void luaX_next (LexState *ls); 75 | LUAI_FUNC void luaX_lookahead (LexState *ls); 76 | LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); 77 | LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); 78 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/lib/lua51/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Limits, basic types, and some other `installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | 17 | 18 | typedef LUAI_UINT32 lu_int32; 19 | 20 | typedef LUAI_UMEM lu_mem; 21 | 22 | typedef LUAI_MEM l_mem; 23 | 24 | 25 | 26 | /* chars used as small naturals (so that `char' is reserved for characters) */ 27 | typedef unsigned char lu_byte; 28 | 29 | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) 31 | 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) 33 | 34 | 35 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 36 | 37 | /* 38 | ** conversion of pointer to integer 39 | ** this is for hashing only; there is no problem if the integer 40 | ** cannot hold the whole pointer value 41 | */ 42 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) 43 | 44 | 45 | 46 | /* type to ensure maximum alignment */ 47 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 48 | 49 | 50 | /* result of a `usual argument conversion' over lua_Number */ 51 | typedef LUAI_UACNUMBER l_uacNumber; 52 | 53 | 54 | /* internal assertions for in-house debugging */ 55 | #ifdef lua_assert 56 | 57 | #define check_exp(c,e) (lua_assert(c), (e)) 58 | #define api_check(l,e) lua_assert(e) 59 | 60 | #else 61 | 62 | #define lua_assert(c) ((void)0) 63 | #define check_exp(c,e) (e) 64 | #define api_check luai_apicheck 65 | 66 | #endif 67 | 68 | 69 | #ifndef UNUSED 70 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 71 | #endif 72 | 73 | 74 | #ifndef cast 75 | #define cast(t, exp) ((t)(exp)) 76 | #endif 77 | 78 | #define cast_byte(i) cast(lu_byte, (i)) 79 | #define cast_num(i) cast(lua_Number, (i)) 80 | #define cast_int(i) cast(int, (i)) 81 | 82 | 83 | 84 | /* 85 | ** type for virtual-machine instructions 86 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 87 | */ 88 | typedef lu_int32 Instruction; 89 | 90 | 91 | 92 | /* maximum stack for a Lua function */ 93 | #define MAXSTACK 250 94 | 95 | 96 | 97 | /* minimum size for the string table (must be power of 2) */ 98 | #ifndef MINSTRTABSIZE 99 | #define MINSTRTABSIZE 32 100 | #endif 101 | 102 | 103 | /* minimum size for string buffer */ 104 | #ifndef LUA_MINBUFFER 105 | #define LUA_MINBUFFER 32 106 | #endif 107 | 108 | 109 | #ifndef lua_lock 110 | #define lua_lock(L) ((void) 0) 111 | #define lua_unlock(L) ((void) 0) 112 | #endif 113 | 114 | #ifndef luai_threadyield 115 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 116 | #endif 117 | 118 | 119 | /* 120 | ** macro to control inclusion of some hard tests on stack reallocation 121 | */ 122 | #ifndef HARDSTACKTESTS 123 | #define condhardstacktests(x) ((void)0) 124 | #else 125 | #define condhardstacktests(x) x 126 | #endif 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /src/lib/lua51/lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Standard mathematical library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #define lmathlib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | #undef PI 21 | #define PI (3.14159265358979323846) 22 | #define RADIANS_PER_DEGREE (PI/180.0) 23 | 24 | 25 | 26 | static int math_abs (lua_State *L) { 27 | lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); 28 | return 1; 29 | } 30 | 31 | static int math_sin (lua_State *L) { 32 | lua_pushnumber(L, sin(luaL_checknumber(L, 1))); 33 | return 1; 34 | } 35 | 36 | static int math_sinh (lua_State *L) { 37 | lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); 38 | return 1; 39 | } 40 | 41 | static int math_cos (lua_State *L) { 42 | lua_pushnumber(L, cos(luaL_checknumber(L, 1))); 43 | return 1; 44 | } 45 | 46 | static int math_cosh (lua_State *L) { 47 | lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); 48 | return 1; 49 | } 50 | 51 | static int math_tan (lua_State *L) { 52 | lua_pushnumber(L, tan(luaL_checknumber(L, 1))); 53 | return 1; 54 | } 55 | 56 | static int math_tanh (lua_State *L) { 57 | lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); 58 | return 1; 59 | } 60 | 61 | static int math_asin (lua_State *L) { 62 | lua_pushnumber(L, asin(luaL_checknumber(L, 1))); 63 | return 1; 64 | } 65 | 66 | static int math_acos (lua_State *L) { 67 | lua_pushnumber(L, acos(luaL_checknumber(L, 1))); 68 | return 1; 69 | } 70 | 71 | static int math_atan (lua_State *L) { 72 | lua_pushnumber(L, atan(luaL_checknumber(L, 1))); 73 | return 1; 74 | } 75 | 76 | static int math_atan2 (lua_State *L) { 77 | lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 78 | return 1; 79 | } 80 | 81 | static int math_ceil (lua_State *L) { 82 | lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); 83 | return 1; 84 | } 85 | 86 | static int math_floor (lua_State *L) { 87 | lua_pushnumber(L, floor(luaL_checknumber(L, 1))); 88 | return 1; 89 | } 90 | 91 | static int math_fmod (lua_State *L) { 92 | lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 93 | return 1; 94 | } 95 | 96 | static int math_modf (lua_State *L) { 97 | double ip; 98 | double fp = modf(luaL_checknumber(L, 1), &ip); 99 | lua_pushnumber(L, ip); 100 | lua_pushnumber(L, fp); 101 | return 2; 102 | } 103 | 104 | static int math_sqrt (lua_State *L) { 105 | lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); 106 | return 1; 107 | } 108 | 109 | static int math_pow (lua_State *L) { 110 | lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); 111 | return 1; 112 | } 113 | 114 | static int math_log (lua_State *L) { 115 | lua_pushnumber(L, log(luaL_checknumber(L, 1))); 116 | return 1; 117 | } 118 | 119 | static int math_log10 (lua_State *L) { 120 | lua_pushnumber(L, log10(luaL_checknumber(L, 1))); 121 | return 1; 122 | } 123 | 124 | static int math_exp (lua_State *L) { 125 | lua_pushnumber(L, exp(luaL_checknumber(L, 1))); 126 | return 1; 127 | } 128 | 129 | static int math_deg (lua_State *L) { 130 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 131 | return 1; 132 | } 133 | 134 | static int math_rad (lua_State *L) { 135 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 136 | return 1; 137 | } 138 | 139 | static int math_frexp (lua_State *L) { 140 | int e; 141 | lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); 142 | lua_pushinteger(L, e); 143 | return 2; 144 | } 145 | 146 | static int math_ldexp (lua_State *L) { 147 | lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); 148 | return 1; 149 | } 150 | 151 | 152 | 153 | static int math_min (lua_State *L) { 154 | int n = lua_gettop(L); /* number of arguments */ 155 | lua_Number dmin = luaL_checknumber(L, 1); 156 | int i; 157 | for (i=2; i<=n; i++) { 158 | lua_Number d = luaL_checknumber(L, i); 159 | if (d < dmin) 160 | dmin = d; 161 | } 162 | lua_pushnumber(L, dmin); 163 | return 1; 164 | } 165 | 166 | 167 | static int math_max (lua_State *L) { 168 | int n = lua_gettop(L); /* number of arguments */ 169 | lua_Number dmax = luaL_checknumber(L, 1); 170 | int i; 171 | for (i=2; i<=n; i++) { 172 | lua_Number d = luaL_checknumber(L, i); 173 | if (d > dmax) 174 | dmax = d; 175 | } 176 | lua_pushnumber(L, dmax); 177 | return 1; 178 | } 179 | 180 | 181 | static int math_random (lua_State *L) { 182 | /* the `%' avoids the (rare) case of r==1, and is needed also because on 183 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ 184 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 185 | switch (lua_gettop(L)) { /* check number of arguments */ 186 | case 0: { /* no arguments */ 187 | lua_pushnumber(L, r); /* Number between 0 and 1 */ 188 | break; 189 | } 190 | case 1: { /* only upper limit */ 191 | int u = luaL_checkint(L, 1); 192 | luaL_argcheck(L, 1<=u, 1, "interval is empty"); 193 | lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ 194 | break; 195 | } 196 | case 2: { /* lower and upper limits */ 197 | int l = luaL_checkint(L, 1); 198 | int u = luaL_checkint(L, 2); 199 | luaL_argcheck(L, l<=u, 2, "interval is empty"); 200 | lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ 201 | break; 202 | } 203 | default: return luaL_error(L, "wrong number of arguments"); 204 | } 205 | return 1; 206 | } 207 | 208 | 209 | static int math_randomseed (lua_State *L) { 210 | srand(luaL_checkint(L, 1)); 211 | return 0; 212 | } 213 | 214 | 215 | static const luaL_Reg mathlib[] = { 216 | {"abs", math_abs}, 217 | {"acos", math_acos}, 218 | {"asin", math_asin}, 219 | {"atan2", math_atan2}, 220 | {"atan", math_atan}, 221 | {"ceil", math_ceil}, 222 | {"cosh", math_cosh}, 223 | {"cos", math_cos}, 224 | {"deg", math_deg}, 225 | {"exp", math_exp}, 226 | {"floor", math_floor}, 227 | {"fmod", math_fmod}, 228 | {"frexp", math_frexp}, 229 | {"ldexp", math_ldexp}, 230 | {"log10", math_log10}, 231 | {"log", math_log}, 232 | {"max", math_max}, 233 | {"min", math_min}, 234 | {"modf", math_modf}, 235 | {"pow", math_pow}, 236 | {"rad", math_rad}, 237 | {"random", math_random}, 238 | {"randomseed", math_randomseed}, 239 | {"sinh", math_sinh}, 240 | {"sin", math_sin}, 241 | {"sqrt", math_sqrt}, 242 | {"tanh", math_tanh}, 243 | {"tan", math_tan}, 244 | {NULL, NULL} 245 | }; 246 | 247 | 248 | /* 249 | ** Open math library 250 | */ 251 | LUALIB_API int luaopen_math (lua_State *L) { 252 | luaL_register(L, LUA_MATHLIBNAME, mathlib); 253 | lua_pushnumber(L, PI); 254 | lua_setfield(L, -2, "pi"); 255 | lua_pushnumber(L, HUGE_VAL); 256 | lua_setfield(L, -2, "huge"); 257 | #if defined(LUA_COMPAT_MOD) 258 | lua_getfield(L, -1, "fmod"); 259 | lua_setfield(L, -2, "mod"); 260 | #endif 261 | return 1; 262 | } 263 | 264 | -------------------------------------------------------------------------------- /src/lib/lua51/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lmem_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | /* 24 | ** About the realloc function: 25 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 26 | ** (`osize' is the old size, `nsize' is the new size) 27 | ** 28 | ** Lua ensures that (ptr == NULL) iff (osize == 0). 29 | ** 30 | ** * frealloc(ud, NULL, 0, x) creates a new block of size `x' 31 | ** 32 | ** * frealloc(ud, p, x, 0) frees the block `p' 33 | ** (in this specific case, frealloc must return NULL). 34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 35 | ** (which is equivalent to free(NULL) in ANSI C) 36 | ** 37 | ** frealloc returns NULL if it cannot create or reallocate the area 38 | ** (any reallocation to an equal or smaller size cannot fail!) 39 | */ 40 | 41 | 42 | 43 | #define MINSIZEARRAY 4 44 | 45 | 46 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 47 | int limit, const char *errormsg) { 48 | void *newblock; 49 | int newsize; 50 | if (*size >= limit/2) { /* cannot double it? */ 51 | if (*size >= limit) /* cannot grow even a little? */ 52 | luaG_runerror(L, errormsg); 53 | newsize = limit; /* still have at least one free place */ 54 | } 55 | else { 56 | newsize = (*size)*2; 57 | if (newsize < MINSIZEARRAY) 58 | newsize = MINSIZEARRAY; /* minimum size */ 59 | } 60 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 61 | *size = newsize; /* update only when everything else is OK */ 62 | return newblock; 63 | } 64 | 65 | 66 | void *luaM_toobig (lua_State *L) { 67 | luaG_runerror(L, "memory allocation error: block too big"); 68 | return NULL; /* to avoid warnings */ 69 | } 70 | 71 | 72 | 73 | /* 74 | ** generic allocation routine. 75 | */ 76 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 77 | global_State *g = G(L); 78 | lua_assert((osize == 0) == (block == NULL)); 79 | block = (*g->frealloc)(g->ud, block, osize, nsize); 80 | if (block == NULL && nsize > 0) 81 | luaD_throw(L, LUA_ERRMEM); 82 | lua_assert((nsize == 0) == (block == NULL)); 83 | g->totalbytes = (g->totalbytes - osize) + nsize; 84 | return block; 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/lib/lua51/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | #define MEMERRMSG "not enough memory" 17 | 18 | 19 | #define luaM_reallocv(L,b,on,n,e) \ 20 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ 21 | luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ 22 | luaM_toobig(L)) 23 | 24 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 25 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 26 | #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) 27 | 28 | #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) 29 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 30 | #define luaM_newvector(L,n,t) \ 31 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 32 | 33 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 34 | if ((nelems)+1 > (size)) \ 35 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 36 | 37 | #define luaM_reallocvector(L, v,oldn,n,t) \ 38 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 39 | 40 | 41 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 42 | size_t size); 43 | LUAI_FUNC void *luaM_toobig (lua_State *L); 44 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 45 | size_t size_elem, int limit, 46 | const char *errormsg); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /src/lib/lua51/lobject.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Some generic functions over Lua objects 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define lobject_c 14 | #define LUA_CORE 15 | 16 | #include "lua.h" 17 | 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "lvm.h" 24 | 25 | 26 | 27 | const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 28 | 29 | 30 | /* 31 | ** converts an integer to a "floating point byte", represented as 32 | ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if 33 | ** eeeee != 0 and (xxx) otherwise. 34 | */ 35 | int luaO_int2fb (unsigned int x) { 36 | int e = 0; /* expoent */ 37 | while (x >= 16) { 38 | x = (x+1) >> 1; 39 | e++; 40 | } 41 | if (x < 8) return x; 42 | else return ((e+1) << 3) | (cast_int(x) - 8); 43 | } 44 | 45 | 46 | /* converts back */ 47 | int luaO_fb2int (int x) { 48 | int e = (x >> 3) & 31; 49 | if (e == 0) return x; 50 | else return ((x & 7)+8) << (e - 1); 51 | } 52 | 53 | 54 | int luaO_log2 (unsigned int x) { 55 | static const lu_byte log_2[256] = { 56 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 57 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 58 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 59 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 60 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 61 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 62 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 63 | 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 64 | }; 65 | int l = -1; 66 | while (x >= 256) { l += 8; x >>= 8; } 67 | return l + log_2[x]; 68 | 69 | } 70 | 71 | 72 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 73 | if (ttype(t1) != ttype(t2)) return 0; 74 | else switch (ttype(t1)) { 75 | case LUA_TNIL: 76 | return 1; 77 | case LUA_TNUMBER: 78 | return luai_numeq(nvalue(t1), nvalue(t2)); 79 | case LUA_TBOOLEAN: 80 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 81 | case LUA_TLIGHTUSERDATA: 82 | return pvalue(t1) == pvalue(t2); 83 | default: 84 | lua_assert(iscollectable(t1)); 85 | return gcvalue(t1) == gcvalue(t2); 86 | } 87 | } 88 | 89 | 90 | int luaO_str2d (const char *s, lua_Number *result) { 91 | char *endptr; 92 | *result = lua_str2number(s, &endptr); 93 | if (endptr == s) return 0; /* conversion failed */ 94 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 95 | *result = cast_num(strtoul(s, &endptr, 16)); 96 | if (*endptr == '\0') return 1; /* most common case */ 97 | while (isspace(cast(unsigned char, *endptr))) endptr++; 98 | if (*endptr != '\0') return 0; /* invalid trailing characters? */ 99 | return 1; 100 | } 101 | 102 | 103 | 104 | static void pushstr (lua_State *L, const char *str) { 105 | setsvalue2s(L, L->top, luaS_new(L, str)); 106 | incr_top(L); 107 | } 108 | 109 | 110 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 111 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 112 | int n = 1; 113 | pushstr(L, ""); 114 | for (;;) { 115 | const char *e = strchr(fmt, '%'); 116 | if (e == NULL) break; 117 | setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 118 | incr_top(L); 119 | switch (*(e+1)) { 120 | case 's': { 121 | const char *s = va_arg(argp, char *); 122 | if (s == NULL) s = "(null)"; 123 | pushstr(L, s); 124 | break; 125 | } 126 | case 'c': { 127 | char buff[2]; 128 | buff[0] = cast(char, va_arg(argp, int)); 129 | buff[1] = '\0'; 130 | pushstr(L, buff); 131 | break; 132 | } 133 | case 'd': { 134 | setnvalue(L->top, cast_num(va_arg(argp, int))); 135 | incr_top(L); 136 | break; 137 | } 138 | case 'f': { 139 | setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 140 | incr_top(L); 141 | break; 142 | } 143 | case 'p': { 144 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 145 | sprintf(buff, "%p", va_arg(argp, void *)); 146 | pushstr(L, buff); 147 | break; 148 | } 149 | case '%': { 150 | pushstr(L, "%"); 151 | break; 152 | } 153 | default: { 154 | char buff[3]; 155 | buff[0] = '%'; 156 | buff[1] = *(e+1); 157 | buff[2] = '\0'; 158 | pushstr(L, buff); 159 | break; 160 | } 161 | } 162 | n += 2; 163 | fmt = e+2; 164 | } 165 | pushstr(L, fmt); 166 | luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 167 | L->top -= n; 168 | return svalue(L->top - 1); 169 | } 170 | 171 | 172 | const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 173 | const char *msg; 174 | va_list argp; 175 | va_start(argp, fmt); 176 | msg = luaO_pushvfstring(L, fmt, argp); 177 | va_end(argp); 178 | return msg; 179 | } 180 | 181 | 182 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { 183 | if (*source == '=') { 184 | strncpy(out, source+1, bufflen); /* remove first char */ 185 | out[bufflen-1] = '\0'; /* ensures null termination */ 186 | } 187 | else { /* out = "source", or "...source" */ 188 | if (*source == '@') { 189 | size_t l; 190 | source++; /* skip the `@' */ 191 | bufflen -= sizeof(" '...' "); 192 | l = strlen(source); 193 | strcpy(out, ""); 194 | if (l > bufflen) { 195 | source += (l-bufflen); /* get last part of file name */ 196 | strcat(out, "..."); 197 | } 198 | strcat(out, source); 199 | } 200 | else { /* out = [string "string"] */ 201 | size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 202 | bufflen -= sizeof(" [string \"...\"] "); 203 | if (len > bufflen) len = bufflen; 204 | strcpy(out, "[string \""); 205 | if (source[len] != '\0') { /* must truncate? */ 206 | strncat(out, source, len); 207 | strcat(out, "..."); 208 | } 209 | else 210 | strcat(out, source); 211 | strcat(out, "\"]"); 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/lib/lua51/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** See Copyright Notice in lua.h 4 | */ 5 | 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | 11 | #include "lopcodes.h" 12 | 13 | 14 | /* ORDER OP */ 15 | 16 | const char *const luaP_opnames[NUM_OPCODES+1] = { 17 | "MOVE", 18 | "LOADK", 19 | "LOADBOOL", 20 | "LOADNIL", 21 | "GETUPVAL", 22 | "GETGLOBAL", 23 | "GETTABLE", 24 | "SETGLOBAL", 25 | "SETUPVAL", 26 | "SETTABLE", 27 | "NEWTABLE", 28 | "SELF", 29 | "ADD", 30 | "SUB", 31 | "MUL", 32 | "DIV", 33 | "MOD", 34 | "POW", 35 | "UNM", 36 | "NOT", 37 | "LEN", 38 | "CONCAT", 39 | "JMP", 40 | "EQ", 41 | "LT", 42 | "LE", 43 | "TEST", 44 | "TESTSET", 45 | "CALL", 46 | "TAILCALL", 47 | "RETURN", 48 | "FORLOOP", 49 | "FORPREP", 50 | "TFORLOOP", 51 | "SETLIST", 52 | "CLOSE", 53 | "CLOSURE", 54 | "VARARG", 55 | NULL 56 | }; 57 | 58 | 59 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 60 | 61 | const lu_byte luaP_opmodes[NUM_OPCODES] = { 62 | /* T A B C mode opcode */ 63 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 64 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 65 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 66 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ 67 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 68 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ 69 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 70 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ 71 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 72 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 73 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 75 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 83 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 84 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 85 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 89 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ 90 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 91 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 92 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 93 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 94 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 96 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ 97 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ 99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 101 | }; 102 | 103 | -------------------------------------------------------------------------------- /src/lib/lua51/lopcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lopcodes_h 8 | #define lopcodes_h 9 | 10 | #include "llimits.h" 11 | 12 | 13 | /*=========================================================================== 14 | We assume that instructions are unsigned numbers. 15 | All instructions have an opcode in the first 6 bits. 16 | Instructions can have the following fields: 17 | `A' : 8 bits 18 | `B' : 9 bits 19 | `C' : 9 bits 20 | `Bx' : 18 bits (`B' and `C' together) 21 | `sBx' : signed Bx 22 | 23 | A signed argument is represented in excess K; that is, the number 24 | value is the unsigned value minus K. K is exactly the maximum value 25 | for that argument (so that -max is represented by 0, and +max is 26 | represented by 2*max), which is half the maximum for the corresponding 27 | unsigned argument. 28 | ===========================================================================*/ 29 | 30 | 31 | enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ 32 | 33 | 34 | /* 35 | ** size and position of opcode arguments. 36 | */ 37 | #define SIZE_C 9 38 | #define SIZE_B 9 39 | #define SIZE_Bx (SIZE_C + SIZE_B) 40 | #define SIZE_A 8 41 | 42 | #define SIZE_OP 6 43 | 44 | #define POS_OP 0 45 | #define POS_A (POS_OP + SIZE_OP) 46 | #define POS_C (POS_A + SIZE_A) 47 | #define POS_B (POS_C + SIZE_C) 48 | #define POS_Bx POS_C 49 | 50 | 51 | /* 52 | ** limits for opcode arguments. 53 | ** we use (signed) int to manipulate most arguments, 54 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) 55 | */ 56 | #if SIZE_Bx < LUAI_BITSINT-1 57 | #define MAXARG_Bx ((1<>1) /* `sBx' is signed */ 59 | #else 60 | #define MAXARG_Bx MAX_INT 61 | #define MAXARG_sBx MAX_INT 62 | #endif 63 | 64 | 65 | #define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) 81 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 82 | ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) 85 | #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ 86 | ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) 89 | #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ 90 | ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) 93 | #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ 94 | ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) 97 | #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ 98 | ((cast(Instruction, b)< C) then pc++ */ 190 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 191 | 192 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 193 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 194 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 195 | 196 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); 197 | if R(A) =) R(A)*/ 205 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ 206 | 207 | OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ 208 | } OpCode; 209 | 210 | 211 | #define NUM_OPCODES (cast(int, OP_VARARG) + 1) 212 | 213 | 214 | 215 | /*=========================================================================== 216 | Notes: 217 | (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, 218 | and can be 0: OP_CALL then sets `top' to last_result+1, so 219 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. 220 | 221 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and 222 | set top (like in OP_CALL with C == 0). 223 | 224 | (*) In OP_RETURN, if (B == 0) then return up to `top' 225 | 226 | (*) In OP_SETLIST, if (B == 0) then B = `top'; 227 | if (C == 0) then next `instruction' is real C 228 | 229 | (*) For comparisons, A specifies what condition the test should accept 230 | (true or false). 231 | 232 | (*) All `skips' (pc++) assume that next instruction is a jump 233 | ===========================================================================*/ 234 | 235 | 236 | /* 237 | ** masks for instruction properties. The format is: 238 | ** bits 0-1: op mode 239 | ** bits 2-3: C arg mode 240 | ** bits 4-5: B arg mode 241 | ** bit 6: instruction set register A 242 | ** bit 7: operator is a test 243 | */ 244 | 245 | enum OpArgMask { 246 | OpArgN, /* argument is not used */ 247 | OpArgU, /* argument is used */ 248 | OpArgR, /* argument is a register or a jump offset */ 249 | OpArgK /* argument is a constant or register/constant */ 250 | }; 251 | 252 | LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; 253 | 254 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) 255 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) 256 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) 257 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) 258 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) 259 | 260 | 261 | LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ 262 | 263 | 264 | /* number of list items to accumulate before a SETLIST instruction */ 265 | #define LFIELDS_PER_FLUSH 50 266 | 267 | 268 | #endif 269 | -------------------------------------------------------------------------------- /src/lib/lua51/loslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ 3 | ** Standard Operating System library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define loslib_c 15 | #define LUA_LIB 16 | 17 | #include "lua.h" 18 | 19 | #include "lauxlib.h" 20 | #include "lualib.h" 21 | 22 | 23 | static int os_pushresult (lua_State *L, int i, const char *filename) { 24 | int en = errno; /* calls to Lua API may change this value */ 25 | if (i) { 26 | lua_pushboolean(L, 1); 27 | return 1; 28 | } 29 | else { 30 | lua_pushnil(L); 31 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); 32 | lua_pushinteger(L, en); 33 | return 3; 34 | } 35 | } 36 | 37 | 38 | static int os_execute (lua_State *L) { 39 | lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); 40 | return 1; 41 | } 42 | 43 | 44 | static int os_remove (lua_State *L) { 45 | const char *filename = luaL_checkstring(L, 1); 46 | return os_pushresult(L, remove(filename) == 0, filename); 47 | } 48 | 49 | 50 | static int os_rename (lua_State *L) { 51 | const char *fromname = luaL_checkstring(L, 1); 52 | const char *toname = luaL_checkstring(L, 2); 53 | return os_pushresult(L, rename(fromname, toname) == 0, fromname); 54 | } 55 | 56 | 57 | static int os_tmpname (lua_State *L) { 58 | char buff[LUA_TMPNAMBUFSIZE]; 59 | int err; 60 | lua_tmpnam(buff, err); 61 | if (err) 62 | return luaL_error(L, "unable to generate a unique filename"); 63 | lua_pushstring(L, buff); 64 | return 1; 65 | } 66 | 67 | 68 | static int os_getenv (lua_State *L) { 69 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ 70 | return 1; 71 | } 72 | 73 | 74 | static int os_clock (lua_State *L) { 75 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); 76 | return 1; 77 | } 78 | 79 | 80 | /* 81 | ** {====================================================== 82 | ** Time/Date operations 83 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, 84 | ** wday=%w+1, yday=%j, isdst=? } 85 | ** ======================================================= 86 | */ 87 | 88 | static void setfield (lua_State *L, const char *key, int value) { 89 | lua_pushinteger(L, value); 90 | lua_setfield(L, -2, key); 91 | } 92 | 93 | static void setboolfield (lua_State *L, const char *key, int value) { 94 | if (value < 0) /* undefined? */ 95 | return; /* does not set field */ 96 | lua_pushboolean(L, value); 97 | lua_setfield(L, -2, key); 98 | } 99 | 100 | static int getboolfield (lua_State *L, const char *key) { 101 | int res; 102 | lua_getfield(L, -1, key); 103 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); 104 | lua_pop(L, 1); 105 | return res; 106 | } 107 | 108 | 109 | static int getfield (lua_State *L, const char *key, int d) { 110 | int res; 111 | lua_getfield(L, -1, key); 112 | if (lua_isnumber(L, -1)) 113 | res = (int)lua_tointeger(L, -1); 114 | else { 115 | if (d < 0) 116 | return luaL_error(L, "field " LUA_QS " missing in date table", key); 117 | res = d; 118 | } 119 | lua_pop(L, 1); 120 | return res; 121 | } 122 | 123 | 124 | static int os_date (lua_State *L) { 125 | const char *s = luaL_optstring(L, 1, "%c"); 126 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); 127 | struct tm *stm; 128 | if (*s == '!') { /* UTC? */ 129 | stm = gmtime(&t); 130 | s++; /* skip `!' */ 131 | } 132 | else 133 | stm = localtime(&t); 134 | if (stm == NULL) /* invalid date? */ 135 | lua_pushnil(L); 136 | else if (strcmp(s, "*t") == 0) { 137 | lua_createtable(L, 0, 9); /* 9 = number of fields */ 138 | setfield(L, "sec", stm->tm_sec); 139 | setfield(L, "min", stm->tm_min); 140 | setfield(L, "hour", stm->tm_hour); 141 | setfield(L, "day", stm->tm_mday); 142 | setfield(L, "month", stm->tm_mon+1); 143 | setfield(L, "year", stm->tm_year+1900); 144 | setfield(L, "wday", stm->tm_wday+1); 145 | setfield(L, "yday", stm->tm_yday+1); 146 | setboolfield(L, "isdst", stm->tm_isdst); 147 | } 148 | else { 149 | char cc[3]; 150 | luaL_Buffer b; 151 | cc[0] = '%'; cc[2] = '\0'; 152 | luaL_buffinit(L, &b); 153 | for (; *s; s++) { 154 | if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ 155 | luaL_addchar(&b, *s); 156 | else { 157 | size_t reslen; 158 | char buff[200]; /* should be big enough for any conversion result */ 159 | cc[1] = *(++s); 160 | reslen = strftime(buff, sizeof(buff), cc, stm); 161 | luaL_addlstring(&b, buff, reslen); 162 | } 163 | } 164 | luaL_pushresult(&b); 165 | } 166 | return 1; 167 | } 168 | 169 | 170 | static int os_time (lua_State *L) { 171 | time_t t; 172 | if (lua_isnoneornil(L, 1)) /* called without args? */ 173 | t = time(NULL); /* get current time */ 174 | else { 175 | struct tm ts; 176 | luaL_checktype(L, 1, LUA_TTABLE); 177 | lua_settop(L, 1); /* make sure table is at the top */ 178 | ts.tm_sec = getfield(L, "sec", 0); 179 | ts.tm_min = getfield(L, "min", 0); 180 | ts.tm_hour = getfield(L, "hour", 12); 181 | ts.tm_mday = getfield(L, "day", -1); 182 | ts.tm_mon = getfield(L, "month", -1) - 1; 183 | ts.tm_year = getfield(L, "year", -1) - 1900; 184 | ts.tm_isdst = getboolfield(L, "isdst"); 185 | t = mktime(&ts); 186 | } 187 | if (t == (time_t)(-1)) 188 | lua_pushnil(L); 189 | else 190 | lua_pushnumber(L, (lua_Number)t); 191 | return 1; 192 | } 193 | 194 | 195 | static int os_difftime (lua_State *L) { 196 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), 197 | (time_t)(luaL_optnumber(L, 2, 0)))); 198 | return 1; 199 | } 200 | 201 | /* }====================================================== */ 202 | 203 | 204 | static int os_setlocale (lua_State *L) { 205 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, 206 | LC_NUMERIC, LC_TIME}; 207 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", 208 | "numeric", "time", NULL}; 209 | const char *l = luaL_optstring(L, 1, NULL); 210 | int op = luaL_checkoption(L, 2, "all", catnames); 211 | lua_pushstring(L, setlocale(cat[op], l)); 212 | return 1; 213 | } 214 | 215 | 216 | static int os_exit (lua_State *L) { 217 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); 218 | } 219 | 220 | static const luaL_Reg syslib[] = { 221 | {"clock", os_clock}, 222 | {"date", os_date}, 223 | {"difftime", os_difftime}, 224 | {"execute", os_execute}, 225 | {"exit", os_exit}, 226 | {"getenv", os_getenv}, 227 | {"remove", os_remove}, 228 | {"rename", os_rename}, 229 | {"setlocale", os_setlocale}, 230 | {"time", os_time}, 231 | {"tmpname", os_tmpname}, 232 | {NULL, NULL} 233 | }; 234 | 235 | /* }====================================================== */ 236 | 237 | 238 | 239 | LUALIB_API int luaopen_os (lua_State *L) { 240 | luaL_register(L, LUA_OSLIBNAME, syslib); 241 | return 1; 242 | } 243 | 244 | -------------------------------------------------------------------------------- /src/lib/lua51/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression descriptor 17 | */ 18 | 19 | typedef enum { 20 | VVOID, /* no value */ 21 | VNIL, 22 | VTRUE, 23 | VFALSE, 24 | VK, /* info = index of constant in `k' */ 25 | VKNUM, /* nval = numerical value */ 26 | VLOCAL, /* info = local register */ 27 | VUPVAL, /* info = index of upvalue in `upvalues' */ 28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ 29 | VINDEXED, /* info = table register; aux = index register (or `k') */ 30 | VJMP, /* info = instruction pc */ 31 | VRELOCABLE, /* info = instruction pc */ 32 | VNONRELOC, /* info = result register */ 33 | VCALL, /* info = instruction pc */ 34 | VVARARG /* info = instruction pc */ 35 | } expkind; 36 | 37 | typedef struct expdesc { 38 | expkind k; 39 | union { 40 | struct { int info, aux; } s; 41 | lua_Number nval; 42 | } u; 43 | int t; /* patch list of `exit when true' */ 44 | int f; /* patch list of `exit when false' */ 45 | } expdesc; 46 | 47 | 48 | typedef struct upvaldesc { 49 | lu_byte k; 50 | lu_byte info; 51 | } upvaldesc; 52 | 53 | 54 | struct BlockCnt; /* defined in lparser.c */ 55 | 56 | 57 | /* state needed to generate code for a given function */ 58 | typedef struct FuncState { 59 | Proto *f; /* current function header */ 60 | Table *h; /* table to find (and reuse) elements in `k' */ 61 | struct FuncState *prev; /* enclosing function */ 62 | struct LexState *ls; /* lexical state */ 63 | struct lua_State *L; /* copy of the Lua state */ 64 | struct BlockCnt *bl; /* chain of current blocks */ 65 | int pc; /* next position to code (equivalent to `ncode') */ 66 | int lasttarget; /* `pc' of last `jump target' */ 67 | int jpc; /* list of pending jumps to `pc' */ 68 | int freereg; /* first free register */ 69 | int nk; /* number of elements in `k' */ 70 | int np; /* number of elements in `p' */ 71 | short nlocvars; /* number of elements in `locvars' */ 72 | lu_byte nactvar; /* number of active local variables */ 73 | upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ 74 | unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ 75 | } FuncState; 76 | 77 | 78 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 79 | const char *name); 80 | 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/lib/lua51/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstate_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "llex.h" 20 | #include "lmem.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | 26 | 27 | #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) 28 | #define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) 29 | #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) 30 | 31 | 32 | /* 33 | ** Main thread combines a thread state and the global state 34 | */ 35 | typedef struct LG { 36 | lua_State l; 37 | global_State g; 38 | } LG; 39 | 40 | 41 | 42 | static void stack_init (lua_State *L1, lua_State *L) { 43 | /* initialize CallInfo array */ 44 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 45 | L1->ci = L1->base_ci; 46 | L1->size_ci = BASIC_CI_SIZE; 47 | L1->end_ci = L1->base_ci + L1->size_ci - 1; 48 | /* initialize stack array */ 49 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 50 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 51 | L1->top = L1->stack; 52 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 53 | /* initialize first ci */ 54 | L1->ci->func = L1->top; 55 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ 56 | L1->base = L1->ci->base = L1->top; 57 | L1->ci->top = L1->top + LUA_MINSTACK; 58 | } 59 | 60 | 61 | static void freestack (lua_State *L, lua_State *L1) { 62 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 63 | luaM_freearray(L, L1->stack, L1->stacksize, TValue); 64 | } 65 | 66 | 67 | /* 68 | ** open parts that may cause memory-allocation errors 69 | */ 70 | static void f_luaopen (lua_State *L, void *ud) { 71 | global_State *g = G(L); 72 | UNUSED(ud); 73 | stack_init(L, L); /* init stack */ 74 | sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ 75 | sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ 76 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 77 | luaT_init(L); 78 | luaX_init(L); 79 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); 80 | g->GCthreshold = 4*g->totalbytes; 81 | } 82 | 83 | 84 | static void preinit_state (lua_State *L, global_State *g) { 85 | G(L) = g; 86 | L->stack = NULL; 87 | L->stacksize = 0; 88 | L->errorJmp = NULL; 89 | L->hook = NULL; 90 | L->hookmask = 0; 91 | L->basehookcount = 0; 92 | L->allowhook = 1; 93 | resethookcount(L); 94 | L->openupval = NULL; 95 | L->size_ci = 0; 96 | L->nCcalls = L->baseCcalls = 0; 97 | L->status = 0; 98 | L->base_ci = L->ci = NULL; 99 | L->savedpc = NULL; 100 | L->errfunc = 0; 101 | setnilvalue(gt(L)); 102 | } 103 | 104 | 105 | static void close_state (lua_State *L) { 106 | global_State *g = G(L); 107 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 108 | luaC_freeall(L); /* collect all objects */ 109 | lua_assert(g->rootgc == obj2gco(L)); 110 | lua_assert(g->strt.nuse == 0); 111 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 112 | luaZ_freebuffer(L, &g->buff); 113 | freestack(L, L); 114 | lua_assert(g->totalbytes == sizeof(LG)); 115 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 116 | } 117 | 118 | 119 | lua_State *luaE_newthread (lua_State *L) { 120 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); 121 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); 122 | preinit_state(L1, G(L)); 123 | stack_init(L1, L); /* init stack */ 124 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ 125 | L1->hookmask = L->hookmask; 126 | L1->basehookcount = L->basehookcount; 127 | L1->hook = L->hook; 128 | resethookcount(L1); 129 | lua_assert(iswhite(obj2gco(L1))); 130 | return L1; 131 | } 132 | 133 | 134 | void luaE_freethread (lua_State *L, lua_State *L1) { 135 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 136 | lua_assert(L1->openupval == NULL); 137 | luai_userstatefree(L1); 138 | freestack(L, L1); 139 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); 140 | } 141 | 142 | 143 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 144 | int i; 145 | lua_State *L; 146 | global_State *g; 147 | void *l = (*f)(ud, NULL, 0, state_size(LG)); 148 | if (l == NULL) return NULL; 149 | L = tostate(l); 150 | g = &((LG *)L)->g; 151 | L->next = NULL; 152 | L->tt = LUA_TTHREAD; 153 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 154 | L->marked = luaC_white(g); 155 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); 156 | preinit_state(L, g); 157 | g->frealloc = f; 158 | g->ud = ud; 159 | g->mainthread = L; 160 | g->uvhead.u.l.prev = &g->uvhead; 161 | g->uvhead.u.l.next = &g->uvhead; 162 | g->GCthreshold = 0; /* mark it as unfinished state */ 163 | g->strt.size = 0; 164 | g->strt.nuse = 0; 165 | g->strt.hash = NULL; 166 | setnilvalue(registry(L)); 167 | luaZ_initbuffer(L, &g->buff); 168 | g->panic = NULL; 169 | g->gcstate = GCSpause; 170 | g->rootgc = obj2gco(L); 171 | g->sweepstrgc = 0; 172 | g->sweepgc = &g->rootgc; 173 | g->gray = NULL; 174 | g->grayagain = NULL; 175 | g->weak = NULL; 176 | g->tmudata = NULL; 177 | g->totalbytes = sizeof(LG); 178 | g->gcpause = LUAI_GCPAUSE; 179 | g->gcstepmul = LUAI_GCMUL; 180 | g->gcdept = 0; 181 | for (i=0; imt[i] = NULL; 182 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { 183 | /* memory allocation error: free partial state */ 184 | close_state(L); 185 | L = NULL; 186 | } 187 | else 188 | luai_userstateopen(L); 189 | return L; 190 | } 191 | 192 | 193 | static void callallgcTM (lua_State *L, void *ud) { 194 | UNUSED(ud); 195 | luaC_callGCTM(L); /* call GC metamethods for all udata */ 196 | } 197 | 198 | 199 | LUA_API void lua_close (lua_State *L) { 200 | L = G(L)->mainthread; /* only the main thread can be closed */ 201 | lua_lock(L); 202 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 203 | luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ 204 | L->errfunc = 0; /* no error function during GC metamethods */ 205 | do { /* repeat until no more errors */ 206 | L->ci = L->base_ci; 207 | L->base = L->top = L->ci->base; 208 | L->nCcalls = L->baseCcalls = 0; 209 | } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); 210 | lua_assert(G(L)->tmudata == NULL); 211 | luai_userstateclose(L); 212 | close_state(L); 213 | } 214 | 215 | -------------------------------------------------------------------------------- /src/lib/lua51/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstate_h 8 | #define lstate_h 9 | 10 | #include "lua.h" 11 | 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | #include "lzio.h" 15 | 16 | 17 | 18 | struct lua_longjmp; /* defined in ldo.c */ 19 | 20 | 21 | /* table of globals */ 22 | #define gt(L) (&L->l_gt) 23 | 24 | /* registry */ 25 | #define registry(L) (&G(L)->l_registry) 26 | 27 | 28 | /* extra stack space to handle TM calls and some other extras */ 29 | #define EXTRA_STACK 5 30 | 31 | 32 | #define BASIC_CI_SIZE 8 33 | 34 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 35 | 36 | 37 | 38 | typedef struct stringtable { 39 | GCObject **hash; 40 | lu_int32 nuse; /* number of elements */ 41 | int size; 42 | } stringtable; 43 | 44 | 45 | /* 46 | ** informations about a call 47 | */ 48 | typedef struct CallInfo { 49 | StkId base; /* base for this function */ 50 | StkId func; /* function index in the stack */ 51 | StkId top; /* top for this function */ 52 | const Instruction *savedpc; 53 | int nresults; /* expected number of results from this function */ 54 | int tailcalls; /* number of tail calls lost under this entry */ 55 | } CallInfo; 56 | 57 | 58 | 59 | #define curr_func(L) (clvalue(L->ci->func)) 60 | #define ci_func(ci) (clvalue((ci)->func)) 61 | #define f_isLua(ci) (!ci_func(ci)->c.isC) 62 | #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) 63 | 64 | 65 | /* 66 | ** `global state', shared by all threads of this state 67 | */ 68 | typedef struct global_State { 69 | stringtable strt; /* hash table for strings */ 70 | lua_Alloc frealloc; /* function to reallocate memory */ 71 | void *ud; /* auxiliary data to `frealloc' */ 72 | lu_byte currentwhite; 73 | lu_byte gcstate; /* state of garbage collector */ 74 | int sweepstrgc; /* position of sweep in `strt' */ 75 | GCObject *rootgc; /* list of all collectable objects */ 76 | GCObject **sweepgc; /* position of sweep in `rootgc' */ 77 | GCObject *gray; /* list of gray objects */ 78 | GCObject *grayagain; /* list of objects to be traversed atomically */ 79 | GCObject *weak; /* list of weak tables (to be cleared) */ 80 | GCObject *tmudata; /* last element of list of userdata to be GC */ 81 | Mbuffer buff; /* temporary buffer for string concatentation */ 82 | lu_mem GCthreshold; 83 | lu_mem totalbytes; /* number of bytes currently allocated */ 84 | lu_mem estimate; /* an estimate of number of bytes actually in use */ 85 | lu_mem gcdept; /* how much GC is `behind schedule' */ 86 | int gcpause; /* size of pause between successive GCs */ 87 | int gcstepmul; /* GC `granularity' */ 88 | lua_CFunction panic; /* to be called in unprotected errors */ 89 | TValue l_registry; 90 | struct lua_State *mainthread; 91 | UpVal uvhead; /* head of double-linked list of all open upvalues */ 92 | struct Table *mt[NUM_TAGS]; /* metatables for basic types */ 93 | TString *tmname[TM_N]; /* array with tag-method names */ 94 | } global_State; 95 | 96 | 97 | /* 98 | ** `per thread' state 99 | */ 100 | struct lua_State { 101 | CommonHeader; 102 | lu_byte status; 103 | StkId top; /* first free slot in the stack */ 104 | StkId base; /* base of current function */ 105 | global_State *l_G; 106 | CallInfo *ci; /* call info for current function */ 107 | const Instruction *savedpc; /* `savedpc' of current function */ 108 | StkId stack_last; /* last free slot in the stack */ 109 | StkId stack; /* stack base */ 110 | CallInfo *end_ci; /* points after end of ci array*/ 111 | CallInfo *base_ci; /* array of CallInfo's */ 112 | int stacksize; 113 | int size_ci; /* size of array `base_ci' */ 114 | unsigned short nCcalls; /* number of nested C calls */ 115 | unsigned short baseCcalls; /* nested C calls when resuming coroutine */ 116 | lu_byte hookmask; 117 | lu_byte allowhook; 118 | int basehookcount; 119 | int hookcount; 120 | lua_Hook hook; 121 | TValue l_gt; /* table of globals */ 122 | TValue env; /* temporary place for environments */ 123 | GCObject *openupval; /* list of open upvalues in this stack */ 124 | GCObject *gclist; 125 | struct lua_longjmp *errorJmp; /* current error recover point */ 126 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 127 | }; 128 | 129 | 130 | #define G(L) (L->l_G) 131 | 132 | 133 | /* 134 | ** Union of all collectable objects 135 | */ 136 | union GCObject { 137 | GCheader gch; 138 | union TString ts; 139 | union Udata u; 140 | union Closure cl; 141 | struct Table h; 142 | struct Proto p; 143 | struct UpVal uv; 144 | struct lua_State th; /* thread */ 145 | }; 146 | 147 | 148 | /* macros to convert a GCObject into a specific value */ 149 | #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) 150 | #define gco2ts(o) (&rawgco2ts(o)->tsv) 151 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 152 | #define gco2u(o) (&rawgco2u(o)->uv) 153 | #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) 154 | #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 155 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 156 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 157 | #define ngcotouv(o) \ 158 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 159 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 160 | 161 | /* macro to convert any Lua object into a GCObject */ 162 | #define obj2gco(v) (cast(GCObject *, (v))) 163 | 164 | 165 | LUAI_FUNC lua_State *luaE_newthread (lua_State *L); 166 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 167 | 168 | #endif 169 | 170 | -------------------------------------------------------------------------------- /src/lib/lua51/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstring_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lmem.h" 16 | #include "lobject.h" 17 | #include "lstate.h" 18 | #include "lstring.h" 19 | 20 | 21 | 22 | void luaS_resize (lua_State *L, int newsize) { 23 | GCObject **newhash; 24 | stringtable *tb; 25 | int i; 26 | if (G(L)->gcstate == GCSsweepstring) 27 | return; /* cannot resize during GC traverse */ 28 | newhash = luaM_newvector(L, newsize, GCObject *); 29 | tb = &G(L)->strt; 30 | for (i=0; isize; i++) { 33 | GCObject *p = tb->hash[i]; 34 | while (p) { /* for each node in the list */ 35 | GCObject *next = p->gch.next; /* save next */ 36 | unsigned int h = gco2ts(p)->hash; 37 | int h1 = lmod(h, newsize); /* new position */ 38 | lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 39 | p->gch.next = newhash[h1]; /* chain it */ 40 | newhash[h1] = p; 41 | p = next; 42 | } 43 | } 44 | luaM_freearray(L, tb->hash, tb->size, TString *); 45 | tb->size = newsize; 46 | tb->hash = newhash; 47 | } 48 | 49 | 50 | static TString *newlstr (lua_State *L, const char *str, size_t l, 51 | unsigned int h) { 52 | TString *ts; 53 | stringtable *tb; 54 | if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 55 | luaM_toobig(L); 56 | ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); 57 | ts->tsv.len = l; 58 | ts->tsv.hash = h; 59 | ts->tsv.marked = luaC_white(G(L)); 60 | ts->tsv.tt = LUA_TSTRING; 61 | ts->tsv.reserved = 0; 62 | memcpy(ts+1, str, l*sizeof(char)); 63 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 64 | tb = &G(L)->strt; 65 | h = lmod(h, tb->size); 66 | ts->tsv.next = tb->hash[h]; /* chain new entry */ 67 | tb->hash[h] = obj2gco(ts); 68 | tb->nuse++; 69 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) 70 | luaS_resize(L, tb->size*2); /* too crowded */ 71 | return ts; 72 | } 73 | 74 | 75 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 76 | GCObject *o; 77 | unsigned int h = cast(unsigned int, l); /* seed */ 78 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ 79 | size_t l1; 80 | for (l1=l; l1>=step; l1-=step) /* compute hash */ 81 | h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); 82 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; 83 | o != NULL; 84 | o = o->gch.next) { 85 | TString *ts = rawgco2ts(o); 86 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { 87 | /* string may be dead */ 88 | if (isdead(G(L), o)) changewhite(o); 89 | return ts; 90 | } 91 | } 92 | return newlstr(L, str, l, h); /* not found */ 93 | } 94 | 95 | 96 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { 97 | Udata *u; 98 | if (s > MAX_SIZET - sizeof(Udata)) 99 | luaM_toobig(L); 100 | u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); 101 | u->uv.marked = luaC_white(G(L)); /* is not finalized */ 102 | u->uv.tt = LUA_TUSERDATA; 103 | u->uv.len = s; 104 | u->uv.metatable = NULL; 105 | u->uv.env = e; 106 | /* chain it on udata list (after main thread) */ 107 | u->uv.next = G(L)->mainthread->next; 108 | G(L)->mainthread->next = obj2gco(u); 109 | return u; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /src/lib/lua51/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | 11 | #include "lgc.h" 12 | #include "lobject.h" 13 | #include "lstate.h" 14 | 15 | 16 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 17 | 18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) 19 | 20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) 21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 22 | (sizeof(s)/sizeof(char))-1)) 23 | 24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 25 | 26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/lib/lua51/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gkey(n) (&(n)->i_key.nk) 15 | #define gval(n) (&(n)->i_val) 16 | #define gnext(n) ((n)->i_key.nk.next) 17 | 18 | #define key2tval(n) (&(n)->i_key.tvk) 19 | 20 | 21 | LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); 22 | LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); 23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 24 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); 25 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 27 | LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); 28 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 29 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 30 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 31 | LUAI_FUNC int luaH_getn (Table *t); 32 | 33 | 34 | #if defined(LUA_DEBUG) 35 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 36 | LUAI_FUNC int luaH_isdummy (Node *n); 37 | #endif 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/lib/lua51/ltablib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ 3 | ** Library for Table Manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define ltablib_c 11 | #define LUA_LIB 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) 20 | 21 | 22 | static int foreachi (lua_State *L) { 23 | int i; 24 | int n = aux_getn(L, 1); 25 | luaL_checktype(L, 2, LUA_TFUNCTION); 26 | for (i=1; i <= n; i++) { 27 | lua_pushvalue(L, 2); /* function */ 28 | lua_pushinteger(L, i); /* 1st argument */ 29 | lua_rawgeti(L, 1, i); /* 2nd argument */ 30 | lua_call(L, 2, 1); 31 | if (!lua_isnil(L, -1)) 32 | return 1; 33 | lua_pop(L, 1); /* remove nil result */ 34 | } 35 | return 0; 36 | } 37 | 38 | 39 | static int foreach (lua_State *L) { 40 | luaL_checktype(L, 1, LUA_TTABLE); 41 | luaL_checktype(L, 2, LUA_TFUNCTION); 42 | lua_pushnil(L); /* first key */ 43 | while (lua_next(L, 1)) { 44 | lua_pushvalue(L, 2); /* function */ 45 | lua_pushvalue(L, -3); /* key */ 46 | lua_pushvalue(L, -3); /* value */ 47 | lua_call(L, 2, 1); 48 | if (!lua_isnil(L, -1)) 49 | return 1; 50 | lua_pop(L, 2); /* remove value and result */ 51 | } 52 | return 0; 53 | } 54 | 55 | 56 | static int maxn (lua_State *L) { 57 | lua_Number max = 0; 58 | luaL_checktype(L, 1, LUA_TTABLE); 59 | lua_pushnil(L); /* first key */ 60 | while (lua_next(L, 1)) { 61 | lua_pop(L, 1); /* remove value */ 62 | if (lua_type(L, -1) == LUA_TNUMBER) { 63 | lua_Number v = lua_tonumber(L, -1); 64 | if (v > max) max = v; 65 | } 66 | } 67 | lua_pushnumber(L, max); 68 | return 1; 69 | } 70 | 71 | 72 | static int getn (lua_State *L) { 73 | lua_pushinteger(L, aux_getn(L, 1)); 74 | return 1; 75 | } 76 | 77 | 78 | static int setn (lua_State *L) { 79 | luaL_checktype(L, 1, LUA_TTABLE); 80 | #ifndef luaL_setn 81 | luaL_setn(L, 1, luaL_checkint(L, 2)); 82 | #else 83 | luaL_error(L, LUA_QL("setn") " is obsolete"); 84 | #endif 85 | lua_pushvalue(L, 1); 86 | return 1; 87 | } 88 | 89 | 90 | static int tinsert (lua_State *L) { 91 | int e = aux_getn(L, 1) + 1; /* first empty element */ 92 | int pos; /* where to insert new element */ 93 | switch (lua_gettop(L)) { 94 | case 2: { /* called with only 2 arguments */ 95 | pos = e; /* insert new element at the end */ 96 | break; 97 | } 98 | case 3: { 99 | int i; 100 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 101 | if (pos > e) e = pos; /* `grow' array if necessary */ 102 | for (i = e; i > pos; i--) { /* move up elements */ 103 | lua_rawgeti(L, 1, i-1); 104 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ 105 | } 106 | break; 107 | } 108 | default: { 109 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); 110 | } 111 | } 112 | luaL_setn(L, 1, e); /* new size */ 113 | lua_rawseti(L, 1, pos); /* t[pos] = v */ 114 | return 0; 115 | } 116 | 117 | 118 | static int tremove (lua_State *L) { 119 | int e = aux_getn(L, 1); 120 | int pos = luaL_optint(L, 2, e); 121 | if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ 122 | return 0; /* nothing to remove */ 123 | luaL_setn(L, 1, e - 1); /* t.n = n-1 */ 124 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ 125 | for ( ;pos= P */ 226 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { 227 | if (i>u) luaL_error(L, "invalid order function for sorting"); 228 | lua_pop(L, 1); /* remove a[i] */ 229 | } 230 | /* repeat --j until a[j] <= P */ 231 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { 232 | if (j 9 | 10 | #define ltm_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lobject.h" 16 | #include "lstate.h" 17 | #include "lstring.h" 18 | #include "ltable.h" 19 | #include "ltm.h" 20 | 21 | 22 | 23 | const char *const luaT_typenames[] = { 24 | "nil", "boolean", "userdata", "number", 25 | "string", "table", "function", "userdata", "thread", 26 | "proto", "upval" 27 | }; 28 | 29 | 30 | void luaT_init (lua_State *L) { 31 | static const char *const luaT_eventname[] = { /* ORDER TM */ 32 | "__index", "__newindex", 33 | "__gc", "__mode", "__eq", 34 | "__add", "__sub", "__mul", "__div", "__mod", 35 | "__pow", "__unm", "__len", "__lt", "__le", 36 | "__concat", "__call" 37 | }; 38 | int i; 39 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 41 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ 42 | } 43 | } 44 | 45 | 46 | /* 47 | ** function to be used with macro "fasttm": optimized for absence of 48 | ** tag methods 49 | */ 50 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 51 | const TValue *tm = luaH_getstr(events, ename); 52 | lua_assert(event <= TM_EQ); 53 | if (ttisnil(tm)) { /* no tag method? */ 54 | events->flags |= cast_byte(1u<metatable; 66 | break; 67 | case LUA_TUSERDATA: 68 | mt = uvalue(o)->metatable; 69 | break; 70 | default: 71 | mt = G(L)->mt[ttype(o)]; 72 | } 73 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/lib/lua51/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_EQ, /* last tag method with `fast' access */ 24 | TM_ADD, 25 | TM_SUB, 26 | TM_MUL, 27 | TM_DIV, 28 | TM_MOD, 29 | TM_POW, 30 | TM_UNM, 31 | TM_LEN, 32 | TM_LT, 33 | TM_LE, 34 | TM_CONCAT, 35 | TM_CALL, 36 | TM_N /* number of elements in the enum */ 37 | } TMS; 38 | 39 | 40 | 41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 43 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 45 | 46 | LUAI_DATA const char *const luaT_typenames[]; 47 | 48 | 49 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 50 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 51 | TMS event); 52 | LUAI_FUNC void luaT_init (lua_State *L); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/lib/lua51/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* Key to file-handle type */ 15 | #define LUA_FILEHANDLE "FILE*" 16 | 17 | 18 | #define LUA_COLIBNAME "coroutine" 19 | LUALIB_API int (luaopen_base) (lua_State *L); 20 | 21 | #define LUA_TABLIBNAME "table" 22 | LUALIB_API int (luaopen_table) (lua_State *L); 23 | 24 | #define LUA_IOLIBNAME "io" 25 | LUALIB_API int (luaopen_io) (lua_State *L); 26 | 27 | #define LUA_OSLIBNAME "os" 28 | LUALIB_API int (luaopen_os) (lua_State *L); 29 | 30 | #define LUA_STRLIBNAME "string" 31 | LUALIB_API int (luaopen_string) (lua_State *L); 32 | 33 | #define LUA_MATHLIBNAME "math" 34 | LUALIB_API int (luaopen_math) (lua_State *L); 35 | 36 | #define LUA_DBLIBNAME "debug" 37 | LUALIB_API int (luaopen_debug) (lua_State *L); 38 | 39 | #define LUA_LOADLIBNAME "package" 40 | LUALIB_API int (luaopen_package) (lua_State *L); 41 | 42 | 43 | /* open all previous libraries */ 44 | LUALIB_API void (luaL_openlibs) (lua_State *L); 45 | 46 | 47 | 48 | #ifndef lua_assert 49 | #define lua_assert(x) ((void)0) 50 | #endif 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/lib/lua51/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define lundump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "ldebug.h" 15 | #include "ldo.h" 16 | #include "lfunc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstring.h" 20 | #include "lundump.h" 21 | #include "lzio.h" 22 | 23 | typedef struct { 24 | lua_State* L; 25 | ZIO* Z; 26 | Mbuffer* b; 27 | const char* name; 28 | } LoadState; 29 | 30 | #ifdef LUAC_TRUST_BINARIES 31 | #define IF(c,s) 32 | #define error(S,s) 33 | #else 34 | #define IF(c,s) if (c) error(S,s) 35 | 36 | static void error(LoadState* S, const char* why) 37 | { 38 | luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); 39 | luaD_throw(S->L,LUA_ERRSYNTAX); 40 | } 41 | #endif 42 | 43 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 44 | #define LoadByte(S) (lu_byte)LoadChar(S) 45 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 46 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 47 | 48 | static void LoadBlock(LoadState* S, void* b, size_t size) 49 | { 50 | size_t r=luaZ_read(S->Z,b,size); 51 | IF (r!=0, "unexpected end"); 52 | } 53 | 54 | static int LoadChar(LoadState* S) 55 | { 56 | char x; 57 | LoadVar(S,x); 58 | return x; 59 | } 60 | 61 | static int LoadInt(LoadState* S) 62 | { 63 | int x; 64 | LoadVar(S,x); 65 | IF (x<0, "bad integer"); 66 | return x; 67 | } 68 | 69 | static lua_Number LoadNumber(LoadState* S) 70 | { 71 | lua_Number x; 72 | LoadVar(S,x); 73 | return x; 74 | } 75 | 76 | static TString* LoadString(LoadState* S) 77 | { 78 | size_t size; 79 | LoadVar(S,size); 80 | if (size==0) 81 | return NULL; 82 | else 83 | { 84 | char* s=luaZ_openspace(S->L,S->b,size); 85 | LoadBlock(S,s,size); 86 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 87 | } 88 | } 89 | 90 | static void LoadCode(LoadState* S, Proto* f) 91 | { 92 | int n=LoadInt(S); 93 | f->code=luaM_newvector(S->L,n,Instruction); 94 | f->sizecode=n; 95 | LoadVector(S,f->code,n,sizeof(Instruction)); 96 | } 97 | 98 | static Proto* LoadFunction(LoadState* S, TString* p); 99 | 100 | static void LoadConstants(LoadState* S, Proto* f) 101 | { 102 | int i,n; 103 | n=LoadInt(S); 104 | f->k=luaM_newvector(S->L,n,TValue); 105 | f->sizek=n; 106 | for (i=0; ik[i]); 107 | for (i=0; ik[i]; 110 | int t=LoadChar(S); 111 | switch (t) 112 | { 113 | case LUA_TNIL: 114 | setnilvalue(o); 115 | break; 116 | case LUA_TBOOLEAN: 117 | setbvalue(o,LoadChar(S)!=0); 118 | break; 119 | case LUA_TNUMBER: 120 | setnvalue(o,LoadNumber(S)); 121 | break; 122 | case LUA_TSTRING: 123 | setsvalue2n(S->L,o,LoadString(S)); 124 | break; 125 | default: 126 | error(S,"bad constant"); 127 | break; 128 | } 129 | } 130 | n=LoadInt(S); 131 | f->p=luaM_newvector(S->L,n,Proto*); 132 | f->sizep=n; 133 | for (i=0; ip[i]=NULL; 134 | for (i=0; ip[i]=LoadFunction(S,f->source); 135 | } 136 | 137 | static void LoadDebug(LoadState* S, Proto* f) 138 | { 139 | int i,n; 140 | n=LoadInt(S); 141 | f->lineinfo=luaM_newvector(S->L,n,int); 142 | f->sizelineinfo=n; 143 | LoadVector(S,f->lineinfo,n,sizeof(int)); 144 | n=LoadInt(S); 145 | f->locvars=luaM_newvector(S->L,n,LocVar); 146 | f->sizelocvars=n; 147 | for (i=0; ilocvars[i].varname=NULL; 148 | for (i=0; ilocvars[i].varname=LoadString(S); 151 | f->locvars[i].startpc=LoadInt(S); 152 | f->locvars[i].endpc=LoadInt(S); 153 | } 154 | n=LoadInt(S); 155 | f->upvalues=luaM_newvector(S->L,n,TString*); 156 | f->sizeupvalues=n; 157 | for (i=0; iupvalues[i]=NULL; 158 | for (i=0; iupvalues[i]=LoadString(S); 159 | } 160 | 161 | static Proto* LoadFunction(LoadState* S, TString* p) 162 | { 163 | Proto* f; 164 | if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); 165 | f=luaF_newproto(S->L); 166 | setptvalue2s(S->L,S->L->top,f); incr_top(S->L); 167 | f->source=LoadString(S); if (f->source==NULL) f->source=p; 168 | f->linedefined=LoadInt(S); 169 | f->lastlinedefined=LoadInt(S); 170 | f->nups=LoadByte(S); 171 | f->numparams=LoadByte(S); 172 | f->is_vararg=LoadByte(S); 173 | f->maxstacksize=LoadByte(S); 174 | LoadCode(S,f); 175 | LoadConstants(S,f); 176 | LoadDebug(S,f); 177 | IF (!luaG_checkcode(f), "bad code"); 178 | S->L->top--; 179 | S->L->nCcalls--; 180 | return f; 181 | } 182 | 183 | static void LoadHeader(LoadState* S) 184 | { 185 | char h[LUAC_HEADERSIZE]; 186 | char s[LUAC_HEADERSIZE]; 187 | luaU_header(h); 188 | LoadBlock(S,s,LUAC_HEADERSIZE); 189 | IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); 190 | } 191 | 192 | /* 193 | ** load precompiled chunk 194 | */ 195 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 196 | { 197 | LoadState S; 198 | if (*name=='@' || *name=='=') 199 | S.name=name+1; 200 | else if (*name==LUA_SIGNATURE[0]) 201 | S.name="binary string"; 202 | else 203 | S.name=name; 204 | S.L=L; 205 | S.Z=Z; 206 | S.b=buff; 207 | LoadHeader(&S); 208 | return LoadFunction(&S,luaS_newliteral(L,"=?")); 209 | } 210 | 211 | /* 212 | * make header 213 | */ 214 | void luaU_header (char* h) 215 | { 216 | int x=1; 217 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); 218 | h+=sizeof(LUA_SIGNATURE)-1; 219 | *h++=(char)LUAC_VERSION; 220 | *h++=(char)LUAC_FORMAT; 221 | *h++=(char)*(char*)&x; /* endianness */ 222 | *h++=(char)sizeof(int); 223 | *h++=(char)sizeof(size_t); 224 | *h++=(char)sizeof(Instruction); 225 | *h++=(char)sizeof(lua_Number); 226 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ 227 | } 228 | -------------------------------------------------------------------------------- /src/lib/lua51/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | /* load one chunk; from lundump.c */ 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); 15 | 16 | /* make header; from lundump.c */ 17 | LUAI_FUNC void luaU_header (char* h); 18 | 19 | /* dump one chunk; from ldump.c */ 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); 21 | 22 | #ifdef luac_c 23 | /* print one chunk; from print.c */ 24 | LUAI_FUNC void luaU_print (const Proto* f, int full); 25 | #endif 26 | 27 | /* for header of binary files -- this is Lua 5.1 */ 28 | #define LUAC_VERSION 0x51 29 | 30 | /* for header of binary files -- this is the official format */ 31 | #define LUAC_FORMAT 0 32 | 33 | /* size of header of binary files */ 34 | #define LUAC_HEADERSIZE 12 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lib/lua51/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) 17 | 18 | #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ 19 | (((o) = luaV_tonumber(o,n)) != NULL)) 20 | 21 | #define equalobj(L,o1,o2) \ 22 | (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) 23 | 24 | 25 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 26 | LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); 27 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 28 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 29 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 30 | StkId val); 31 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 32 | StkId val); 33 | LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); 34 | LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lib/lua51/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** a generic input stream interface 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lzio_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "llimits.h" 16 | #include "lmem.h" 17 | #include "lstate.h" 18 | #include "lzio.h" 19 | 20 | 21 | int luaZ_fill (ZIO *z) { 22 | size_t size; 23 | lua_State *L = z->L; 24 | const char *buff; 25 | lua_unlock(L); 26 | buff = z->reader(L, z->data, &size); 27 | lua_lock(L); 28 | if (buff == NULL || size == 0) return EOZ; 29 | z->n = size - 1; 30 | z->p = buff; 31 | return char2int(*(z->p++)); 32 | } 33 | 34 | 35 | int luaZ_lookahead (ZIO *z) { 36 | if (z->n == 0) { 37 | if (luaZ_fill(z) == EOZ) 38 | return EOZ; 39 | else { 40 | z->n++; /* luaZ_fill removed first byte; put back it */ 41 | z->p--; 42 | } 43 | } 44 | return char2int(*z->p); 45 | } 46 | 47 | 48 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 49 | z->L = L; 50 | z->reader = reader; 51 | z->data = data; 52 | z->n = 0; 53 | z->p = NULL; 54 | } 55 | 56 | 57 | /* --------------------------------------------------------------- read --- */ 58 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 59 | while (n) { 60 | size_t m; 61 | if (luaZ_lookahead(z) == EOZ) 62 | return n; /* return number of missing bytes */ 63 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 64 | memcpy(b, z->p, m); 65 | z->n -= m; 66 | z->p += m; 67 | b = (char *)b + m; 68 | n -= m; 69 | } 70 | return 0; 71 | } 72 | 73 | /* ------------------------------------------------------------------------ */ 74 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 75 | if (n > buff->buffsize) { 76 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 77 | luaZ_resizebuffer(L, buff, n); 78 | } 79 | return buff->buffer; 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/lib/lua51/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define char2int(c) cast(int, cast(unsigned char, (c))) 21 | 22 | #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) 23 | 24 | typedef struct Mbuffer { 25 | char *buffer; 26 | size_t n; 27 | size_t buffsize; 28 | } Mbuffer; 29 | 30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 31 | 32 | #define luaZ_buffer(buff) ((buff)->buffer) 33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 34 | #define luaZ_bufflen(buff) ((buff)->n) 35 | 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ 41 | (buff)->buffsize = size) 42 | 43 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 44 | 45 | 46 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ 50 | LUAI_FUNC int luaZ_lookahead (ZIO *z); 51 | 52 | 53 | 54 | /* --------- Private Part ------------------ */ 55 | 56 | struct Zio { 57 | size_t n; /* bytes still unread */ 58 | const char *p; /* current position in buffer */ 59 | lua_Reader reader; 60 | void* data; /* additional data */ 61 | lua_State *L; /* Lua state (for reader) */ 62 | }; 63 | 64 | 65 | LUAI_FUNC int luaZ_fill (ZIO *z); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/lib/sera/sera.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef SERA_H 9 | #define SERA_H 10 | 11 | #if SR_MODE_RGBA 12 | #define SR_CHANNELS r, g, b, a 13 | #define SR_RGB_MASK 0xffffff 14 | #elif SR_MODE_ARGB 15 | #define SR_CHANNELS a, r, g, b 16 | #define SR_RGB_MASK 0xffffff00 17 | #elif SR_MODE_ABGR 18 | #define SR_CHANNELS a, b, g, r 19 | #define SR_RGB_MASK 0xffffff00 20 | #else 21 | #define SR_CHANNELS b, g, r, a 22 | #define SR_RGB_MASK 0xffffff 23 | #endif 24 | 25 | typedef union { 26 | unsigned int word; 27 | struct { unsigned char SR_CHANNELS; } rgba; 28 | } sr_Pixel; 29 | 30 | typedef struct { 31 | int x, y, w, h; 32 | } sr_Rect; 33 | 34 | typedef struct { 35 | sr_Pixel color; 36 | unsigned char alpha, blend; 37 | } sr_DrawMode; 38 | 39 | typedef struct { 40 | float ox, oy, r, sx, sy; 41 | } sr_Transform; 42 | 43 | typedef struct { 44 | sr_DrawMode mode; 45 | sr_Rect clip; 46 | sr_Pixel *pixels; 47 | int w, h; 48 | char flags; 49 | } sr_Buffer; 50 | 51 | #define SR_BUFFER_SHARED (1 << 0) 52 | 53 | enum { 54 | SR_FMT_BGRA, 55 | SR_FMT_RGBA, 56 | SR_FMT_ARGB, 57 | SR_FMT_ABGR 58 | }; 59 | 60 | enum { 61 | SR_BLEND_ALPHA, 62 | SR_BLEND_COLOR, 63 | SR_BLEND_ADD, 64 | SR_BLEND_SUBTRACT, 65 | SR_BLEND_MULTIPLY, 66 | SR_BLEND_LIGHTEN, 67 | SR_BLEND_DARKEN, 68 | SR_BLEND_SCREEN, 69 | SR_BLEND_DIFFERENCE 70 | }; 71 | 72 | 73 | sr_Pixel sr_pixel(int r, int g, int b, int a); 74 | sr_Pixel sr_color(int r, int g, int b); 75 | sr_Transform sr_transform(void); 76 | sr_Rect sr_rect(int x, int y, int w, int h); 77 | 78 | sr_Buffer *sr_newBuffer(int w, int h); 79 | sr_Buffer *sr_newBufferShared(void *pixels, int w, int h); 80 | sr_Buffer *sr_cloneBuffer(sr_Buffer *src); 81 | void sr_destroyBuffer(sr_Buffer* b); 82 | 83 | void sr_loadPixels(sr_Buffer *b, void *src, int fmt); 84 | void sr_loadPixels8(sr_Buffer *b, unsigned char *src, sr_Pixel *pal); 85 | 86 | void sr_setAlpha(sr_Buffer* b, int alpha); 87 | void sr_setBlend(sr_Buffer* b, int blend); 88 | void sr_setColor(sr_Buffer* b, sr_Pixel c); 89 | void sr_setClip(sr_Buffer *b, sr_Rect r); 90 | void sr_reset(sr_Buffer *b); 91 | 92 | void sr_clear(sr_Buffer *b, sr_Pixel c); 93 | sr_Pixel sr_getPixel(sr_Buffer *b, int x, int y); 94 | void sr_setPixel(sr_Buffer *b, sr_Pixel c, int x, int y); 95 | void sr_copyPixels(sr_Buffer *b, sr_Buffer *src, int x, int y, 96 | sr_Rect *sub, float sx, float sy); 97 | void sr_noise(sr_Buffer *b, unsigned seed, int low, int high, int grey); 98 | void sr_floodFill(sr_Buffer *b, sr_Pixel c, int x, int y); 99 | 100 | void sr_drawPixel(sr_Buffer *b, sr_Pixel c, int x, int y); 101 | void sr_drawLine(sr_Buffer *b, sr_Pixel c, int x0, int y0, int x1, int y1); 102 | void sr_drawRect(sr_Buffer *b, sr_Pixel c, int x, int y, int w, int h); 103 | void sr_drawBox(sr_Buffer *b, sr_Pixel c, int x, int y, int w, int h); 104 | void sr_drawCircle(sr_Buffer *b, sr_Pixel c, int x, int y, int r); 105 | void sr_drawRing(sr_Buffer *b, sr_Pixel c, int x, int y, int r); 106 | void sr_drawBuffer(sr_Buffer *b, sr_Buffer *src, int x, int y, 107 | sr_Rect *sub, sr_Transform *t); 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/lib/vec/vec.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #include "vec.h" 9 | 10 | 11 | int vec_expand_(char **data, int *length, int *capacity, int memsz) { 12 | if (*length + 1 > *capacity) { 13 | void *ptr; 14 | int n = (*capacity == 0) ? 1 : *capacity << 1; 15 | ptr = realloc(*data, n * memsz); 16 | if (ptr == NULL) return -1; 17 | *data = ptr; 18 | *capacity = n; 19 | } 20 | return 0; 21 | } 22 | 23 | 24 | int vec_reserve_(char **data, int *length, int *capacity, int memsz, int n) { 25 | (void) length; 26 | if (n > *capacity) { 27 | void *ptr = realloc(*data, n * memsz); 28 | if (ptr == NULL) return -1; 29 | *data = ptr; 30 | *capacity = n; 31 | } 32 | return 0; 33 | } 34 | 35 | 36 | int vec_reserve_po2_( 37 | char **data, int *length, int *capacity, int memsz, int n 38 | ) { 39 | int n2 = 1; 40 | if (n == 0) return 0; 41 | while (n2 < n) n2 <<= 1; 42 | return vec_reserve_(data, length, capacity, memsz, n2); 43 | } 44 | 45 | 46 | int vec_compact_(char **data, int *length, int *capacity, int memsz) { 47 | if (*length == 0) { 48 | free(*data); 49 | *data = NULL; 50 | *capacity = 0; 51 | return 0; 52 | } else { 53 | void *ptr; 54 | int n = *length; 55 | ptr = realloc(*data, n * memsz); 56 | if (ptr == NULL) return -1; 57 | *capacity = n; 58 | *data = ptr; 59 | } 60 | return 0; 61 | } 62 | 63 | 64 | int vec_insert_(char **data, int *length, int *capacity, int memsz, 65 | int idx 66 | ) { 67 | int err = vec_expand_(data, length, capacity, memsz); 68 | if (err) return err; 69 | memmove(*data + (idx + 1) * memsz, 70 | *data + idx * memsz, 71 | (*length - idx) * memsz); 72 | return 0; 73 | } 74 | 75 | 76 | void vec_splice_(char **data, int *length, int *capacity, int memsz, 77 | int start, int count 78 | ) { 79 | (void) capacity; 80 | memmove(*data + start * memsz, 81 | *data + (start + count) * memsz, 82 | (*length - start - count) * memsz); 83 | } 84 | 85 | 86 | void vec_swapsplice_(char **data, int *length, int *capacity, int memsz, 87 | int start, int count 88 | ) { 89 | (void) capacity; 90 | memmove(*data + start * memsz, 91 | *data + (*length - count) * memsz, 92 | count * memsz); 93 | } 94 | 95 | 96 | void vec_swap_(char **data, int *length, int *capacity, int memsz, 97 | int idx1, int idx2 98 | ) { 99 | unsigned char *a, *b, tmp; 100 | int count; 101 | (void) length; 102 | (void) capacity; 103 | if (idx1 == idx2) return; 104 | a = (unsigned char*) *data + idx1 * memsz; 105 | b = (unsigned char*) *data + idx2 * memsz; 106 | count = memsz; 107 | while (count--) { 108 | tmp = *a; 109 | *a = *b; 110 | *b = tmp; 111 | a++, b++; 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/lib/vec/vec.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | #ifndef VEC_H 9 | #define VEC_H 10 | 11 | #include 12 | #include 13 | 14 | #define VEC_VERSION "0.2.1" 15 | 16 | 17 | #define vec_unpack_(v)\ 18 | (char**)&(v)->data, &(v)->length, &(v)->capacity, sizeof(*(v)->data) 19 | 20 | 21 | #define vec_t(T)\ 22 | struct { T *data; int length, capacity; } 23 | 24 | 25 | #define vec_init(v)\ 26 | memset((v), 0, sizeof(*(v))) 27 | 28 | 29 | #define vec_deinit(v)\ 30 | ( free((v)->data),\ 31 | vec_init(v) ) 32 | 33 | 34 | #define vec_push(v, val)\ 35 | ( vec_expand_(vec_unpack_(v)) ? -1 :\ 36 | ((v)->data[(v)->length++] = (val), 0), 0 ) 37 | 38 | 39 | #define vec_pop(v)\ 40 | (v)->data[--(v)->length] 41 | 42 | 43 | #define vec_splice(v, start, count)\ 44 | ( vec_splice_(vec_unpack_(v), start, count),\ 45 | (v)->length -= (count) ) 46 | 47 | 48 | #define vec_swapsplice(v, start, count)\ 49 | ( vec_swapsplice_(vec_unpack_(v), start, count),\ 50 | (v)->length -= (count) ) 51 | 52 | 53 | #define vec_insert(v, idx, val)\ 54 | ( vec_insert_(vec_unpack_(v), idx) ? -1 :\ 55 | ((v)->data[idx] = (val), 0), (v)->length++, 0 ) 56 | 57 | 58 | #define vec_sort(v, fn)\ 59 | qsort((v)->data, (v)->length, sizeof(*(v)->data), fn) 60 | 61 | 62 | #define vec_swap(v, idx1, idx2)\ 63 | vec_swap_(vec_unpack_(v), idx1, idx2) 64 | 65 | 66 | #define vec_truncate(v, len)\ 67 | ((v)->length = (len) < (v)->length ? (len) : (v)->length) 68 | 69 | 70 | #define vec_clear(v)\ 71 | ((v)->length = 0) 72 | 73 | 74 | #define vec_first(v)\ 75 | (v)->data[0] 76 | 77 | 78 | #define vec_last(v)\ 79 | (v)->data[(v)->length - 1] 80 | 81 | 82 | #define vec_reserve(v, n)\ 83 | vec_reserve_(vec_unpack_(v), n) 84 | 85 | 86 | #define vec_compact(v)\ 87 | vec_compact_(vec_unpack_(v)) 88 | 89 | 90 | #define vec_pusharr(v, arr, count)\ 91 | do {\ 92 | int i__, n__ = (count);\ 93 | if (vec_reserve_po2_(vec_unpack_(v), (v)->length + n__) != 0) break;\ 94 | for (i__ = 0; i__ < n__; i__++) {\ 95 | (v)->data[(v)->length++] = (arr)[i__];\ 96 | }\ 97 | } while (0) 98 | 99 | 100 | #define vec_extend(v, v2)\ 101 | vec_pusharr((v), (v2)->data, (v2)->length) 102 | 103 | 104 | #define vec_find(v, val, idx)\ 105 | do {\ 106 | for ((idx) = 0; (idx) < (v)->length; (idx)++) {\ 107 | if ((v)->data[(idx)] == (val)) break;\ 108 | }\ 109 | if ((idx) == (v)->length) (idx) = -1;\ 110 | } while (0) 111 | 112 | 113 | #define vec_remove(v, val)\ 114 | do {\ 115 | int idx__;\ 116 | vec_find(v, val, idx__);\ 117 | if (idx__ != -1) vec_splice(v, idx__, 1);\ 118 | } while (0) 119 | 120 | 121 | #define vec_reverse(v)\ 122 | do {\ 123 | int i__ = (v)->length / 2;\ 124 | while (i__--) {\ 125 | vec_swap((v), i__, (v)->length - (i__ + 1));\ 126 | }\ 127 | } while (0) 128 | 129 | 130 | #define vec_foreach(v, var, iter)\ 131 | if ( (v)->length > 0 )\ 132 | for ( (iter) = 0;\ 133 | (iter) < (v)->length && (((var) = (v)->data[(iter)]), 1);\ 134 | ++(iter)) 135 | 136 | 137 | #define vec_foreach_rev(v, var, iter)\ 138 | if ( (v)->length > 0 )\ 139 | for ( (iter) = (v)->length - 1;\ 140 | (iter) >= 0 && (((var) = (v)->data[(iter)]), 1);\ 141 | --(iter)) 142 | 143 | 144 | #define vec_foreach_ptr(v, var, iter)\ 145 | if ( (v)->length > 0 )\ 146 | for ( (iter) = 0;\ 147 | (iter) < (v)->length && (((var) = &(v)->data[(iter)]), 1);\ 148 | ++(iter)) 149 | 150 | 151 | #define vec_foreach_ptr_rev(v, var, iter)\ 152 | if ( (v)->length > 0 )\ 153 | for ( (iter) = (v)->length - 1;\ 154 | (iter) >= 0 && (((var) = &(v)->data[(iter)]), 1);\ 155 | --(iter)) 156 | 157 | 158 | 159 | int vec_expand_(char **data, int *length, int *capacity, int memsz); 160 | int vec_reserve_(char **data, int *length, int *capacity, int memsz, int n); 161 | int vec_reserve_po2_(char **data, int *length, int *capacity, int memsz, 162 | int n); 163 | int vec_compact_(char **data, int *length, int *capacity, int memsz); 164 | int vec_insert_(char **data, int *length, int *capacity, int memsz, 165 | int idx); 166 | void vec_splice_(char **data, int *length, int *capacity, int memsz, 167 | int start, int count); 168 | void vec_swapsplice_(char **data, int *length, int *capacity, int memsz, 169 | int start, int count); 170 | void vec_swap_(char **data, int *length, int *capacity, int memsz, 171 | int idx1, int idx2); 172 | 173 | 174 | typedef vec_t(void*) vec_void_t; 175 | typedef vec_t(char*) vec_str_t; 176 | typedef vec_t(int) vec_int_t; 177 | typedef vec_t(char) vec_char_t; 178 | typedef vec_t(float) vec_float_t; 179 | typedef vec_t(double) vec_double_t; 180 | 181 | #endif 182 | -------------------------------------------------------------------------------- /src/luax.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef LUAX_H 10 | #define LUAX_H 11 | 12 | //#include 13 | //#include 14 | //#include 15 | 16 | #include "lib/lua51/lua.h" 17 | #include "lib/lua51/lualib.h" 18 | #include "lib/lua51/lauxlib.h" 19 | #include "lib/lextlib_lua52.h" 20 | 21 | #define luax_setfield_(T, L, k, v)\ 22 | do { lua_push##T(L, v); lua_setfield(L, -2, k); } while (0) 23 | 24 | #define luax_setfield_number(L, k, v) luax_setfield_(number, L, k, v) 25 | #define luax_setfield_string(L, k, v) luax_setfield_(string, L, k, v) 26 | #define luax_setfield_bool(L, k, v) luax_setfield_(boolean, L, k, v) 27 | #define luax_setfield_udata(L, k, v) luax_setfield_(lightuserdata, L, k, v) 28 | #define luax_setfield_cfunc(L, k, v) luax_setfield_(cfunction, L, k, v) 29 | #define luax_setfield_fstring(L, k, ...)\ 30 | do { lua_pushfstring(L, __VA_ARGS__); lua_setfield(L, -2, k); } while (0) 31 | 32 | 33 | #define luax_optboolean(L, i, x)\ 34 | (!lua_isnoneornil(L, i) ? lua_toboolean(L, i) : (x)) 35 | 36 | #define luax_optudata(L, i, name, x)\ 37 | (!lua_isnoneornil(L, i) ? luaL_checkudata(L, i, name) : (x)) 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/m_audio.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include "luax.h" 11 | #include "util.h" 12 | #include "m_source.h" 13 | 14 | 15 | static int inited = 0; 16 | static double samplerate = 0; 17 | 18 | 19 | static void audioCallback(void *udata, Uint8 *stream, int size) { 20 | lua_State *L = udata; 21 | int16_t *buffer = (void*) stream; 22 | int len = size >> 1; 23 | int i; 24 | UNUSED(L); 25 | /* Process source commands */ 26 | source_processCommands(); 27 | /* Process sources audio */ 28 | source_processAllSources(len); 29 | /* Copy master to buffer */ 30 | Source *master = source_getMaster(NULL); 31 | for (i = 0; i < len; i++) { 32 | int x = master->buf[i]; 33 | buffer[i] = CLAMP(x, -32768, 32767); 34 | } 35 | } 36 | 37 | 38 | static int l_audio_init(lua_State *L) { 39 | int rate = luaL_optint(L, 1, 44100); 40 | int bufferSize = luaL_optint(L, 2, 44100); 41 | if (inited) { 42 | luaL_error(L, "audio is already inited"); 43 | } 44 | if (SDL_Init(SDL_INIT_AUDIO) != 0) { 45 | luaL_error(L, "could not init audio"); 46 | } 47 | /* Init format, open and start */ 48 | SDL_AudioSpec fmt; 49 | memset(&fmt, 0, sizeof(fmt)); 50 | fmt.freq = rate; 51 | fmt.format = AUDIO_S16; 52 | fmt.channels = 2; 53 | fmt.callback = audioCallback; 54 | fmt.samples = bufferSize; 55 | fmt.userdata = L; 56 | if (SDL_OpenAudio(&fmt, 0) < 0) { 57 | luaL_error(L, "could not open audio"); 58 | } 59 | /* Set state */ 60 | samplerate = rate; 61 | inited = 1; 62 | /* Init Source state */ 63 | source_setSamplerate(samplerate); 64 | /* Start audio */ 65 | SDL_PauseAudio(0); 66 | return 0; 67 | } 68 | 69 | 70 | int luaopen_audio(lua_State *L) { 71 | luaL_Reg reg[] = { 72 | { "init", l_audio_init }, 73 | { NULL, NULL } 74 | }; 75 | luaL_newlib(L, reg); 76 | /* Add .master Source field */ 77 | int ref; 78 | source_getMaster(&ref); 79 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref); 80 | lua_setfield(L, -2, "master"); 81 | return 1; 82 | } 83 | -------------------------------------------------------------------------------- /src/m_buffer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef BUFFER_H 10 | #define BUFFER_H 11 | 12 | #include "luax.h" 13 | #include "lib/sera/sera.h" 14 | 15 | #define BUFFER_CLASS_NAME "Buffer" 16 | 17 | typedef struct { 18 | sr_Buffer *buffer; 19 | } Buffer; 20 | 21 | Buffer *buffer_new(lua_State *L); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/m_data.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include "util.h" 13 | #include "luax.h" 14 | #include "fs.h" 15 | #include "m_data.h" 16 | 17 | #define CLASS_NAME DATA_CLASS_NAME 18 | 19 | 20 | static Data *newData(lua_State *L) { 21 | Data *self = lua_newuserdata(L, sizeof(*self)); 22 | luaL_setmetatable(L, CLASS_NAME); 23 | memset(self, 0, sizeof(*self)); 24 | return self; 25 | } 26 | 27 | 28 | static int l_data_fromFile(lua_State *L) { 29 | const char *filename = luaL_checkstring(L, 1); 30 | Data *self = newData(L); 31 | size_t len; 32 | void *data = fs_read(filename, &len); 33 | if (!data) { 34 | luaL_error(L, "could not open file '%s'", filename); 35 | } 36 | self->data = data; 37 | self->len = len; 38 | return 1; 39 | } 40 | 41 | 42 | static int l_data_fromString(lua_State *L) { 43 | size_t len; 44 | const char *data = luaL_checklstring(L, 1, &len); 45 | Data *self = newData(L); 46 | self->data = malloc(len); 47 | if (!self->data) { 48 | luaL_error(L, "out of memory"); 49 | } 50 | memcpy(self->data, data, len); 51 | self->len = len; 52 | return 1; 53 | } 54 | 55 | 56 | static int l_data_gc(lua_State *L) { 57 | Data *self = luaL_checkudata(L, 1, CLASS_NAME); 58 | free(self->data); 59 | return 1; 60 | } 61 | 62 | 63 | static int l_data_getLength(lua_State *L) { 64 | Data *self = luaL_checkudata(L, 1, CLASS_NAME); 65 | lua_pushnumber(L, self->len); 66 | return 1; 67 | } 68 | 69 | 70 | static int l_data_toString(lua_State *L) { 71 | Data *self = luaL_checkudata(L, 1, CLASS_NAME); 72 | lua_pushlstring(L, self->data, self->len); 73 | return 1; 74 | } 75 | 76 | 77 | 78 | int luaopen_data(lua_State *L) { 79 | luaL_Reg reg[] = { 80 | { "__gc", l_data_gc }, 81 | { "fromFile", l_data_fromFile }, 82 | { "fromString", l_data_fromString }, 83 | { "getLength", l_data_getLength }, 84 | { "toString", l_data_toString }, 85 | { NULL, NULL } 86 | }; 87 | ASSERT( luaL_newmetatable(L, CLASS_NAME) ); 88 | luaL_setfuncs(L, reg, 0); 89 | lua_pushvalue(L, -1); 90 | lua_setfield(L, -2, "__index"); 91 | return 1; 92 | } 93 | -------------------------------------------------------------------------------- /src/m_data.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef M_DATA_H 10 | #define M_DATA_H 11 | 12 | #define DATA_CLASS_NAME "Data" 13 | 14 | typedef struct { 15 | void *data; 16 | int len; 17 | } Data; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/m_font.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib/sera/sera.h" 14 | #include "util.h" 15 | #include "luax.h" 16 | #include "fs.h" 17 | #include "ttf.h" 18 | #include "m_buffer.h" 19 | 20 | #define CLASS_NAME "Font" 21 | #define DEFAULT_FONTSIZE 14 22 | 23 | typedef struct { 24 | ttf_Font *font; 25 | } Font; 26 | 27 | 28 | static Font *newFont(lua_State *L) { 29 | Font *self = lua_newuserdata(L, sizeof(*self)); 30 | luaL_setmetatable(L, CLASS_NAME); 31 | memset(self, 0, sizeof(*self)); 32 | return self; 33 | } 34 | 35 | static const char *loadFontFromMemory( 36 | Font *self, const void *data, int len, int ptsize 37 | ) { 38 | self->font = ttf_new(data, len); 39 | if (!self->font) { 40 | return "could not load font"; 41 | } 42 | ttf_ptsize(self->font, ptsize); 43 | return NULL; 44 | } 45 | 46 | 47 | static int l_font_fromFile(lua_State *L) { 48 | const char *filename = luaL_checkstring(L, 1); 49 | int fontsize = luaL_optint(L, 2, DEFAULT_FONTSIZE); 50 | Font *self = newFont(L); 51 | size_t len; 52 | void *data = fs_read(filename, &len); 53 | /* Load new font */ 54 | if (!data) { 55 | luaL_error(L, "could not open file '%s'", filename); 56 | } 57 | const char *err = loadFontFromMemory(self, data, len, fontsize); 58 | free(data); 59 | if (err) luaL_error(L, "%s", err); 60 | return 1; 61 | } 62 | 63 | 64 | static int l_font_fromString(lua_State *L) { 65 | size_t len; 66 | const char *data = luaL_checklstring(L, 1, &len); 67 | int fontsize = luaL_optint(L, 2, DEFAULT_FONTSIZE); 68 | Font *self = newFont(L); 69 | const char *err = loadFontFromMemory(self, data, len, fontsize); 70 | if (err) luaL_error(L, "%s", err); 71 | return 1; 72 | } 73 | 74 | 75 | static int l_font_fromEmbedded(lua_State *L) { 76 | #include "font_ttf.h" 77 | int fontsize = luaL_optint(L, 1, DEFAULT_FONTSIZE); 78 | Font *self = newFont(L); 79 | const char *err = loadFontFromMemory(self, font_ttf, sizeof(font_ttf), 80 | fontsize); 81 | if (err) luaL_error(L, "%s", err); 82 | return 1; 83 | } 84 | 85 | 86 | static int l_font_gc(lua_State *L) { 87 | Font *self = luaL_checkudata(L, 1, CLASS_NAME); 88 | if (self->font) { 89 | ttf_destroy(self->font); 90 | } 91 | return 0; 92 | } 93 | 94 | 95 | static int l_font_render(lua_State *L) { 96 | int w, h; 97 | Font *self = luaL_checkudata(L, 1, CLASS_NAME); 98 | const char *str = lua_tostring(L, 2); 99 | if (!str || *str == '\0') str = " "; 100 | Buffer *b = buffer_new(L); 101 | void *data = ttf_render(self->font, str, &w, &h); 102 | if (!data) { 103 | luaL_error(L, "could not render text"); 104 | } 105 | /* Load bitmap and free intermediate 8bit bitmap */ 106 | b->buffer = sr_newBuffer(w, h); 107 | if (!b->buffer) { 108 | free(data); 109 | luaL_error(L, "could not create buffer"); 110 | } 111 | sr_loadPixels8(b->buffer, data, NULL); 112 | free(data); 113 | return 1; 114 | } 115 | 116 | 117 | static int l_font_getWidth(lua_State *L) { 118 | Font *self = luaL_checkudata(L, 1, CLASS_NAME); 119 | const char *str = luaL_checkstring(L, 2); 120 | lua_pushnumber(L, ttf_width(self->font, str)); 121 | return 1; 122 | } 123 | 124 | 125 | static int l_font_getHeight(lua_State *L) { 126 | Font *self = luaL_checkudata(L, 1, CLASS_NAME); 127 | lua_pushnumber(L, ttf_height(self->font)); 128 | return 1; 129 | } 130 | 131 | 132 | int luaopen_font(lua_State *L) { 133 | luaL_Reg reg[] = { 134 | { "__gc", l_font_gc }, 135 | { "fromFile", l_font_fromFile }, 136 | { "fromString", l_font_fromString }, 137 | { "fromEmbedded", l_font_fromEmbedded }, 138 | { "render", l_font_render }, 139 | { "getWidth", l_font_getWidth }, 140 | { "getHeight", l_font_getHeight }, 141 | { NULL, NULL } 142 | }; 143 | ASSERT( luaL_newmetatable(L, CLASS_NAME) ); 144 | luaL_setfuncs(L, reg, 0); 145 | lua_pushvalue(L, -1); 146 | lua_setfield(L, -2, "__index"); 147 | return 1; 148 | } 149 | -------------------------------------------------------------------------------- /src/m_fs.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include "luax.h" 11 | #include "fs.h" 12 | 13 | 14 | static void checkError(lua_State *L, int err, const char *str) { 15 | if (!err) return; 16 | if (err == FS_ENOWRITEPATH || !str) { 17 | luaL_error(L, "%s", fs_errorStr(err)); 18 | } 19 | luaL_error(L, "%s '%s'", fs_errorStr(err), str); 20 | } 21 | 22 | 23 | static int l_fs_mount(lua_State *L) { 24 | const char *path = luaL_checkstring(L, 1); 25 | int res = fs_mount(path); 26 | if (res != FS_ESUCCESS) { 27 | lua_pushnil(L); 28 | lua_pushfstring(L, "%s '%s'", fs_errorStr(res), path); 29 | return 2; 30 | } 31 | lua_pushboolean(L, 1); 32 | return 1; 33 | } 34 | 35 | 36 | static int l_fs_unmount(lua_State *L) { 37 | const char *path = luaL_checkstring(L, 1); 38 | fs_unmount(path); 39 | return 0; 40 | } 41 | 42 | 43 | static int l_fs_setWritePath(lua_State *L) { 44 | const char *path = luaL_checkstring(L, 1); 45 | int res = fs_setWritePath(path); 46 | checkError(L, res, path); 47 | return 0; 48 | } 49 | 50 | 51 | static int l_fs_exists(lua_State *L) { 52 | const char *filename = luaL_checkstring(L, 1); 53 | lua_pushboolean(L, fs_exists(filename)); 54 | return 1; 55 | } 56 | 57 | 58 | static int l_fs_getSize(lua_State *L) { 59 | const char *filename = luaL_checkstring(L, 1); 60 | size_t sz; 61 | int res = fs_size(filename, &sz); 62 | checkError(L, res, filename); 63 | lua_pushnumber(L, sz); 64 | return 1; 65 | } 66 | 67 | 68 | static int l_fs_getModified(lua_State *L) { 69 | const char *filename = luaL_checkstring(L, 1); 70 | unsigned t; 71 | int res = fs_modified(filename, &t); 72 | checkError(L, res, filename); 73 | lua_pushnumber(L, t); 74 | return 1; 75 | } 76 | 77 | 78 | static int l_fs_read(lua_State *L) { 79 | const char *filename = luaL_checkstring(L, 1); 80 | size_t len; 81 | char *data = fs_read(filename, &len); 82 | if (!data) { 83 | luaL_error(L, "could not read file '%s'", filename); 84 | } 85 | lua_pushlstring(L, data, len); 86 | free(data); 87 | return 1; 88 | } 89 | 90 | 91 | static int l_fs_isDir(lua_State *L) { 92 | const char *filename = luaL_checkstring(L, 1); 93 | lua_pushboolean(L, fs_isDir(filename)); 94 | return 1; 95 | } 96 | 97 | 98 | static int l_fs_listDir(lua_State *L) { 99 | const char *path = luaL_checkstring(L, 1); 100 | fs_FileListNode *list = fs_listDir(path); 101 | lua_newtable(L); 102 | int i = 1; 103 | fs_FileListNode *n = list; 104 | while (n) { 105 | lua_pushstring(L, n->name); 106 | lua_rawseti(L, -2, i); 107 | i++; 108 | n = n->next; 109 | } 110 | fs_freeFileList(list); 111 | return 1; 112 | } 113 | 114 | 115 | static int l_fs_write(lua_State *L) { 116 | const char *filename = luaL_checkstring(L, 1); 117 | size_t len; 118 | const char *data = luaL_checklstring(L, 2, &len); 119 | int res = fs_write(filename, data, len); 120 | checkError(L, res, filename); 121 | return 0; 122 | } 123 | 124 | 125 | static int l_fs_append(lua_State *L) { 126 | const char *filename = luaL_checkstring(L, 1); 127 | size_t len; 128 | const char *data = luaL_checklstring(L, 2, &len); 129 | int res = fs_append(filename, data, len); 130 | checkError(L, res, filename); 131 | return 0; 132 | } 133 | 134 | 135 | static int l_fs_delete(lua_State *L) { 136 | const char *filename = luaL_checkstring(L, 1); 137 | int res = fs_delete(filename); 138 | if (res != FS_ESUCCESS) { 139 | lua_pushnil(L); 140 | lua_pushfstring(L, "%s", fs_errorStr(res)); 141 | return 2; 142 | } 143 | lua_pushboolean(L, 1); 144 | return 1; 145 | } 146 | 147 | 148 | static int l_fs_makeDirs(lua_State *L) { 149 | const char *path = luaL_checkstring(L, 1); 150 | int res = fs_makeDirs(path); 151 | if (res != FS_ESUCCESS) { 152 | luaL_error(L, "%s '%s'", fs_errorStr(res), path); 153 | } 154 | return 0; 155 | } 156 | 157 | 158 | int luaopen_fs(lua_State *L) { 159 | luaL_Reg reg[] = { 160 | { "mount", l_fs_mount }, 161 | { "unmount", l_fs_unmount }, 162 | { "setWritePath", l_fs_setWritePath }, 163 | { "exists", l_fs_exists }, 164 | { "getSize", l_fs_getSize }, 165 | { "getModified", l_fs_getModified }, 166 | { "read", l_fs_read }, 167 | { "isDir", l_fs_isDir }, 168 | { "listDir", l_fs_listDir }, 169 | { "write", l_fs_write }, 170 | { "append", l_fs_append }, 171 | { "delete", l_fs_delete }, 172 | { "makeDirs", l_fs_makeDirs }, 173 | { NULL, NULL } 174 | }; 175 | luaL_newlib(L, reg); 176 | atexit(fs_deinit); 177 | return 1; 178 | } 179 | -------------------------------------------------------------------------------- /src/m_gif.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "lib/jo_gif.c" 15 | #include "util.h" 16 | #include "luax.h" 17 | #include "m_buffer.h" 18 | 19 | #define CLASS_NAME "Gif" 20 | 21 | typedef struct { 22 | int state; 23 | jo_gif_t gif; 24 | int w, h; 25 | unsigned char *buf; 26 | } Gif; 27 | 28 | enum { 29 | STATE_INIT, 30 | STATE_ACTIVE, 31 | STATE_CLOSED, 32 | }; 33 | 34 | static int l_gif_new(lua_State *L) { 35 | const char *filename = luaL_checkstring(L, 1); 36 | int w = luaL_checknumber(L, 2); 37 | int h = luaL_checknumber(L, 3); 38 | int ncolors = luaL_optnumber(L, 4, 63); 39 | Gif *self = lua_newuserdata(L, sizeof(*self)); 40 | luaL_setmetatable(L, CLASS_NAME); 41 | memset(self, 0, sizeof(*self)); 42 | self->state = STATE_INIT; 43 | self->w = w; 44 | self->h = h; 45 | self->buf = malloc(w * h * 4); 46 | ASSERT(self->buf); 47 | memset(self->buf, 0, w * h * 4); 48 | /* Activate gif */ 49 | self->gif = jo_gif_start(filename, self->w, self->h, 0, ncolors); 50 | self->state = STATE_ACTIVE; 51 | return 1; 52 | } 53 | 54 | 55 | static int l_gif_gc(lua_State *L) { 56 | Gif *self = luaL_checkudata(L, 1, CLASS_NAME); 57 | free(self->buf); 58 | /* Not closed? close now */ 59 | if (self->state == STATE_ACTIVE) { 60 | jo_gif_end(&self->gif); 61 | } 62 | return 0; 63 | } 64 | 65 | 66 | static int l_gif_update(lua_State *L) { 67 | Gif *self = luaL_checkudata(L, 1, CLASS_NAME); 68 | Buffer *buf = luaL_checkudata(L, 2, BUFFER_CLASS_NAME); 69 | int delay = luaL_checknumber(L, 3); 70 | /* Already closed? Error */ 71 | if (self->state == STATE_CLOSED) { 72 | luaL_error(L, "can't update closed gif"); 73 | } 74 | /* Buffer dimensions are okay? */ 75 | if (buf->buffer->w != self->w || buf->buffer->h != self->h) { 76 | luaL_error(L, "bad buffer dimensions for gif object, expected %dx%d", 77 | self->w, self->h); 78 | } 79 | /* Copy pixels to buffer -- jo_gif expects a specific channel byte-order 80 | * which may differ from what sera is using -- alpha channel isn't copied 81 | * since jo_gif doesn't use this */ 82 | int i, n; 83 | int len = self->w * self->h; 84 | sr_Pixel *p = buf->buffer->pixels; 85 | for (i = 0; i < len; i++) { 86 | n = i * 4; 87 | self->buf[n ] = p[i].rgba.r; 88 | self->buf[n + 1] = p[i].rgba.g; 89 | self->buf[n + 2] = p[i].rgba.b; 90 | } 91 | /* Update */ 92 | jo_gif_frame(&self->gif, self->buf, delay, 0); 93 | return 0; 94 | } 95 | 96 | 97 | static int l_gif_close(lua_State *L) { 98 | Gif *self = luaL_checkudata(L, 1, CLASS_NAME); 99 | if (self->state == STATE_CLOSED) { 100 | luaL_error(L, "state already closed"); 101 | } 102 | self->state = STATE_CLOSED; 103 | jo_gif_end(&self->gif); 104 | return 0; 105 | } 106 | 107 | 108 | int luaopen_gif(lua_State *L) { 109 | luaL_Reg reg[] = { 110 | { "__gc", l_gif_gc }, 111 | { "new", l_gif_new }, 112 | { "update", l_gif_update }, 113 | { "close", l_gif_close }, 114 | { NULL, NULL } 115 | }; 116 | ASSERT( luaL_newmetatable(L, CLASS_NAME) ); 117 | luaL_setfuncs(L, reg, 0); 118 | lua_pushvalue(L, -1); 119 | lua_setfield(L, -2, "__index"); 120 | return 1; 121 | } 122 | -------------------------------------------------------------------------------- /src/m_graphics.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib/sera/sera.h" 15 | #include "util.h" 16 | #include "luax.h" 17 | #include "m_buffer.h" 18 | 19 | double m_graphics_maxFps = 60.; 20 | 21 | static int inited = 0; 22 | static int screenWidth = 0; 23 | static int screenHeight = 0; 24 | static int screenRef = 0; 25 | static int fullscreen = 0; 26 | static int resizable = 0; 27 | Buffer *screen; 28 | 29 | 30 | static void resetVideoMode(lua_State *L) { 31 | /* Reset video mode */ 32 | int flags = (fullscreen ? SDL_FULLSCREEN : 0) | 33 | (resizable ? SDL_RESIZABLE : 0); 34 | if (SDL_SetVideoMode(screenWidth, screenHeight, 32, flags) == NULL) { 35 | luaL_error(L, "could not set video mode"); 36 | } 37 | /* Reset screen buffer */ 38 | if (screen) { 39 | sr_Buffer *b = screen->buffer; 40 | b->pixels = (void*) SDL_GetVideoSurface()->pixels; 41 | b->w = screenWidth; 42 | b->h = screenHeight; 43 | sr_setClip(b, sr_rect(0, 0, b->w, b->h)); 44 | } 45 | } 46 | 47 | 48 | static int l_graphics_init(lua_State *L) { 49 | screenWidth = luaL_checkint(L, 1); 50 | screenHeight = luaL_checkint(L, 2); 51 | const char *title = luaL_optstring(L, 3, "Juno"); 52 | fullscreen = luax_optboolean(L, 4, 0); 53 | resizable = luax_optboolean(L, 5, 0); 54 | if (inited) { 55 | luaL_error(L, "graphics are already inited"); 56 | } 57 | if (SDL_Init(SDL_INIT_VIDEO) != 0) { 58 | luaL_error(L, "could not init video"); 59 | } 60 | /* Init SDL video */ 61 | resetVideoMode(L); 62 | /* Required to get the associated character when a key is pressed. This has 63 | * to be enabled *after* SDL video is set up */ 64 | SDL_EnableUNICODE(1); 65 | /* Init window title */ 66 | SDL_WM_SetCaption(title, title); 67 | /* Create, store in registry and return main screen buffer */ 68 | screen = buffer_new(L); 69 | screen->buffer = sr_newBufferShared( 70 | SDL_GetVideoSurface()->pixels, screenWidth, screenHeight); 71 | lua_pushvalue(L, -1); 72 | screenRef = lua_ref(L, LUA_REGISTRYINDEX); 73 | /* Set state */ 74 | inited = 1; 75 | return 1; 76 | } 77 | 78 | 79 | static int l_graphics_setFullscreen(lua_State *L) { 80 | fullscreen = luax_optboolean(L, 1, 0); 81 | resetVideoMode(L); 82 | return 0; 83 | } 84 | 85 | 86 | static int l_graphics_setMaxFps(lua_State *L) { 87 | m_graphics_maxFps = luaL_optnumber(L, 1, 60); 88 | return 0; 89 | } 90 | 91 | 92 | int luaopen_graphics(lua_State *L) { 93 | luaL_Reg reg[] = { 94 | { "init", l_graphics_init }, 95 | { "setFullscreen", l_graphics_setFullscreen }, 96 | { "setMaxFps", l_graphics_setMaxFps }, 97 | { NULL, NULL } 98 | }; 99 | luaL_newlib(L, reg); 100 | return 1; 101 | } 102 | -------------------------------------------------------------------------------- /src/m_juno.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include "luax.h" 10 | #include 11 | 12 | #define JUNO_VERSION "0.0.0" 13 | 14 | 15 | static int l_juno_getVersion(lua_State *L) { 16 | lua_pushstring(L, JUNO_VERSION); 17 | return 1; 18 | } 19 | 20 | 21 | int luaopen_system(lua_State *L); 22 | int luaopen_fs(lua_State *L); 23 | int luaopen_time(lua_State *L); 24 | int luaopen_graphics(lua_State *L); 25 | int luaopen_audio(lua_State *L); 26 | int luaopen_mouse(lua_State *L); 27 | int luaopen_buffer(lua_State *L); 28 | int luaopen_bufferfx(lua_State *L); 29 | int luaopen_font(lua_State *L); 30 | int luaopen_source(lua_State *L); 31 | int luaopen_data(lua_State *L); 32 | int luaopen_gif(lua_State *L); 33 | 34 | int luaopen_juno(lua_State *L) { 35 | luaL_Reg reg[] = { 36 | { "getVersion", l_juno_getVersion }, 37 | { NULL, NULL } 38 | }; 39 | luaL_newlib(L, reg); 40 | 41 | /* Init submodules */ 42 | int i; 43 | struct { char *name; int (*fn)(lua_State *L); } mods[] = { 44 | /* Objects */ 45 | { "Font", luaopen_font }, 46 | { "Buffer", luaopen_buffer }, 47 | { "Source", luaopen_source }, 48 | { "Data", luaopen_data }, 49 | { "Gif", luaopen_gif }, 50 | /* Modules */ 51 | { "system", luaopen_system }, 52 | { "fs", luaopen_fs }, 53 | { "time", luaopen_time }, 54 | { "graphics", luaopen_graphics }, 55 | { "audio", luaopen_audio }, 56 | { "mouse", luaopen_mouse }, 57 | { "bufferfx", luaopen_bufferfx }, 58 | { NULL, NULL }, 59 | }; 60 | for (i = 0; mods[i].name; i++) { 61 | mods[i].fn(L); 62 | lua_setfield(L, -2, mods[i].name); 63 | } 64 | 65 | return 1; 66 | } 67 | -------------------------------------------------------------------------------- /src/m_mouse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include "luax.h" 11 | 12 | 13 | static int l_mouse_setVisible(lua_State *L) { 14 | SDL_ShowCursor(lua_toboolean(L, 1)); 15 | return 0; 16 | } 17 | 18 | 19 | static int l_mouse_setPosition(lua_State *L) { 20 | SDL_WarpMouse(luaL_checknumber(L, 1), luaL_checknumber(L, 2)); 21 | return 0; 22 | } 23 | 24 | 25 | int luaopen_mouse(lua_State *L) { 26 | luaL_Reg reg[] = { 27 | { "setVisible", l_mouse_setVisible }, 28 | { "setPosition", l_mouse_setPosition }, 29 | { NULL, NULL } 30 | }; 31 | luaL_newlib(L, reg); 32 | return 1; 33 | } 34 | -------------------------------------------------------------------------------- /src/m_source.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef M_SOURCE_H 10 | #define M_SOURCE_H 11 | 12 | #include "luax.h" 13 | #include "wav.h" 14 | #include "m_data.h" 15 | 16 | #define STB_VORBIS_HEADER_ONLY 17 | #include "lib/stb_vorbis.c" 18 | #undef STB_VORBIS_HEADER_ONLY 19 | 20 | 21 | #define SOURCE_CLASS_NAME "Source" 22 | 23 | #define SOURCE_BUFFER_MAX 4096 24 | #define SOURCE_BUFFER_MASK (SOURCE_BUFFER_MAX - 1) 25 | 26 | struct Source; 27 | struct SourceEvent; 28 | 29 | typedef void (*SourceEventHandler)(struct Source*, struct SourceEvent*); 30 | 31 | typedef struct Source { 32 | int rawBufLeft[SOURCE_BUFFER_MAX]; 33 | int rawBufRight[SOURCE_BUFFER_MAX]; 34 | int buf[SOURCE_BUFFER_MAX]; 35 | int dataRef, destRef, callbackRef, tableRef; 36 | Data *data; 37 | struct Source *dest; 38 | SourceEventHandler onEvent; 39 | int samplerate; 40 | int state; 41 | int flags; 42 | int length; 43 | int rate; 44 | long long position; 45 | int end; 46 | int bufEnd; 47 | int lgain, rgain; 48 | double gain, pan; 49 | /* Type-specific fields */ 50 | union { 51 | /* .wav */ 52 | struct { wav_t wav; int wavIdx; }; 53 | /* .ogg */ 54 | struct { stb_vorbis *oggStream; }; 55 | }; 56 | } Source; 57 | 58 | typedef struct SourceEvent { 59 | int type; 60 | lua_State *luaState; 61 | int offset; 62 | int len; 63 | } SourceEvent; 64 | 65 | #define SOURCE_FLOOP (1 << 0) 66 | #define SOURCE_FREPLACE (1 << 1) 67 | 68 | enum { 69 | SOURCE_STATE_STOPPED, 70 | SOURCE_STATE_PLAYING, 71 | SOURCE_STATE_PAUSED, 72 | }; 73 | 74 | enum { 75 | SOURCE_EVENT_NULL, 76 | SOURCE_EVENT_INIT, 77 | SOURCE_EVENT_DEINIT, 78 | SOURCE_EVENT_REWIND, 79 | SOURCE_EVENT_PROCESS, 80 | }; 81 | 82 | 83 | Source *source_getMaster(int *ref); 84 | void source_setLuaMutex(SDL_mutex *m); 85 | void source_setSamplerate(int sr); 86 | void source_processCommands(void); 87 | void source_process(Source *s, int len); 88 | void source_processAllSources(int len); 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/m_system.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include "util.h" 11 | #include "luax.h" 12 | 13 | #if _WIN32 14 | #include 15 | #elif __linux__ 16 | #include 17 | #elif __APPLE__ 18 | #include 19 | #endif 20 | 21 | 22 | static const char *buttonStr(int id) { 23 | switch (id) { 24 | case 1 : return "left"; 25 | case 2 : return "middle"; 26 | case 3 : return "right"; 27 | case 4 : return "wheelup"; 28 | case 5 : return "wheeldown"; 29 | default : return "?"; 30 | } 31 | } 32 | 33 | static char keyChar(char c) { 34 | return (c == '\r') ? '\n' : c; 35 | } 36 | 37 | static int l_system_poll(lua_State *L) { 38 | /* Create events table */ 39 | lua_newtable(L); 40 | 41 | /* Handle events */ 42 | int eventIdx = 1; 43 | SDL_Event e; 44 | while (SDL_PollEvent(&e)) { 45 | lua_newtable(L); 46 | 47 | switch (e.type) { 48 | case SDL_QUIT: 49 | luax_setfield_string(L, "type", "quit"); 50 | break; 51 | 52 | // /* TODO: */ 53 | //case SDL_VIDEORESIZE: 54 | // lua_getfield(L, -3, "setSize"); 55 | // lua_pushnumber(L, e.resize.w); 56 | // lua_pushnumber(L, e.resize.h); 57 | // luax_call(L, 2, 0); 58 | // luax_setfield_string(L, "type", "resize"); 59 | // luax_setfield_number(L, "width", e.resize.w); 60 | // luax_setfield_number(L, "height", e.resize.h); 61 | // break; 62 | 63 | case SDL_KEYDOWN: { 64 | luax_setfield_string(L, "type", "keydown"); 65 | luax_setfield_fstring(L, "key", "%s", 66 | SDL_GetKeyName(e.key.keysym.sym)); 67 | int c = keyChar(e.key.keysym.unicode); 68 | if (c) { 69 | luax_setfield_fstring(L, "char", "%c", c); 70 | } 71 | break; 72 | } 73 | 74 | case SDL_KEYUP: 75 | luax_setfield_string(L, "type", "keyup"); 76 | luax_setfield_fstring(L, "key", "%s", 77 | SDL_GetKeyName(e.key.keysym.sym)); 78 | break; 79 | 80 | case SDL_MOUSEMOTION: 81 | luax_setfield_string(L, "type", "mousemove"); 82 | luax_setfield_number(L, "x", e.motion.x); 83 | luax_setfield_number(L, "y", e.motion.y); 84 | break; 85 | 86 | case SDL_MOUSEBUTTONDOWN: 87 | luax_setfield_string(L, "type", "mousebuttondown"); 88 | luax_setfield_string(L, "button", buttonStr(e.button.button)); 89 | luax_setfield_number(L, "x", e.button.x); 90 | luax_setfield_number(L, "y", e.button.y); 91 | break; 92 | 93 | case SDL_MOUSEBUTTONUP: 94 | luax_setfield_string(L, "type", "mousebuttonup"); 95 | luax_setfield_string(L, "button", buttonStr(e.button.button)); 96 | luax_setfield_number(L, "x", e.button.x); 97 | luax_setfield_number(L, "y", e.button.y); 98 | break; 99 | } 100 | 101 | /* Push event to events table */ 102 | lua_rawseti(L, -2, eventIdx++); 103 | } 104 | return 1; 105 | } 106 | 107 | 108 | static char *dirname(char *str) { 109 | char *p = str + strlen(str); 110 | while (p != str) { 111 | if (*p == '/' || *p == '\\') { 112 | *p = '\0'; 113 | break; 114 | } 115 | p--; 116 | } 117 | return str; 118 | } 119 | 120 | static int l_system_info(lua_State *L) { 121 | const char *str = luaL_checkstring(L, 1); 122 | if (!strcmp(str, "os")) { 123 | #if _WIN32 124 | lua_pushstring(L, "windows"); 125 | #elif __linux__ 126 | lua_pushstring(L, "linux"); 127 | #elif __FreeBSD__ 128 | lua_pushstring(L, "bsd"); 129 | #elif __APPLE__ 130 | lua_pushstring(L, "osx"); 131 | #else 132 | lua_pushstring(L, "?"); 133 | #endif 134 | 135 | } else if (!strcmp(str, "exedir")) { 136 | UNUSED(dirname); 137 | #if _WIN32 138 | char buf[1024]; 139 | int len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); 140 | buf[len] = '\0'; 141 | dirname(buf); 142 | lua_pushfstring(L, "%s", buf); 143 | #elif __linux__ 144 | char path[128]; 145 | char buf[1024]; 146 | sprintf(path, "/proc/%d/exe", getpid()); 147 | int len = readlink(path, buf, sizeof(buf) - 1); 148 | ASSERT( len != -1 ); 149 | buf[len] = '\0'; 150 | dirname(buf); 151 | lua_pushfstring(L, "%s", buf); 152 | #elif __FreeBSD__ 153 | /* TODO : Implement this */ 154 | lua_pushfstring(L, "."); 155 | #elif __APPLE__ 156 | char buf[1024]; 157 | uint32_t size = sizeof(buf); 158 | ASSERT( _NSGetExecutablePath(buf, &size) == 0 ); 159 | dirname(buf); 160 | lua_pushfstring(L, "%s", buf); 161 | #else 162 | lua_pushfstring(L, "."); 163 | #endif 164 | 165 | } else if (!strcmp(str, "appdata")) { 166 | #if _WIN32 167 | lua_pushfstring(L, "%s", getenv("APPDATA")); 168 | #elif __APPLE__ 169 | lua_pushfstring(L, "%s/Library/Application Support", getenv("HOME")); 170 | #else 171 | lua_pushfstring(L, "%s/.local/share", getenv("HOME")); 172 | #endif 173 | } else { 174 | luaL_argerror(L, 1, "invalid string"); 175 | } 176 | return 1; 177 | } 178 | 179 | 180 | int luaopen_system(lua_State *L) { 181 | luaL_Reg reg[] = { 182 | { "poll", l_system_poll }, 183 | { "info", l_system_info }, 184 | { NULL, NULL } 185 | }; 186 | luaL_newlib(L, reg); 187 | return 1; 188 | } 189 | -------------------------------------------------------------------------------- /src/m_time.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifdef _WIN32 10 | #include 11 | #else 12 | #include 13 | #endif 14 | #include "luax.h" 15 | #include 16 | 17 | 18 | static int l_time_getNow(lua_State *L) { 19 | double t; 20 | #ifdef _WIN32 21 | FILETIME ft; 22 | GetSystemTimeAsFileTime(&ft); 23 | t = (ft.dwHighDateTime * 4294967296.0 / 1e7) + ft.dwLowDateTime / 1e7; 24 | t -= 11644473600.0; 25 | #else 26 | struct timeval tv; 27 | gettimeofday(&tv, NULL); 28 | t = tv.tv_sec + tv.tv_usec / 1e6; 29 | #endif 30 | lua_pushnumber(L, t); 31 | return 1; 32 | } 33 | 34 | 35 | static int l_time_getTime(lua_State *L) { 36 | lua_pushnumber(L, SDL_GetTicks() / 1000.); 37 | return 1; 38 | } 39 | 40 | 41 | static int l_time_sleep(lua_State *L) { 42 | SDL_Delay(luaL_checknumber(L, 1) * 1000.); 43 | return 0; 44 | } 45 | 46 | 47 | int luaopen_time(lua_State *L) { 48 | luaL_Reg reg[] = { 49 | { "getNow", l_time_getNow }, 50 | { "getTime", l_time_getTime }, 51 | { "sleep", l_time_sleep }, 52 | { NULL, NULL } 53 | }; 54 | luaL_newlib(L, reg); 55 | return 1; 56 | } 57 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "util.h" 14 | #include "luax.h" 15 | #include "m_source.h" 16 | 17 | 18 | extern double m_graphics_maxFps; 19 | 20 | static lua_State *L; 21 | static SDL_mutex *luaMutex; 22 | 23 | static void shutdown(void) { 24 | #ifndef __APPLE__ 25 | SDL_UnlockMutex(luaMutex); 26 | SDL_Quit(); 27 | #endif 28 | } 29 | 30 | int luaopen_juno(lua_State *L); 31 | 32 | int main(int argc, char **argv) { 33 | 34 | atexit(shutdown); 35 | 36 | /* Init lua state mutex and pass to sources module */ 37 | luaMutex = SDL_CreateMutex(); 38 | ASSERT(luaMutex); 39 | source_setLuaMutex(luaMutex); 40 | 41 | /* Init lua state */ 42 | L = luaL_newstate(); 43 | luaL_openlibs(L); 44 | 45 | /* Init main module -- this also inits the submodules */ 46 | luaL_requiref(L, "juno", luaopen_juno, 1); 47 | 48 | /* Push command line arguments */ 49 | lua_getglobal(L, "juno"); 50 | if (!lua_isnil(L, -1)) { 51 | lua_newtable(L); 52 | int i; 53 | for (i = 0; i < argc; i++) { 54 | lua_pushstring(L, argv[i]); 55 | lua_rawseti(L, -2, i + 1); 56 | } 57 | lua_setfield(L, -2, "_argv"); 58 | } 59 | lua_pop(L, 1); 60 | 61 | /* Init embedded scripts -- these should be ordered in the array in the order 62 | * we want them loaded; init.lua should always be last since it depends on 63 | * all the other modules */ 64 | #include "buffer_lua.h" 65 | #include "time_lua.h" 66 | #include "graphics_lua.h" 67 | #include "keyboard_lua.h" 68 | #include "mouse_lua.h" 69 | #include "debug_lua.h" 70 | #include "init_lua.h" 71 | struct { 72 | const char *name, *data; int size; 73 | } items[] = { 74 | { "buffer.lua", buffer_lua, sizeof(buffer_lua) }, 75 | { "time.lua", time_lua, sizeof(time_lua) }, 76 | { "graphics.lua", graphics_lua, sizeof(graphics_lua) }, 77 | { "keyboard.lua", keyboard_lua, sizeof(keyboard_lua) }, 78 | { "mouse.lua", mouse_lua, sizeof(mouse_lua) }, 79 | { "debug.lua", debug_lua, sizeof(debug_lua) }, 80 | { "init.lua", init_lua, sizeof(init_lua) }, 81 | { NULL, NULL, 0 } 82 | }; 83 | ASSERT(SDL_LockMutex(luaMutex) == 0); 84 | int i; 85 | for (i = 0; items[i].name; i++) { 86 | int err = luaL_loadbuffer(L, items[i].data, items[i].size, items[i].name); 87 | if (err || lua_pcall(L, 0, 0, 0) != 0) { 88 | const char *str = lua_tostring(L, -1); 89 | fprintf(stderr, "error: %s\n", str); 90 | abort(); 91 | } 92 | } 93 | ASSERT(SDL_UnlockMutex(luaMutex) == 0); 94 | 95 | /* Do main loop */ 96 | double last = 0; 97 | SDL_Surface *screen; 98 | for (;;) { 99 | screen = SDL_GetVideoSurface(); 100 | if (screen && SDL_MUSTLOCK(screen)) SDL_LockSurface(screen); 101 | ASSERT(SDL_LockMutex(luaMutex) == 0); 102 | lua_getglobal(L, "juno"); 103 | if (!lua_isnil(L, -1)) { 104 | lua_getfield(L, -1, "_onStep"); 105 | if (!lua_isnil(L, -1)) { 106 | int err = lua_pcall(L, 0, 0, 0); 107 | if (err) { 108 | const char *str = lua_tostring(L, -1); 109 | fprintf(stderr, "error: %s\n", str); 110 | abort(); 111 | } 112 | } 113 | lua_pop(L, 1); 114 | } 115 | ASSERT(SDL_UnlockMutex(luaMutex) == 0); 116 | if (screen && SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); 117 | /* Flip -- this blocks on some platforms (OSX) */ 118 | SDL_Surface *screen = SDL_GetVideoSurface(); 119 | if (screen) { 120 | SDL_Flip(screen); 121 | } 122 | /* Wait for next frame */ 123 | double step = (1. / m_graphics_maxFps); 124 | double now = SDL_GetTicks() / 1000.; 125 | double wait = step - (now - last); 126 | last += step; 127 | if (wait > 0) { 128 | SDL_Delay(wait * 1000.); 129 | } else { 130 | last = now; 131 | } 132 | } 133 | 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /src/ttf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include "ttf.h" 13 | #define STB_TRUETYPE_IMPLEMENTATION 14 | #include "lib/stb_truetype.h" 15 | 16 | /* ttf.c/h provides some higher level functionality around `stb_truetype` -- 17 | * most importantly it provides a function which takes a string and a font and 18 | * returns an 8bit bitmap of the rendered string's text. 19 | * 20 | * For better results for our use case (writing each character straight to a 21 | * single buffer), stb_truetype.h has been slightly modified at the end of the 22 | * stbtt__rasterize_sorted_edges() function so that the character is added to 23 | * the buffer rather than overwriting whatever already exists in it; this is 24 | * beneficial in situations where character bounding boxes may overlap. 25 | */ 26 | 27 | 28 | ttf_Font *ttf_new(const void *data, int len) { 29 | ttf_Font *self = calloc(1, sizeof(*self)); 30 | if (!self) { 31 | goto fail; 32 | } 33 | /* Copy font data */ 34 | self->fontData = malloc(len); 35 | if (!self->fontData) { 36 | goto fail; 37 | } 38 | memcpy(self->fontData, data, len); 39 | /* Init font */ 40 | if (!stbtt_InitFont(&self->font, self->fontData, 0)) { 41 | goto fail; 42 | } 43 | /* Init font size */ 44 | ttf_ptsize(self, 14); 45 | return self; 46 | fail: 47 | if (self) { 48 | ttf_destroy(self); 49 | } 50 | return NULL; 51 | } 52 | 53 | 54 | void ttf_destroy(ttf_Font *self) { 55 | free(self->fontData); 56 | free(self); 57 | } 58 | 59 | 60 | void ttf_ptsize(ttf_Font *self, float ptsize) { 61 | int ascent, descent, lineGap; 62 | self->ptsize = ptsize; 63 | self->scale = stbtt_ScaleForMappingEmToPixels(&self->font, self->ptsize); 64 | stbtt_GetFontVMetrics(&self->font, &ascent, &descent, &lineGap); 65 | self->baseline = ascent * self->scale + 1; 66 | } 67 | 68 | 69 | int ttf_height(ttf_Font *self) { 70 | int ascent, descent, lineGap; 71 | stbtt_GetFontVMetrics(&self->font, &ascent, &descent, &lineGap); 72 | return ceil((ascent - descent + lineGap) * self->scale) + 1; 73 | } 74 | 75 | 76 | static const char *ttf_utf8toCodepoint(const char *p, unsigned *res) { 77 | unsigned x, mask, shift; 78 | switch (*p & 0xf0) { 79 | case 0xf0: mask = 0x07; shift = 18; break; 80 | case 0xe0: mask = 0x0f; shift = 12; break; 81 | case 0xc0: 82 | case 0xd0: mask = 0x1f; shift = 6; break; 83 | default: 84 | *res = *p; 85 | return p + 1; 86 | } 87 | x = (*p & mask) << shift; 88 | do { 89 | /* Return early if we reach an unexpected NULL */ 90 | if (*(++p) == '\0') { 91 | *res = x; 92 | return p; 93 | } 94 | shift -= 6; 95 | x |= (*p & 0x3f) << shift; 96 | } while (shift); 97 | *res = x; 98 | return p + 1; 99 | } 100 | 101 | 102 | static float ttf_charWidthf(ttf_Font *self, int c, int last) { 103 | int res = 0; 104 | int width, lsb; 105 | stbtt_GetCodepointHMetrics(&self->font, c, &width, &lsb); 106 | res = width; 107 | if (last) { 108 | int kerning = stbtt_GetCodepointKernAdvance(&self->font, last, c); 109 | res += kerning; 110 | } 111 | return res * self->scale; 112 | } 113 | 114 | 115 | int ttf_width(ttf_Font *self, const char *str) { 116 | float res = 0; 117 | int last = 0; 118 | const char *p = str; 119 | while (*p) { 120 | unsigned c; 121 | p = ttf_utf8toCodepoint(p, &c); 122 | res += ttf_charWidthf(self, c, last); 123 | last = c; 124 | } 125 | return ceil(res); 126 | } 127 | 128 | 129 | void *ttf_render(ttf_Font *self, const char *str, int *w, int *h) { 130 | *w = ttf_width(self, str); 131 | *h = ttf_height(self); 132 | void *pixels = calloc(1, *w * *h); 133 | if (!pixels) return NULL; 134 | const char *p = str; 135 | float xoffset = 0; 136 | float xfract = 0; 137 | int last = 0; 138 | while (*p) { 139 | /* Get unicode codepoint */ 140 | unsigned c; 141 | p = ttf_utf8toCodepoint(p, &c); 142 | /* Get char placement coords */ 143 | int x0, y0, x1, y1; 144 | stbtt_GetCodepointBitmapBoxSubpixel( 145 | &self->font, c, self->scale, self->scale, xfract, 0, 146 | &x0, &y0, &x1, &y1); 147 | /* Work out position / max size */ 148 | int x = xoffset + x0; 149 | int y = self->baseline + y0; 150 | if (x < 0) x = 0; 151 | if (y < 0) y = 0; 152 | /* Render char */ 153 | stbtt_MakeCodepointBitmapSubpixel( 154 | &self->font, 155 | pixels + x + (y * *w), 156 | *w - x, *h - y, *w, self->scale, self->scale, 157 | xfract, 0, c); 158 | /* Next */ 159 | xoffset += ttf_charWidthf(self, c, last); 160 | xfract = xoffset - (int) xoffset; 161 | last = c; 162 | } 163 | return pixels; 164 | } 165 | 166 | -------------------------------------------------------------------------------- /src/ttf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef TTF_H 10 | #define TTF_H 11 | 12 | #include "lib/stb_truetype.h" 13 | 14 | typedef struct { 15 | stbtt_fontinfo font; 16 | void *fontData; 17 | float ptsize; 18 | float scale; 19 | int baseline; 20 | } ttf_Font; 21 | 22 | 23 | ttf_Font *ttf_new(const void *data, int len); 24 | void ttf_destroy(ttf_Font *self); 25 | void ttf_ptsize(ttf_Font *self, float ptsize); 26 | int ttf_height(ttf_Font *self); 27 | int ttf_width(ttf_Font *self, const char *str); 28 | void *ttf_render(ttf_Font *self, const char *str, int *w, int *h); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef UTIL_H 10 | #define UTIL_H 11 | 12 | #define ASSERT(x)\ 13 | do {\ 14 | if (!(x)) {\ 15 | fprintf(stderr, "%s:%d: %s(): assertion '%s' failed\n",\ 16 | __FILE__, __LINE__, __func__, #x);\ 17 | abort();\ 18 | }\ 19 | } while (0) 20 | 21 | #define UNUSED(x) ((void) (x)) 22 | #define MIN(a, b) ((b) < (a) ? (b) : (a)) 23 | #define MAX(a, b) ((b) > (a) ? (b) : (a)) 24 | #define CLAMP(x, a, b) (MAX(a, MIN(x, b))) 25 | #define LERP(a, b, p) ((a) + ((b) - (a)) * (p)) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/wav.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include "wav.h" 13 | 14 | typedef unsigned short Uint16; 15 | typedef unsigned int Uint32; 16 | 17 | 18 | static const char *findSubChunk( 19 | const char *data, size_t len, const char *id, size_t *size 20 | ) { 21 | /* TODO : Error handling on malformed wav file */ 22 | size_t idLen = strlen(id); 23 | const char *p = data + 12; 24 | next: 25 | *size = *((Uint32*) (p + 4)); 26 | if (memcmp(p, id, idLen)) { 27 | p += 8 + *size; 28 | if (p > data + len) return NULL; 29 | goto next; 30 | } 31 | return p + 8; 32 | } 33 | 34 | 35 | int wav_read(wav_t *w, const void *data, size_t len) { 36 | int bitdepth, channels, samplerate, format; 37 | size_t sz; 38 | const char *p = data; 39 | memset(w, 0, sizeof(*w)); 40 | /* Check header */ 41 | if (memcmp(p, "RIFF", 4) || memcmp(p + 8, "WAVE", 4)) { 42 | return WAV_EBADHEADER; 43 | } 44 | /* Find fmt subchunk */ 45 | p = findSubChunk(data, len, "fmt", &sz); 46 | if (!p) return WAV_ENOFMT; 47 | /* Load fmt info */ 48 | format = *((Uint16*) (p)); 49 | channels = *((Uint16*) (p + 2)); 50 | samplerate = *((Uint32*) (p + 4)); 51 | bitdepth = *((Uint16*) (p + 14)); 52 | if (format != 1) { 53 | return WAV_ENOSUPPORT; 54 | } 55 | if (channels == 0 || samplerate == 0 || bitdepth == 0) { 56 | return WAV_EBADFMT; 57 | } 58 | /* Find data subchunk */ 59 | p = findSubChunk(data, len, "data", &sz); 60 | if (!p) return WAV_ENODATA; 61 | /* Init wav_t struct */ 62 | w->data = p; 63 | w->samplerate = samplerate; 64 | w->channels = channels; 65 | w->length = (sz / (bitdepth / 8)) / channels; 66 | w->bitdepth = bitdepth; 67 | /* Done! */ 68 | return WAV_ESUCCESS; 69 | } 70 | 71 | 72 | const char *wav_strerror(int err) { 73 | switch (err) { 74 | case WAV_ESUCCESS : return "success"; 75 | case WAV_EFAILURE : return "failure"; 76 | case WAV_EBADHEADER : return "bad header data"; 77 | case WAV_EBADFMT : return "bad fmt data"; 78 | case WAV_ENOFMT : return "missing 'fmt' subchunk"; 79 | case WAV_ENODATA : return "missing 'data' subchunk"; 80 | case WAV_ENOSUPPORT : return "unsupported format; " 81 | "expected uncompressed PCM"; 82 | } 83 | return "unknown error"; 84 | } 85 | -------------------------------------------------------------------------------- /src/wav.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 rxi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it 5 | * under the terms of the MIT license. See LICENSE for details. 6 | */ 7 | 8 | 9 | #ifndef WAV_H 10 | #define WAV_H 11 | 12 | #include 13 | #include 14 | 15 | typedef struct { 16 | const void *data; 17 | int bitdepth; 18 | int samplerate; 19 | int channels; 20 | size_t length; 21 | } wav_t; 22 | 23 | enum { 24 | WAV_ESUCCESS = 0, 25 | WAV_EFAILURE = -1, 26 | WAV_EBADHEADER = -2, 27 | WAV_EBADFMT = -3, 28 | WAV_ENOFMT = -4, 29 | WAV_ENODATA = -5, 30 | WAV_ENOSUPPORT = -6 31 | }; 32 | 33 | int wav_read(wav_t *w, const void *data, size_t len); 34 | const char *wav_strerror(int err); 35 | 36 | #endif 37 | --------------------------------------------------------------------------------