├── LICENSE ├── README.md ├── build.py ├── doc ├── api.md ├── building.md └── packaging.md └── src ├── audio.c ├── audio.h ├── embed ├── boot.lua ├── font.ttf └── nogame.lua ├── event.c ├── event.h ├── filesystem.c ├── filesystem.h ├── font.c ├── font.h ├── image.c ├── image.h ├── keyboard.c ├── keyboard.h ├── lib ├── cmixer │ ├── cmixer.c │ └── cmixer.h ├── dmt │ ├── dmt.c │ └── dmt.h ├── lua │ ├── Makefile │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lbitlib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── 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.c_ │ ├── lua.h │ ├── lua.hpp │ ├── luac.c_ │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── microtar │ ├── microtar.c │ └── microtar.h └── stb │ ├── stb_image.c │ ├── stb_image.h │ ├── stb_truetype.c │ └── stb_truetype.h ├── luaobj.c ├── luaobj.h ├── main.c ├── modules ├── l_audio.c ├── l_event.c ├── l_filesystem.c ├── l_font.c ├── l_graphics.c ├── l_image.c ├── l_keyboard.c ├── l_love.c ├── l_mouse.c ├── l_quad.c ├── l_source.c ├── l_system.c └── l_timer.c ├── mouse.c ├── mouse.h ├── package.c ├── package.h ├── palette.c ├── palette.h ├── quad.h ├── soundblaster.c ├── soundblaster.h ├── vga.c └── vga.h /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 rxi 2 | 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | of the Software, and to permit persons to whom the Software is furnished to do 9 | so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LoveDOS 2 | A framework for making 2D DOS games in Lua. LoveDOS provides an API based on a 3 | subset of the [LÖVE](https://love2d.org/) API. 4 | 5 | ![screenshot](https://cloud.githubusercontent.com/assets/3920290/21948750/ed49e9a6-d9e4-11e6-960a-1fac0ec41ee0.gif) 6 | 7 | ## Getting started 8 | You can download LoveDOS from the 9 | [releases page](https://github.com/rxi/lovedos/releases). If you're not 10 | using DOS as your operating system then [DOSbox](http://www.dosbox.com/) can be 11 | used to emulate a DOS computer. 12 | 13 | When you run `love.exe` it will expect its first argument to be your game's 14 | directory. The file `main.lua` will then be searched for and executed. If, for 15 | example, your project was in a directory named `mygame` you would run the 16 | following: 17 | ```batch 18 | love mygame 19 | ``` 20 | 21 | A small example program which displays white text on a black background and 22 | exits when the `escape` key is pressed is as follows: 23 | 24 | ```lua 25 | function love.draw() 26 | love.graphics.print('Hello World!', 20, 20) 27 | end 28 | 29 | function love.keypressed(key) 30 | if key == "escape" then 31 | love.event.quit() 32 | end 33 | end 34 | ``` 35 | 36 | The [doc/api.md](doc/api.md) file provides a reference and overview of all of 37 | the built-in LoveDOS modules, functions and callbacks. 38 | 39 | The [doc/packaging.md](doc/packaging.md) file provides instructions for 40 | packaging your game for distribution. 41 | 42 | 43 | ## Building 44 | Instructions for building the project from source can be found in the 45 | [doc/building.md](doc/building.md) file. 46 | 47 | 48 | ## License 49 | This library is free software; you can redistribute it and/or modify it under 50 | the terms of the MIT license. See [LICENSE](LICENSE) for details. 51 | 52 | LoveDOS includes Lua (MIT license). The full license for Lua can be found at 53 | the bottom of the [src/lib/lua/lua.h](src/lib/lua/lua.h) file. 54 | -------------------------------------------------------------------------------- /build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.7 2 | import os, sys, shutil, re, textwrap 3 | 4 | COMPILER = "i586-pc-msdosdjgpp-gcc" 5 | SRC_DIR = "src" 6 | BIN_DIR = "bin" 7 | BIN_NAME = "love.exe" 8 | EMBED_DIR = "src/embed" 9 | TEMPSRC_DIR = ".tempsrc" 10 | 11 | CFLAGS = [ "-O2", "-Wall", "-s", "-Wno-misleading-indentation" ] 12 | DLIBS = [ "m" ] 13 | DEFINES = [ "DMT_ABORT_NULL", "LUA_COMPAT_ALL" ] 14 | INCLUDES = [ "src", TEMPSRC_DIR ] 15 | 16 | 17 | def fmt(fmt, var): 18 | for k in var: 19 | fmt = fmt.replace("{%s}" % str(k), var[k]) 20 | return fmt 21 | 22 | 23 | def listdir(path): 24 | return [os.path.join(dp, f) for dp, dn, fn in os.walk(path) for f in fn] 25 | 26 | 27 | def make_c_include(name, data): 28 | name = re.sub("[^a-z0-9]", "_", name.lower()) 29 | res = "static const char " + name + "[] = {" 30 | for c in data: 31 | res += str(ord(c)) + ", " 32 | res = res.rstrip(", ") + "};" 33 | return name, textwrap.fill(res, width=79) 34 | 35 | 36 | def main(): 37 | os.chdir(sys.path[0]) 38 | 39 | if not os.path.exists(BIN_DIR): 40 | os.makedirs(BIN_DIR) 41 | 42 | if not os.path.exists(TEMPSRC_DIR): 43 | os.makedirs(TEMPSRC_DIR) 44 | 45 | embedded_files = listdir(EMBED_DIR) 46 | 47 | for filename in embedded_files: 48 | name = os.path.basename(filename) 49 | name, text = make_c_include(name, open(filename).read()) 50 | open("%s/%s.h" % (TEMPSRC_DIR, name), "wb").write(text) 51 | 52 | cfiles = filter(lambda x:x.endswith((".c", ".C")), listdir(SRC_DIR)) 53 | 54 | cmd = fmt( 55 | "{compiler} {flags} {defines} {includes} -o {outfile} {srcfiles} {libs} {argv}", 56 | { 57 | "compiler" : COMPILER, 58 | "flags" : " ".join(CFLAGS), 59 | "defines" : " ".join(map(lambda x: "-D " + x, DEFINES)), 60 | "includes" : " ".join(map(lambda x: "-I " + x, INCLUDES)), 61 | "outfile" : BIN_DIR + "/" + BIN_NAME, 62 | "srcfiles" : " ".join(cfiles), 63 | "libs" : " ".join(map(lambda x: "-l" + x, DLIBS)), 64 | "argv" : " ".join(sys.argv[1:]) 65 | }) 66 | 67 | print "compiling..." 68 | res = os.system(cmd) 69 | 70 | print "deleting temporary files..." 71 | if os.path.exists(TEMPSRC_DIR): 72 | shutil.rmtree(TEMPSRC_DIR) 73 | 74 | print "done" + (" with errors" if res else "") 75 | 76 | 77 | 78 | if __name__ == "__main__": 79 | main() 80 | -------------------------------------------------------------------------------- /doc/building.md: -------------------------------------------------------------------------------- 1 | # Building LoveDOS 2 | Although LoveDOS provides precompiled binaries on the 3 | [releases page](https://github.com/rxi/lovedos/releases), you may still wish to 4 | build the project's source if you want to make changes to the project. 5 | 6 | 7 | ## Requirements 8 | LoveDOS depends on the following being installed before building: 9 | * **[Python2.7](https://www.python.org/)** is required by build.py, the build 10 | script 11 | * **[DJGPP cross compiler](https://github.com/andrewwutw/build-djgpp)** 12 | is required to compile the source files 13 | 14 | 15 | ## Building 16 | To compile you should clone the git repository or 17 | [download the .zip](https://github.com/rxi/lovedos/archive/master.zip) of it. 18 | Once this is done you should open the build.py file in an editor and check to 19 | make sure the COMPILER variable is set to the correct command as to run DJGPP's 20 | gcc executable; change the COMPILER variable's value if it is not set to the 21 | correct value. 22 | 23 | Assuming the COMPILER variable is correctly set the script should be run: 24 | ``` 25 | ./build.py 26 | ``` 27 | The script will output the following line when it starts: 28 | ``` 29 | compiling... 30 | ``` 31 | Within a minute the script should finish and display the following line: 32 | ``` 33 | done 34 | ``` 35 | There should now be a file named "love.exe" in the "bin/" directory 36 | -------------------------------------------------------------------------------- /doc/packaging.md: -------------------------------------------------------------------------------- 1 | # Packaging 2 | LoveDOS provides a built-in mechanism for packaging your game into an exe for 3 | distribution. Simply pass `--pack` as the first argument to LoveDOS followed by 4 | the your game's directory and the name of the output exe file. 5 | 6 | For example, to package the game in the directory `mygame` to an exe file named 7 | `mygame.exe`, you would run the following: 8 | ```batch 9 | love --pack mygame mygame.exe 10 | ``` 11 | 12 | This would result in the file `mygame.exe` -- *Make sure to include the `.exe` 13 | at the end of the name so LoveDOS knows to pack the project into an executable.* 14 | 15 | You should also include `cwsdpmi.exe` with your game when distributing. 16 | -------------------------------------------------------------------------------- /src/audio.c: -------------------------------------------------------------------------------- 1 | #include "lib/cmixer/cmixer.h" 2 | #include "soundblaster.h" 3 | 4 | 5 | static short audio_buffer[SOUNDBLASTER_SAMPLES_PER_BUFFER * 2]; 6 | 7 | static const short* audio_callback(void) { 8 | /* For the moment the soundblaster code expects mono audio while the cmixer 9 | ** library outputs stereo -- we process to a stereo buffer, then copy the left 10 | ** channel to the start of the buffer */ 11 | int i; 12 | int len = SOUNDBLASTER_SAMPLES_PER_BUFFER; 13 | cm_process(audio_buffer, len * 2); 14 | for (i = 0; i < len; i++) { 15 | audio_buffer[i] = audio_buffer[i * 2]; 16 | } 17 | return audio_buffer; 18 | } 19 | 20 | 21 | void audio_init(void) { 22 | cm_init(soundblaster_getSampleRate()); 23 | soundblaster_init(audio_callback); 24 | } 25 | 26 | 27 | void audio_deinit(void) { 28 | soundblaster_deinit(); 29 | } 30 | -------------------------------------------------------------------------------- /src/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIO_H 2 | #define AUDIO_H 3 | 4 | void audio_init(void); 5 | void audio_deinit(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/embed/boot.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2017 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 | function love.boot() 9 | -- Init package.path and add filesystem-compatible package loader 10 | package.path = "?.lua;?/init.lua" 11 | table.insert(package.loaders, 1, function(modname) 12 | modname = modname:gsub("%.", "/") 13 | for x in package.path:gmatch("[^;]+") do 14 | local file = x:gsub("?", modname) 15 | if love.filesystem.exists(file) then 16 | return assert(loadstring(love.filesystem.read(file), "=" .. file)) 17 | end 18 | end 19 | end) 20 | 21 | -- Init event handlers table 22 | local function makewrapper(name) 23 | return function(...) 24 | if love[name] then return love[name](...) end 25 | end 26 | end 27 | love.handlers = { 28 | ["quit"] = function() end, 29 | ["mousepressed"] = makewrapper("mousepressed"), 30 | ["mousereleased"] = makewrapper("mousereleased"), 31 | ["mousemoved"] = makewrapper("mousemoved"), 32 | ["keypressed"] = makewrapper("keypressed"), 33 | ["keyreleased"] = makewrapper("keyreleased"), 34 | ["textinput"] = makewrapper("textinput"), 35 | } 36 | 37 | -- Try to mount .exe file, then the first argument 38 | for i, v in ipairs { love.argv[1], love.argv[2] } do 39 | local mounted = love.filesystem.mount(v) 40 | if mounted then 41 | break 42 | end 43 | end 44 | 45 | -- Init the save directory - if it doesn't exist (can't be mounted) 46 | -- love.filesystem.write() is wrapped so that it is only set, created and 47 | -- mounted when write() is called 48 | local savedir = "save" 49 | local mounted = love.filesystem.mount(savedir) 50 | if mounted then 51 | love.filesystem.setWriteDir(savedir) 52 | else 53 | local old = love.filesystem.write 54 | love.filesystem.write = function(...) 55 | love.filesystem.setWriteDir(savedir) 56 | love.filesystem.mount(savedir) 57 | love.filesystem.write = old 58 | return old(...) 59 | end 60 | end 61 | 62 | -- Load main.lua or init `nogame` state 63 | if love.filesystem.isFile("main.lua") then 64 | require("main") 65 | else 66 | love.nogame() 67 | end 68 | 69 | love.run() 70 | end 71 | 72 | 73 | function love.run() 74 | -- Prepare arguments 75 | local args = {} 76 | for i = 2, #love.argv do 77 | args[i - 1] = love.argv[i] 78 | end 79 | 80 | -- Do load callback 81 | if love.load then love.load(args) end 82 | love.timer.step() 83 | 84 | while true do 85 | -- Handle events 86 | love.event.pump() 87 | while 1 do 88 | local name, a,b,c,d = love.event.poll() 89 | if not name then 90 | break 91 | end 92 | if name == "quit" then 93 | if not love.quit or not love.quit() then 94 | os.exit(a) 95 | end 96 | end 97 | love.handlers[name](a, b, c, d) 98 | end 99 | -- Update 100 | love.timer.step() 101 | local dt = love.timer.getDelta() 102 | if love.update then love.update(dt) end 103 | -- Draw 104 | love.graphics.clear() 105 | if love.draw then love.draw() end 106 | love.graphics.present() 107 | end 108 | end 109 | 110 | 111 | function love.errhand(msg) 112 | -- Init error text 113 | local err = { "Error\n", msg } 114 | local trace = debug.traceback("", 2) 115 | for line in string.gmatch(trace, "([^\t]-)\n") do 116 | table.insert(err, line) 117 | end 118 | local str = table.concat(err, "\n") 119 | 120 | -- Init error state 121 | love.graphics.reset() 122 | pcall(love.graphics.setBackgroundColor, 89, 157, 220) 123 | 124 | -- Do error main loop 125 | while true do 126 | love.event.pump() 127 | repeat 128 | local name, a = love.event.poll() 129 | if name == "keypressed" and a == "escape" then 130 | return 131 | end 132 | until not name 133 | love.graphics.clear() 134 | love.graphics.print(str, 6, 6) 135 | love.graphics.present() 136 | end 137 | end 138 | 139 | 140 | xpcall(love.boot, love.errhand) 141 | -------------------------------------------------------------------------------- /src/embed/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxi/lovedos/edbd20e79b5caa0b7a936b91de83767afde17242/src/embed/font.ttf -------------------------------------------------------------------------------- /src/embed/nogame.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (c) 2017 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 | function love.nogame() 9 | 10 | function love.load() 11 | love.graphics.setBackgroundColor(0, 138, 225) 12 | end 13 | 14 | function love.keypressed(key) 15 | if key == "escape" then 16 | os.exit() 17 | end 18 | end 19 | 20 | local function drawText(str, y) 21 | local screenw = love.graphics.getWidth() 22 | local font = love.graphics.getFont() 23 | love.graphics.print(str, (screenw - font:getWidth(str)) / 2, y) 24 | end 25 | 26 | function love.draw() 27 | love.graphics.setColor(255, 255, 255) 28 | drawText("LoveDOS " .. love.getVersion(), 90) 29 | drawText("No game", 102) 30 | love.graphics.setColor(95, 181, 255) 31 | drawText("Press ESCAPE to quit", 186) 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /src/event.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include "keyboard.h" 11 | #include "mouse.h" 12 | #include "event.h" 13 | 14 | #define BUFFER_SIZE 256 15 | #define BUFFER_MASK (BUFFER_SIZE - 1) 16 | 17 | static struct { 18 | event_t buffer[BUFFER_SIZE]; 19 | unsigned writei, readi; 20 | } events; 21 | 22 | 23 | const char* event_typestr(int type) { 24 | switch (type) { 25 | case EVENT_QUIT : return "quit"; 26 | case EVENT_KEYBOARD_PRESSED : return "keypressed"; 27 | case EVENT_KEYBOARD_RELEASED : return "keyreleased"; 28 | case EVENT_KEYBOARD_TEXTINPUT : return "textinput"; 29 | case EVENT_MOUSE_MOVED : return "mousemoved"; 30 | case EVENT_MOUSE_PRESSED : return "mousepressed"; 31 | case EVENT_MOUSE_RELEASED : return "mousereleased"; 32 | } 33 | return "?"; 34 | } 35 | 36 | 37 | void event_push(event_t *e) { 38 | events.buffer[events.writei++ & BUFFER_MASK] = *e; 39 | } 40 | 41 | 42 | void event_pump(void) { 43 | keyboard_update(); 44 | mouse_update(); 45 | } 46 | 47 | 48 | int event_poll(event_t *e) { 49 | if (events.readi != events.writei) { 50 | *e = events.buffer[events.readi++ & BUFFER_MASK]; 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/event.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 EVENT_H 9 | #define EVENT_H 10 | 11 | enum { 12 | EVENT_NULL, 13 | EVENT_QUIT, 14 | EVENT_KEYBOARD_PRESSED, 15 | EVENT_KEYBOARD_RELEASED, 16 | EVENT_KEYBOARD_TEXTINPUT, 17 | EVENT_MOUSE_MOVED, 18 | EVENT_MOUSE_PRESSED, 19 | EVENT_MOUSE_RELEASED 20 | }; 21 | 22 | typedef union { 23 | int type; 24 | 25 | struct { 26 | int type; 27 | int status; 28 | } quit; 29 | 30 | struct { 31 | int type; 32 | int x, y; 33 | int dx, dy; 34 | int button; 35 | } mouse; 36 | 37 | struct { 38 | int type; 39 | const char *key; 40 | char text[64]; 41 | int isrepeat; 42 | } keyboard; 43 | 44 | } event_t; 45 | 46 | 47 | const char* event_typestr(int type); 48 | void event_push(event_t *e); 49 | void event_pump(void); 50 | int event_poll(event_t *e); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/filesystem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 FILESYSTEM_H 9 | #define FILESYSTEM_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | enum { 16 | FILESYSTEM_ESUCCESS = 0, 17 | FILESYSTEM_EFAILURE = -1, 18 | FILESYSTEM_ETOOLONG = -2, 19 | FILESYSTEM_EMOUNTED = -3, 20 | FILESYSTEM_ENOMOUNT = -4, 21 | FILESYSTEM_EMOUNTFAIL = -5, 22 | FILESYSTEM_ENOWRITEDIR = -6, 23 | FILESYSTEM_EWRITEFAIL = -7, 24 | FILESYSTEM_EMKDIRFAIL = -8 25 | }; 26 | 27 | const char* filesystem_strerror(int err); 28 | void filesystem_deinit(void); 29 | int filesystem_mount(const char *path); 30 | int filesystem_unmount(const char *path); 31 | int filesystem_exists(const char *filename); 32 | int filesystem_isFile(const char *filename); 33 | int filesystem_isDirectory(const char *filename); 34 | void* filesystem_read(const char *filename, int *size); 35 | void filesystem_free(void *ptr); 36 | int filesystem_setWriteDir(const char *path); 37 | int filesystem_write(const char *filename, const void *data, int size); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/font.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | 12 | #include "lib/dmt/dmt.h" 13 | #include "lib/stb/stb_truetype.h" 14 | #include "filesystem.h" 15 | #include "font.h" 16 | 17 | 18 | static const char *initFont(font_t *self, const void *data, int ptsize) { 19 | int i; 20 | 21 | /* Init font */ 22 | stbtt_fontinfo font; 23 | if ( !stbtt_InitFont(&font, data, 0) ) { 24 | return "could not load font"; 25 | } 26 | 27 | /* Get height and scale */ 28 | int ascent, descent, lineGap; 29 | stbtt_GetFontVMetrics(&font, &ascent, &descent, &lineGap); 30 | float scale = stbtt_ScaleForMappingEmToPixels(&font, ptsize); 31 | self->height = (ascent - descent + lineGap) * scale + 0.5; 32 | 33 | /* Init image */ 34 | int w = 128, h = 128; 35 | retry: 36 | image_initBlank(&self->image, w, h); 37 | 38 | /* Load glyphs */ 39 | float s = stbtt_ScaleForMappingEmToPixels(&font, 1) / 40 | stbtt_ScaleForPixelHeight(&font, 1); 41 | int res = stbtt_BakeFontBitmap( 42 | data, 0, ptsize * s, self->image.data, w, h, 0, 128, self->glyphs); 43 | 44 | /* Retry with a larger image buffer if the buffer wasn't large enough */ 45 | if (res < 0) { 46 | w <<= 1; 47 | h <<= 1; 48 | image_deinit(&self->image); 49 | goto retry; 50 | } 51 | 52 | /* Adjust glyph yoffsets */ 53 | int scaledAscent = ascent * scale + 0.5; 54 | for (i = 0; i < 128; i++) { 55 | self->glyphs[i].yoff += scaledAscent; 56 | } 57 | 58 | /* Init image data and mask */ 59 | for (i = 0; i < w * h; i++) { 60 | self->image.data[i] = (self->image.data[i] > 127) ? 1 : 0; 61 | self->image.mask[i] = (self->image.data[i] == 0) ? 0xff : 0; 62 | } 63 | 64 | /* Return NULL for no error */ 65 | return NULL; 66 | } 67 | 68 | 69 | const char *font_init(font_t *self, const char *filename, int ptsize) { 70 | const char *errmsg = NULL; 71 | void *data = NULL; 72 | FILE *fp = NULL; 73 | memset(self, 0, sizeof(*self)); 74 | 75 | /* Load font file */ 76 | int size; 77 | data = filesystem_read(filename, &size); 78 | if (!data) { 79 | errmsg = "could not open font file"; 80 | goto fail; 81 | } 82 | 83 | /* Init font */ 84 | errmsg = initFont(self, data, ptsize); 85 | if (errmsg) { 86 | goto fail; 87 | } 88 | 89 | /* Free font data */ 90 | filesystem_free(data); 91 | data = NULL; 92 | 93 | return NULL; 94 | 95 | fail: 96 | if (fp) fclose(fp); 97 | filesystem_free(data); 98 | return errmsg; 99 | } 100 | 101 | 102 | const char *font_initEmbedded(font_t *self, int ptsize) { 103 | #include "font_ttf.h" 104 | return initFont(self, font_ttf, ptsize); 105 | } 106 | 107 | 108 | void font_deinit(font_t *self) { 109 | image_deinit(&self->image); 110 | } 111 | 112 | 113 | extern int image_blendMode; 114 | extern int image_flip; 115 | 116 | void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, 117 | const char *str, int dx, int dy 118 | ) { 119 | const char *p = str; 120 | int x = dx; 121 | int y = dy; 122 | 123 | int oldBlendMode = image_blendMode; 124 | int oldFlip = image_flip; 125 | image_blendMode = IMAGE_COLOR; 126 | image_flip = 0; 127 | 128 | while (*p) { 129 | if (*p == '\n') { 130 | x = dx; 131 | y += self->height; 132 | } else { 133 | stbtt_bakedchar *g = &self->glyphs[(int) (*p & 127)]; 134 | int w = g->x1 - g->x0; 135 | int h = g->y1 - g->y0; 136 | image_blit(&self->image, buf, bufw, bufh, 137 | x + g->xoff, y + g->yoff, g->x0, g->y0, w, h); 138 | x += g->xadvance; 139 | } 140 | p++; 141 | } 142 | 143 | image_blendMode = oldBlendMode; 144 | image_flip = oldFlip; 145 | } 146 | -------------------------------------------------------------------------------- /src/font.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 FONT_H 9 | #define FONT_H 10 | 11 | #include "image.h" 12 | #include "lib/stb/stb_truetype.h" 13 | 14 | typedef struct { 15 | image_t image; 16 | stbtt_bakedchar glyphs[128]; 17 | int height; 18 | } font_t; 19 | 20 | const char *font_init(font_t *self, const char *filename, int ptsize); 21 | const char *font_initEmbedded(font_t *self, int ptsize); 22 | void font_deinit(font_t *self); 23 | void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, 24 | const char *str, int dx, int dy); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/image.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | 12 | #include "lib/dmt/dmt.h" 13 | #include "lib/stb/stb_image.h" 14 | #include "filesystem.h" 15 | #include "image.h" 16 | #include "palette.h" 17 | 18 | int image_blendMode = IMAGE_NORMAL; 19 | int image_flip = 0; 20 | unsigned int image_color = 0x0f0f0f0f; 21 | 22 | 23 | void image_setBlendMode(int mode) { 24 | image_blendMode = mode; 25 | } 26 | 27 | void image_setColor(pixel_t color) { 28 | image_color = color | (color << 8) | (color << 16) | (color << 24); 29 | } 30 | 31 | void image_setFlip(int mode) { 32 | image_flip = !!mode; 33 | } 34 | 35 | 36 | 37 | const char *image_init(image_t *self, const char *filename) { 38 | /* Loads an image file into the struct and inits the mask */ 39 | const char *errmsg = NULL; 40 | void *filedata = NULL; 41 | unsigned char *data32 = NULL; 42 | memset(self, 0, sizeof(*self)); 43 | 44 | /* Load file data */ 45 | int size; 46 | filedata = filesystem_read(filename, &size); 47 | if (!filedata) { 48 | errmsg = "could not read file"; 49 | goto fail; 50 | } 51 | 52 | /* Load 32bit image data */ 53 | int width, height, n; 54 | data32 = stbi_load_from_memory(filedata, size, &width, &height, &n, 4); 55 | if (!data32) { 56 | errmsg = "could not load image file"; 57 | goto fail; 58 | } 59 | 60 | /* Free file data */ 61 | filesystem_free(filedata); 62 | filedata = NULL; 63 | 64 | /* Set dimensions and allocate memory */ 65 | int sz = width * height; 66 | self->width = width; 67 | self->height = height; 68 | self->data = dmt_malloc(sz); 69 | 70 | /* Load pixels into struct, converting 32bit to 8bit paletted */ 71 | int i; 72 | for (i = 0; i < width * height; i++) { 73 | unsigned char *p = data32 + i * 4; 74 | int r = p[0]; 75 | int g = p[1]; 76 | int b = p[2]; 77 | int a = p[3]; 78 | int idx = palette_colorToIdx(r, g, b); 79 | if (idx < 0) { 80 | errmsg = "color palette exhausted: use fewer unique colors"; 81 | goto fail; 82 | } 83 | self->data[i] = (a >= 127) ? idx : 0; 84 | } 85 | 86 | /* Init mask */ 87 | self->mask = dmt_malloc(sz); 88 | for (i = 0; i < sz; i++) { 89 | self->mask[i] = (self->data[i] == 0) ? 0xFF : 0x00; 90 | } 91 | 92 | /* Free 32bit pixel data, return NULL for no error */ 93 | free(data32); 94 | data32 = NULL; 95 | 96 | return NULL; 97 | 98 | fail: 99 | filesystem_free(filedata); 100 | free(data32); 101 | return errmsg; 102 | } 103 | 104 | 105 | void image_initBlank(image_t *self, int width, int height) { 106 | /* Creates a blank zeroset image with a zeroset mask. This function can be 107 | * used to init the image instead of image_init() */ 108 | memset(self, 0, sizeof(*self)); 109 | self->data = dmt_calloc(1, width * height); 110 | self->width = width; 111 | self->height = height; 112 | /* Init mask */ 113 | self->mask = dmt_calloc(1, width * height); 114 | } 115 | 116 | 117 | void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, 118 | int dx, int dy, int sx, int sy, int sw, int sh 119 | ) { 120 | int diff; 121 | 122 | /* Clip to source buffer */ 123 | if (sx < 0) { sw -= sx; sx = 0; } 124 | if (sy < 0) { sy -= sy; sy = 0; } 125 | if ((diff = (sx + sw) - self->width) > 0) { sw -= diff; } 126 | if ((diff = (sy + sh) - self->height) > 0) { sh -= diff; } 127 | 128 | /* Clip to destination buffer */ 129 | if (!image_flip) { 130 | if ((diff = -dx) > 0) { sw -= diff; sx += diff; dx += diff; } 131 | if ((diff = dx + sw - bufw) >= 0) { sw -= diff; } 132 | } else { 133 | if ((diff = -dx) > 0) { sw -= diff; dx += diff; } 134 | if ((diff = dx + sw - bufw) >= 0) { sx += diff; sw -= diff; } 135 | } 136 | if ((diff = dy + sh - bufh) >= 0) { sh -= diff; } 137 | if ((diff = -dy) > 0) { sh -= diff; sy += diff; dy += diff; } 138 | 139 | /* Return early if we're clipped entirely off the dest / source */ 140 | if (sw <= 0 || sh <= 0) return; 141 | 142 | /* Blit */ 143 | #define BLIT_LOOP_NORMAL(func)\ 144 | {\ 145 | int x, y;\ 146 | int srci = sx + sy * self->width;\ 147 | int dsti = dx + dy * bufw;\ 148 | int srcrowdiff = self->width - sw;\ 149 | int dstrowdiff = bufw - sw;\ 150 | int sw32 = sw - (sw & 3);\ 151 | for (y = 0; y < sh; y++) {\ 152 | for (x = 0; x < sw32; x += 4) {\ 153 | func(*(unsigned int*)&buf[dsti],\ 154 | *(unsigned int*)&self->data[srci],\ 155 | *(unsigned int*)&self->mask[srci])\ 156 | srci += 4;\ 157 | dsti += 4;\ 158 | }\ 159 | for (; x < sw; x++) {\ 160 | func(buf[dsti], self->data[srci], self->mask[srci])\ 161 | srci++;\ 162 | dsti++;\ 163 | }\ 164 | srci += srcrowdiff;\ 165 | dsti += dstrowdiff;\ 166 | }\ 167 | } 168 | 169 | #define BLIT_LOOP_FLIPPED(func)\ 170 | {\ 171 | int x, y;\ 172 | int srci = sx + sy * self->width + sw - 1;\ 173 | int dsti = dx + dy * bufw;\ 174 | int srcrowdiff = self->width + sw;\ 175 | int dstrowdiff = bufw - sw;\ 176 | for (y = 0; y < sh; y++) {\ 177 | for (x = 0; x < sw; x++) {\ 178 | func(buf[dsti], self->data[srci], self->mask[srci])\ 179 | srci--;\ 180 | dsti++;\ 181 | }\ 182 | srci += srcrowdiff;\ 183 | dsti += dstrowdiff;\ 184 | }\ 185 | } 186 | 187 | #define BLIT_NORMAL(dst, src, msk)\ 188 | (dst) &= (msk);\ 189 | (dst) |= (src); 190 | 191 | #define BLIT_AND(dst, src, msk)\ 192 | (dst) &= (src); 193 | 194 | #define BLIT_OR(dst, src, msk)\ 195 | (dst) |= (src); 196 | 197 | #define BLIT_COLOR(dst, src, msk)\ 198 | (dst) &= (msk);\ 199 | (dst) |= ~(msk) & image_color; 200 | 201 | #define BLIT(blit_loop)\ 202 | switch (image_blendMode) {\ 203 | default:\ 204 | case IMAGE_NORMAL : blit_loop(BLIT_NORMAL) break;\ 205 | case IMAGE_AND : blit_loop(BLIT_AND) break;\ 206 | case IMAGE_OR : blit_loop(BLIT_OR) break;\ 207 | case IMAGE_COLOR : blit_loop(BLIT_COLOR) break;\ 208 | }\ 209 | 210 | if (!image_flip) { 211 | if (image_blendMode == IMAGE_FAST) { 212 | int y; 213 | int srci = sx + sy * self->width; 214 | int dsti = dx + dy * bufw; 215 | for (y = 0; y < sh; y++) { 216 | memcpy(buf + dsti, self->data + srci, sw); 217 | srci += self->width; 218 | dsti += bufw; 219 | } 220 | } else { 221 | BLIT(BLIT_LOOP_NORMAL); 222 | } 223 | } else { 224 | BLIT(BLIT_LOOP_FLIPPED); 225 | } 226 | 227 | } 228 | 229 | 230 | void image_deinit(image_t *self) { 231 | dmt_free(self->data); 232 | dmt_free(self->mask); 233 | } 234 | -------------------------------------------------------------------------------- /src/image.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 IMAGE_H 9 | #define IMAGE_H 10 | 11 | #include "vga.h" 12 | #include "luaobj.h" 13 | 14 | 15 | enum { 16 | IMAGE_NORMAL, 17 | IMAGE_FAST, 18 | IMAGE_AND, 19 | IMAGE_OR, 20 | IMAGE_COLOR, 21 | } IMAGE_BLEND_MODE; 22 | 23 | 24 | typedef struct { 25 | pixel_t *data; 26 | pixel_t *mask; 27 | int width, height; 28 | } image_t; 29 | 30 | 31 | static inline 32 | void image_setPixel(image_t* self, int x, int y, pixel_t val) { 33 | if (x >= 0 && x < self->width && y >= 0 && y < self->height) { 34 | self->data[x + y * self->width] = val; 35 | } 36 | } 37 | 38 | static inline 39 | void image_setMaskPixel(image_t* self, int x, int y, pixel_t val) { 40 | if (x >= 0 && x < self->width && y >= 0 && y < self->height) { 41 | self->mask[x + y * self->width] = val; 42 | } 43 | } 44 | 45 | void image_setColor(pixel_t color); 46 | void image_setBlendMode(int mode); 47 | void image_setFlip(int mode); 48 | 49 | const char *image_init(image_t *self, const char *filename); 50 | void image_initBlank(image_t*, int, int); 51 | void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, 52 | int dx, int dy, int sx, int sy, int sw, int sh); 53 | void image_deinit(image_t*); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/keyboard.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "luaobj.h" 14 | #include "keyboard.h" 15 | #include "event.h" 16 | 17 | #define KEY_MAX 128 18 | #define BUFFER_SIZE 32 19 | #define BUFFER_MASK (BUFFER_SIZE - 1) 20 | 21 | static const char *scancodeMap[] = { 22 | [ 0] = "?", 23 | [ 1] = "escape", 24 | [ 2] = "1", 25 | [ 3] = "2", 26 | [ 4] = "3", 27 | [ 5] = "4", 28 | [ 6] = "5", 29 | [ 7] = "6", 30 | [ 8] = "7", 31 | [ 9] = "8", 32 | [ 10] = "9", 33 | [ 11] = "0", 34 | [ 12] = "-", 35 | [ 13] = "=", 36 | [ 14] = "backspace", 37 | [ 15] = "tab", 38 | [ 16] = "q", 39 | [ 17] = "w", 40 | [ 18] = "e", 41 | [ 19] = "r", 42 | [ 20] = "t", 43 | [ 21] = "y", 44 | [ 22] = "u", 45 | [ 23] = "i", 46 | [ 24] = "o", 47 | [ 25] = "p", 48 | [ 26] = "[", 49 | [ 27] = "]", 50 | [ 28] = "return", 51 | [ 29] = "lctrl", 52 | [ 30] = "a", 53 | [ 31] = "s", 54 | [ 32] = "d", 55 | [ 33] = "f", 56 | [ 34] = "g", 57 | [ 35] = "h", 58 | [ 36] = "j", 59 | [ 37] = "k", 60 | [ 38] = "l", 61 | [ 39] = ";", 62 | [ 40] = "\"", 63 | [ 41] = "`", 64 | [ 42] = "lshift", 65 | [ 43] = "\\", 66 | [ 44] = "z", 67 | [ 45] = "x", 68 | [ 46] = "c", 69 | [ 47] = "v", 70 | [ 48] = "b", 71 | [ 49] = "n", 72 | [ 50] = "m", 73 | [ 51] = ",", 74 | [ 52] = ".", 75 | [ 53] = "/", 76 | [ 54] = "rshift", 77 | [ 55] = "*", 78 | [ 56] = "lalt", 79 | [ 57] = "space", 80 | [ 58] = "capslock", 81 | [ 59] = "f1", 82 | [ 60] = "f2", 83 | [ 61] = "f3", 84 | [ 62] = "f4", 85 | [ 63] = "f5", 86 | [ 64] = "f6", 87 | [ 65] = "f7", 88 | [ 66] = "f8", 89 | [ 67] = "f9", 90 | [ 68] = "f10", 91 | [ 69] = "numlock", 92 | [ 70] = "scrolllock", 93 | [ 71] = "home", 94 | [ 72] = "up", 95 | [ 73] = "pageup", 96 | [ 74] = "-", 97 | [ 75] = "left", 98 | [ 76] = "5", 99 | [ 77] = "right", 100 | [ 78] = "+", 101 | [ 79] = "end", 102 | [ 80] = "down", 103 | [ 81] = "pagedown", 104 | [ 82] = "insert", 105 | [ 83] = "delete", 106 | [ 84] = "?", 107 | [ 85] = "?", 108 | [ 86] = "?", 109 | [ 87] = "?", 110 | [ 88] = "f12", 111 | [ 89] = "?", 112 | [ 90] = "?", 113 | [ 91] = "?", 114 | [ 92] = "?", 115 | [ 93] = "?", 116 | [ 94] = "?", 117 | [ 95] = "?", 118 | [ 96] = "enter", 119 | [ 97] = "lctrl", 120 | [ 98] = "/", 121 | [ 99] = "f12", 122 | [100] = "rctrl", 123 | [101] = "pause", 124 | [102] = "home", 125 | [103] = "up", 126 | [104] = "pageup", 127 | [105] = "left", 128 | [106] = "right", 129 | [107] = "end", 130 | [108] = "down", 131 | [109] = "pagedown", 132 | [110] = "insert", 133 | [111] = "?", 134 | [112] = "?", 135 | [113] = "?", 136 | [114] = "?", 137 | [115] = "?", 138 | [116] = "?", 139 | [117] = "?", 140 | [118] = "?", 141 | [119] = "pause", 142 | [120] = "?", 143 | [121] = "?", 144 | [122] = "?", 145 | [123] = "?", 146 | [124] = "?", 147 | [125] = "?", 148 | [126] = "?", 149 | [127] = "?", 150 | [128] = NULL, 151 | }; 152 | 153 | 154 | volatile int keyboard_allowKeyRepeat = 0; 155 | volatile char keyboard_keyStates[KEY_MAX]; 156 | 157 | enum { KEYPRESSED, KEYRELEASED }; 158 | typedef struct { unsigned char type, code, isrepeat; } key_event_t; 159 | 160 | volatile struct { 161 | key_event_t data[32]; 162 | unsigned readi, writei; 163 | } keyboard_events; 164 | 165 | _go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo; 166 | 167 | 168 | void keyboard_handler() { 169 | static unsigned char code; 170 | code = inportb(0x60); 171 | 172 | if (code != 224) { 173 | volatile key_event_t *e; 174 | /* Handle key up / down */ 175 | if (code & (1 << 7)) { 176 | /* Key up */ 177 | code &= ~(1 << 7); 178 | keyboard_keyStates[code] = 0; 179 | e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; 180 | e->type = KEYRELEASED; 181 | e->code = code; 182 | e->isrepeat = 0; 183 | keyboard_events.writei++; 184 | 185 | } else { 186 | /* Key down */ 187 | int isrepeat = keyboard_keyStates[code]; 188 | if (!isrepeat || keyboard_allowKeyRepeat) { 189 | keyboard_keyStates[code] = 1; 190 | e = &keyboard_events.data[keyboard_events.writei & BUFFER_MASK]; 191 | e->type = KEYPRESSED; 192 | e->code = code; 193 | e->isrepeat = isrepeat; 194 | keyboard_events.writei++; 195 | } 196 | } 197 | } 198 | 199 | outportb(0x20, 0x20); 200 | } 201 | 202 | 203 | void keyboard_handler_end() {} 204 | 205 | 206 | int keyboard_init(void) { 207 | _go32_dpmi_lock_data((char*)&keyboard_keyStates, KEY_MAX); 208 | _go32_dpmi_lock_data((char*)&keyboard_events, sizeof(keyboard_events)); 209 | _go32_dpmi_lock_code(keyboard_handler,(unsigned long)keyboard_handler_end - 210 | (unsigned long)keyboard_handler); 211 | _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); 212 | new_keyb_handler_seginfo.pm_offset = (int)keyboard_handler; 213 | _go32_dpmi_chain_protected_mode_interrupt_vector(9, &new_keyb_handler_seginfo); 214 | return 0; 215 | } 216 | 217 | 218 | void keyboard_deinit(void) { 219 | _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); 220 | } 221 | 222 | 223 | void keyboard_setKeyRepeat(int allow) { 224 | keyboard_allowKeyRepeat = allow; 225 | } 226 | 227 | 228 | int keyboard_isDown(const char *key) { 229 | int i; 230 | for (i = 0; scancodeMap[i]; i++) { 231 | if (!strcmp(scancodeMap[i], key)) { 232 | return keyboard_keyStates[i]; 233 | } 234 | } 235 | return 0; 236 | } 237 | 238 | 239 | void keyboard_update(void) { 240 | /* Handle key press / release */ 241 | while (keyboard_events.readi != keyboard_events.writei) { 242 | key_event_t ke = keyboard_events.data[keyboard_events.readi++ & BUFFER_MASK]; 243 | event_t e; 244 | if (ke.type == KEYPRESSED) { 245 | e.type = EVENT_KEYBOARD_PRESSED; 246 | } else { 247 | e.type = EVENT_KEYBOARD_RELEASED; 248 | } 249 | e.keyboard.key = scancodeMap[ke.code]; 250 | e.keyboard.isrepeat = ke.isrepeat; 251 | event_push(&e); 252 | } 253 | 254 | /* Handle text input */ 255 | char buf[64]; 256 | int i = 0; 257 | while ( kbhit() ) { 258 | int chr = getch(); 259 | if (chr == 0) { /* Discard "special" keys */ 260 | getch(); 261 | } else if (chr >= 32) { 262 | buf[i++] = chr; 263 | } 264 | } 265 | if (i > 0) { 266 | event_t e; 267 | e.type = EVENT_KEYBOARD_TEXTINPUT; 268 | memcpy(e.keyboard.text, buf, i); 269 | e.keyboard.text[i] = '\0'; 270 | event_push(&e); 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /src/keyboard.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 KEYBOARD_H 9 | #define KEYBOARD_H 10 | 11 | int keyboard_init(void); 12 | void keyboard_deinit(void); 13 | void keyboard_setKeyRepeat(int allow); 14 | int keyboard_isDown(const char *key); 15 | void keyboard_update(void); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/lib/cmixer/cmixer.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2017 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 `cmixer.c` for details. 6 | **/ 7 | 8 | #ifndef CMIXER_H 9 | #define CMIXER_H 10 | 11 | #define CM_VERSION "0.1.0" 12 | 13 | typedef short cm_Int16; 14 | typedef int cm_Int32; 15 | typedef long long cm_Int64; 16 | typedef unsigned char cm_UInt8; 17 | typedef unsigned short cm_UInt16; 18 | typedef unsigned cm_UInt32; 19 | 20 | typedef struct cm_Source cm_Source; 21 | 22 | typedef struct { 23 | int type; 24 | void *udata; 25 | const char *msg; 26 | cm_Int16 *buffer; 27 | int length; 28 | } cm_Event; 29 | 30 | typedef void (*cm_EventHandler)(cm_Event *e); 31 | 32 | typedef struct { 33 | cm_EventHandler handler; 34 | void *udata; 35 | int samplerate; 36 | int length; 37 | } cm_SourceInfo; 38 | 39 | 40 | enum { 41 | CM_STATE_STOPPED, 42 | CM_STATE_PLAYING, 43 | CM_STATE_PAUSED 44 | }; 45 | 46 | enum { 47 | CM_EVENT_LOCK, 48 | CM_EVENT_UNLOCK, 49 | CM_EVENT_DESTROY, 50 | CM_EVENT_SAMPLES, 51 | CM_EVENT_REWIND 52 | }; 53 | 54 | 55 | const char* cm_get_error(void); 56 | void cm_init(int samplerate); 57 | void cm_set_lock(cm_EventHandler lock); 58 | void cm_set_master_gain(double gain); 59 | void cm_process(cm_Int16 *dst, int len); 60 | 61 | cm_Source* cm_new_source(const cm_SourceInfo *info); 62 | cm_Source* cm_new_source_from_file(const char *filename); 63 | cm_Source* cm_new_source_from_mem(void *data, int size); 64 | void cm_destroy_source(cm_Source *src); 65 | double cm_get_length(cm_Source *src); 66 | double cm_get_position(cm_Source *src); 67 | int cm_get_state(cm_Source *src); 68 | void cm_set_gain(cm_Source *src, double gain); 69 | void cm_set_pan(cm_Source *src, double pan); 70 | void cm_set_pitch(cm_Source *src, double pitch); 71 | void cm_set_loop(cm_Source *src, int loop); 72 | void cm_play(cm_Source *src); 73 | void cm_pause(cm_Source *src); 74 | void cm_stop(cm_Source *src); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/lib/dmt/dmt.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013, 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 9 | #include 10 | #include 11 | 12 | #include "dmt.h" 13 | 14 | #ifdef DMT_STACK_TRACE 15 | #include 16 | #ifndef DMT_STACK_TRACE_MAX 17 | #define DMT_STACK_TRACE_MAX 32 18 | #endif 19 | #endif 20 | 21 | 22 | typedef struct dmt_node_t { 23 | struct dmt_node_t *prev, *next; 24 | const char *file; 25 | size_t line; 26 | size_t size; 27 | #ifdef DMT_STACK_TRACE 28 | void *stacktrace[DMT_STACK_TRACE_MAX]; 29 | size_t stacktrace_sz; 30 | #endif 31 | } dmt_node_t; 32 | 33 | 34 | dmt_node_t *dmt_head; 35 | 36 | 37 | 38 | int _dmt_has_node(dmt_node_t *n) { 39 | dmt_node_t *node = dmt_head; 40 | while (node != NULL) { 41 | if (node == n) return 1; 42 | node = node->next; 43 | } 44 | return 0; 45 | } 46 | 47 | 48 | 49 | void _dmt_abort(void) { 50 | #ifdef DMT_STACK_TRACE 51 | void *array[DMT_STACK_TRACE_MAX]; 52 | size_t sz = backtrace(array, DMT_STACK_TRACE_MAX); 53 | backtrace_symbols_fd(array, sz, fileno(stderr)); 54 | #endif 55 | abort(); 56 | } 57 | 58 | 59 | 60 | void *_dmt_alloc(size_t sz, int zeroset, const char *file, unsigned line) { 61 | dmt_node_t *node = NULL; 62 | 63 | if (zeroset) { 64 | node = calloc(sizeof(*node) + sz, 1); 65 | } else { 66 | node = malloc(sizeof(*node) + sz); 67 | if (node != NULL) { 68 | memset(node, 0, sizeof(*node)); 69 | } 70 | } 71 | 72 | if (node == NULL) { 73 | #ifdef DMT_ABORT_NULL 74 | fprintf(stderr, "Couldn't allocate: %s, line %u\n", file, line); 75 | _dmt_abort(); 76 | #else 77 | return NULL; 78 | #endif 79 | } 80 | 81 | node->line = line; 82 | node->file = file; 83 | node->size = sz; 84 | 85 | #ifdef DMT_STACK_TRACE 86 | node->stacktrace_sz = backtrace(node->stacktrace, DMT_STACK_TRACE_MAX); 87 | #endif 88 | 89 | if (dmt_head) { 90 | dmt_head->prev = node; 91 | node->next = dmt_head; 92 | } 93 | dmt_head = node; 94 | 95 | return (char*)node + sizeof(*node); 96 | } 97 | 98 | 99 | 100 | void *_dmt_realloc(void *ptr, size_t sz, const char *file, unsigned line) { 101 | dmt_node_t *node = (dmt_node_t*)((char*)ptr - sizeof(*node)); 102 | dmt_node_t *old_node = node; 103 | 104 | if (ptr == NULL) return _dmt_alloc(sz, 0, file, line); 105 | 106 | #ifndef DMT_UNSAFE 107 | if (!_dmt_has_node(node)) { 108 | fprintf(stderr, "Bad realloc: %p %s, line %u\n", ptr, file, line); 109 | _dmt_abort(); 110 | } 111 | #endif 112 | 113 | node = realloc(node, sizeof(*node) + sz); 114 | 115 | if (node == NULL) { 116 | #ifdef DMT_ABORT_NULL 117 | fprintf(stderr, "Couldn't reallocate: %s, line %u\n", file, line); 118 | _dmt_abort(); 119 | #else 120 | return NULL; 121 | #endif 122 | } 123 | 124 | node->size = sz; 125 | if (dmt_head == old_node) dmt_head = node; 126 | if (node->prev) node->prev->next = node; 127 | if (node->next) node->next->prev = node; 128 | 129 | return (char*)node + sizeof(*node); 130 | } 131 | 132 | 133 | 134 | void _dmt_free(void *ptr, const char *file, unsigned line) { 135 | dmt_node_t *node = (dmt_node_t*)((char*)ptr - sizeof(*node)); 136 | 137 | if (ptr == NULL) return; 138 | 139 | #ifndef DMT_UNSAFE 140 | if (!_dmt_has_node(node)) { 141 | fprintf(stderr, "Bad free: %p %s, line %u\n", ptr, file, line); 142 | _dmt_abort(); 143 | } 144 | #endif 145 | 146 | if (node == dmt_head) dmt_head = node->next; 147 | if (node->prev) node->prev->next = node->next; 148 | if (node->next) node->next->prev = node->prev; 149 | 150 | free(node); 151 | } 152 | 153 | 154 | 155 | void dmt_dump(FILE *fp) { 156 | dmt_node_t *node = dmt_head; 157 | size_t total = 0; 158 | 159 | if (!fp) fp = stdout; 160 | 161 | while (node != NULL) { 162 | fprintf(fp, "Unfreed: %p %s, line %lu (%lu bytes)\n", 163 | (char*)node + sizeof(*node), node->file, 164 | (unsigned long)node->line, (unsigned long)node->size); 165 | 166 | #ifdef DMT_STACK_TRACE 167 | backtrace_symbols_fd(node->stacktrace, node->stacktrace_sz, fileno(fp)); 168 | fprintf(fp, "\n"); 169 | #endif 170 | 171 | total += node->size; 172 | node = node->next; 173 | } 174 | 175 | fprintf(fp, "Total unfreed: %lu bytes\n", (unsigned long)total); 176 | } 177 | 178 | 179 | 180 | size_t _dmt_size(void *ptr, const char* file, unsigned line) { 181 | dmt_node_t *node = (dmt_node_t*)((char*)ptr - sizeof(*node)); 182 | 183 | #ifndef DMT_UNSAFE 184 | if (!_dmt_has_node(node)) { 185 | fprintf(stderr, "Bad pointer: %p %s, line %u\n", ptr, file, line); 186 | _dmt_abort(); 187 | } 188 | #endif 189 | 190 | return node->size; 191 | } 192 | 193 | 194 | 195 | size_t dmt_usage(void) { 196 | dmt_node_t *node = dmt_head; 197 | size_t total = 0; 198 | 199 | while (node != NULL) { 200 | total += node->size; 201 | node = node->next; 202 | } 203 | 204 | return total; 205 | } 206 | 207 | 208 | 209 | int dmt_has(void *ptr) { 210 | dmt_node_t *node = (dmt_node_t*)((char*)ptr - sizeof(*node)); 211 | return _dmt_has_node(node); 212 | } 213 | -------------------------------------------------------------------------------- /src/lib/dmt/dmt.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013, 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 DMT_H_ 9 | #define DMT_H_ 10 | 11 | #include 12 | 13 | #define dmt_malloc(sz) _dmt_alloc(sz, 0, __FILE__, __LINE__) 14 | #define dmt_calloc(num, sz) _dmt_alloc((num) * (sz), 1, __FILE__, __LINE__) 15 | #define dmt_realloc(ptr, sz) _dmt_realloc(ptr, sz, __FILE__, __LINE__) 16 | #define dmt_free(ptr) _dmt_free(ptr, __FILE__, __LINE__) 17 | #define dmt_size(ptr) _dmt_size(ptr, __FILE__, __LINE__) 18 | 19 | void *_dmt_alloc(size_t, int, const char*, unsigned); 20 | void *_dmt_realloc(void*, size_t, const char*, unsigned); 21 | void _dmt_free(void*, const char*, unsigned); 22 | size_t _dmt_size(void*, const char*, unsigned); 23 | 24 | void dmt_dump(FILE*); 25 | size_t dmt_usage(void); 26 | int dmt_has(void *ptr); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/lib/lua/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for building Lua 2 | # See ../doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | CC= gcc 10 | CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) 11 | LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) 12 | LIBS= -lm $(SYSLIBS) $(MYLIBS) 13 | 14 | AR= ar rcu 15 | RANLIB= ranlib 16 | RM= rm -f 17 | 18 | SYSCFLAGS= 19 | SYSLDFLAGS= 20 | SYSLIBS= 21 | 22 | MYCFLAGS= 23 | MYLDFLAGS= 24 | MYLIBS= 25 | MYOBJS= 26 | 27 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 28 | 29 | PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris 30 | 31 | LUA_A= liblua.a 32 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 34 | ltm.o lundump.o lvm.o lzio.o 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ 36 | lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) 38 | 39 | LUA_T= lua 40 | LUA_O= lua.o 41 | 42 | LUAC_T= luac 43 | LUAC_O= luac.o 44 | 45 | ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) 46 | ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) 47 | ALL_A= $(LUA_A) 48 | 49 | # Targets start here. 50 | default: $(PLAT) 51 | 52 | all: $(ALL_T) 53 | 54 | o: $(ALL_O) 55 | 56 | a: $(ALL_A) 57 | 58 | $(LUA_A): $(BASE_O) 59 | $(AR) $@ $(BASE_O) 60 | $(RANLIB) $@ 61 | 62 | $(LUA_T): $(LUA_O) $(LUA_A) 63 | $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) 64 | 65 | $(LUAC_T): $(LUAC_O) $(LUA_A) 66 | $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) 67 | 68 | clean: 69 | $(RM) $(ALL_T) $(ALL_O) 70 | 71 | depend: 72 | @$(CC) $(CFLAGS) -MM l*.c 73 | 74 | echo: 75 | @echo "PLAT= $(PLAT)" 76 | @echo "CC= $(CC)" 77 | @echo "CFLAGS= $(CFLAGS)" 78 | @echo "LDFLAGS= $(SYSLDFLAGS)" 79 | @echo "LIBS= $(LIBS)" 80 | @echo "AR= $(AR)" 81 | @echo "RANLIB= $(RANLIB)" 82 | @echo "RM= $(RM)" 83 | 84 | # Convenience targets for popular platforms 85 | ALL= all 86 | 87 | none: 88 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 89 | @echo " $(PLATS)" 90 | 91 | aix: 92 | $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" 93 | 94 | ansi: 95 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" 96 | 97 | bsd: 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" 99 | 100 | freebsd: 101 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" 102 | 103 | generic: $(ALL) 104 | 105 | linux: 106 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" 107 | 108 | macosx: 109 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc 110 | 111 | mingw: 112 | $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ 113 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ 114 | "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe 115 | $(MAKE) "LUAC_T=luac.exe" luac.exe 116 | 117 | posix: 118 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" 119 | 120 | solaris: 121 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" 122 | 123 | # list targets that do not create files (but not all makes understand .PHONY) 124 | .PHONY: all $(PLATS) default o a clean depend echo none 125 | 126 | # DO NOT DELETE 127 | 128 | lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ 129 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ 130 | lvm.h 131 | lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h 132 | lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h 133 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h 134 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 135 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ 136 | lstring.h ltable.h lvm.h 137 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h 138 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h 139 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h 140 | ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ 141 | ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ 142 | lfunc.h lstring.h lgc.h ltable.h lvm.h 143 | ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ 144 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ 145 | lstring.h ltable.h lundump.h lvm.h 146 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ 147 | lzio.h lmem.h lundump.h 148 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ 149 | lstate.h ltm.h lzio.h lmem.h 150 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 151 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 152 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h 153 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h 154 | llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ 155 | lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h 156 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h 157 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 158 | ltm.h lzio.h lmem.h ldo.h lgc.h 159 | loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h 160 | lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ 161 | lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h 162 | lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h 163 | loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h 164 | lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 165 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ 166 | lstring.h lgc.h ltable.h 167 | lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ 168 | ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ 169 | ltable.h 170 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ 171 | ltm.h lzio.h lstring.h lgc.h 172 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h 173 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 174 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 175 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h 176 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ 177 | lmem.h lstring.h lgc.h ltable.h 178 | lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h 179 | luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ 180 | ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h 181 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ 182 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h 183 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 184 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h 185 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ 186 | lzio.h 187 | 188 | -------------------------------------------------------------------------------- /src/lib/lua/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 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 "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/lib/lua/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 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 | 19 | /* extra error code for `luaL_load' */ 20 | #define LUA_ERRFILE (LUA_ERRERR+1) 21 | 22 | 23 | typedef struct luaL_Reg { 24 | const char *name; 25 | lua_CFunction func; 26 | } luaL_Reg; 27 | 28 | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) 31 | 32 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 33 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 34 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 35 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 36 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 37 | size_t *l); 38 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 39 | const char *def, size_t *l); 40 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 41 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 42 | 43 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 44 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 45 | lua_Integer def); 46 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); 47 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, 48 | lua_Unsigned def); 49 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 53 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 56 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 57 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 58 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 61 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 63 | const char *const lst[]); 64 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 67 | 68 | /* pre-defined references */ 69 | #define LUA_NOREF (-2) 70 | #define LUA_REFNIL (-1) 71 | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 74 | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 76 | const char *mode); 77 | 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 79 | 80 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 81 | const char *name, const char *mode); 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 83 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); 85 | 86 | LUALIB_API int (luaL_len) (lua_State *L, int idx); 87 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 89 | const char *r); 90 | 91 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 92 | 93 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 94 | 95 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 96 | const char *msg, int level); 97 | 98 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 99 | lua_CFunction openf, int glb); 100 | 101 | /* 102 | ** =============================================================== 103 | ** some useful macros 104 | ** =============================================================== 105 | */ 106 | 107 | 108 | #define luaL_newlibtable(L,l) \ 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 110 | 111 | #define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 112 | 113 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 114 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 115 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 116 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 117 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 118 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 119 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 120 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 121 | 122 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 123 | 124 | #define luaL_dofile(L, fn) \ 125 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 126 | 127 | #define luaL_dostring(L, s) \ 128 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 129 | 130 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 131 | 132 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 133 | 134 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 135 | 136 | 137 | /* 138 | ** {====================================================== 139 | ** Generic Buffer manipulation 140 | ** ======================================================= 141 | */ 142 | 143 | typedef struct luaL_Buffer { 144 | char *b; /* buffer address */ 145 | size_t size; /* buffer size */ 146 | size_t n; /* number of characters in buffer */ 147 | lua_State *L; 148 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ 149 | } luaL_Buffer; 150 | 151 | 152 | #define luaL_addchar(B,c) \ 153 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 154 | ((B)->b[(B)->n++] = (c))) 155 | 156 | #define luaL_addsize(B,s) ((B)->n += (s)) 157 | 158 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 159 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 160 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 161 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 162 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 163 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 164 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 165 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 166 | 167 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 168 | 169 | /* }====================================================== */ 170 | 171 | 172 | 173 | /* 174 | ** {====================================================== 175 | ** File handles for IO library 176 | ** ======================================================= 177 | */ 178 | 179 | /* 180 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 181 | ** initial structure 'luaL_Stream' (it may contain other fields 182 | ** after that initial structure). 183 | */ 184 | 185 | #define LUA_FILEHANDLE "FILE*" 186 | 187 | 188 | typedef struct luaL_Stream { 189 | FILE *f; /* stream (NULL for incompletely created streams) */ 190 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 191 | } luaL_Stream; 192 | 193 | /* }====================================================== */ 194 | 195 | 196 | 197 | /* compatibility with old module system */ 198 | #if defined(LUA_COMPAT_MODULE) 199 | 200 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, 201 | int sizehint); 202 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 203 | const luaL_Reg *l, int nup); 204 | 205 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) 206 | 207 | #endif 208 | 209 | 210 | #endif 211 | 212 | 213 | -------------------------------------------------------------------------------- /src/lib/lua/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lua.h" 11 | 12 | #include "lauxlib.h" 13 | #include "lualib.h" 14 | 15 | 16 | /* number of bits to consider in a number */ 17 | #if !defined(LUA_NBITS) 18 | #define LUA_NBITS 32 19 | #endif 20 | 21 | 22 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 23 | 24 | /* macro to trim extra bits */ 25 | #define trim(x) ((x) & ALLONES) 26 | 27 | 28 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 29 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 30 | 31 | 32 | typedef lua_Unsigned b_uint; 33 | 34 | 35 | 36 | static b_uint andaux (lua_State *L) { 37 | int i, n = lua_gettop(L); 38 | b_uint r = ~(b_uint)0; 39 | for (i = 1; i <= n; i++) 40 | r &= luaL_checkunsigned(L, i); 41 | return trim(r); 42 | } 43 | 44 | 45 | static int b_and (lua_State *L) { 46 | b_uint r = andaux(L); 47 | lua_pushunsigned(L, r); 48 | return 1; 49 | } 50 | 51 | 52 | static int b_test (lua_State *L) { 53 | b_uint r = andaux(L); 54 | lua_pushboolean(L, r != 0); 55 | return 1; 56 | } 57 | 58 | 59 | static int b_or (lua_State *L) { 60 | int i, n = lua_gettop(L); 61 | b_uint r = 0; 62 | for (i = 1; i <= n; i++) 63 | r |= luaL_checkunsigned(L, i); 64 | lua_pushunsigned(L, trim(r)); 65 | return 1; 66 | } 67 | 68 | 69 | static int b_xor (lua_State *L) { 70 | int i, n = lua_gettop(L); 71 | b_uint r = 0; 72 | for (i = 1; i <= n; i++) 73 | r ^= luaL_checkunsigned(L, i); 74 | lua_pushunsigned(L, trim(r)); 75 | return 1; 76 | } 77 | 78 | 79 | static int b_not (lua_State *L) { 80 | b_uint r = ~luaL_checkunsigned(L, 1); 81 | lua_pushunsigned(L, trim(r)); 82 | return 1; 83 | } 84 | 85 | 86 | static int b_shift (lua_State *L, b_uint r, int i) { 87 | if (i < 0) { /* shift right? */ 88 | i = -i; 89 | r = trim(r); 90 | if (i >= LUA_NBITS) r = 0; 91 | else r >>= i; 92 | } 93 | else { /* shift left */ 94 | if (i >= LUA_NBITS) r = 0; 95 | else r <<= i; 96 | r = trim(r); 97 | } 98 | lua_pushunsigned(L, r); 99 | return 1; 100 | } 101 | 102 | 103 | static int b_lshift (lua_State *L) { 104 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); 105 | } 106 | 107 | 108 | static int b_rshift (lua_State *L) { 109 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); 110 | } 111 | 112 | 113 | static int b_arshift (lua_State *L) { 114 | b_uint r = luaL_checkunsigned(L, 1); 115 | int i = luaL_checkint(L, 2); 116 | if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) 117 | return b_shift(L, r, -i); 118 | else { /* arithmetic shift for 'negative' number */ 119 | if (i >= LUA_NBITS) r = ALLONES; 120 | else 121 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ 122 | lua_pushunsigned(L, r); 123 | return 1; 124 | } 125 | } 126 | 127 | 128 | static int b_rot (lua_State *L, int i) { 129 | b_uint r = luaL_checkunsigned(L, 1); 130 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ 131 | r = trim(r); 132 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ 133 | r = (r << i) | (r >> (LUA_NBITS - i)); 134 | lua_pushunsigned(L, trim(r)); 135 | return 1; 136 | } 137 | 138 | 139 | static int b_lrot (lua_State *L) { 140 | return b_rot(L, luaL_checkint(L, 2)); 141 | } 142 | 143 | 144 | static int b_rrot (lua_State *L) { 145 | return b_rot(L, -luaL_checkint(L, 2)); 146 | } 147 | 148 | 149 | /* 150 | ** get field and width arguments for field-manipulation functions, 151 | ** checking whether they are valid. 152 | ** ('luaL_error' called without 'return' to avoid later warnings about 153 | ** 'width' being used uninitialized.) 154 | */ 155 | static int fieldargs (lua_State *L, int farg, int *width) { 156 | int f = luaL_checkint(L, farg); 157 | int w = luaL_optint(L, farg + 1, 1); 158 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 159 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 160 | if (f + w > LUA_NBITS) 161 | luaL_error(L, "trying to access non-existent bits"); 162 | *width = w; 163 | return f; 164 | } 165 | 166 | 167 | static int b_extract (lua_State *L) { 168 | int w; 169 | b_uint r = luaL_checkunsigned(L, 1); 170 | int f = fieldargs(L, 2, &w); 171 | r = (r >> f) & mask(w); 172 | lua_pushunsigned(L, r); 173 | return 1; 174 | } 175 | 176 | 177 | static int b_replace (lua_State *L) { 178 | int w; 179 | b_uint r = luaL_checkunsigned(L, 1); 180 | b_uint v = luaL_checkunsigned(L, 2); 181 | int f = fieldargs(L, 3, &w); 182 | int m = mask(w); 183 | v &= m; /* erase bits outside given width */ 184 | r = (r & ~(m << f)) | (v << f); 185 | lua_pushunsigned(L, r); 186 | return 1; 187 | } 188 | 189 | 190 | static const luaL_Reg bitlib[] = { 191 | {"arshift", b_arshift}, 192 | {"band", b_and}, 193 | {"bnot", b_not}, 194 | {"bor", b_or}, 195 | {"bxor", b_xor}, 196 | {"btest", b_test}, 197 | {"extract", b_extract}, 198 | {"lrotate", b_lrot}, 199 | {"lshift", b_lshift}, 200 | {"replace", b_replace}, 201 | {"rrotate", b_rrot}, 202 | {"rshift", b_rshift}, 203 | {NULL, NULL} 204 | }; 205 | 206 | 207 | 208 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 209 | luaL_newlib(L, bitlib); 210 | return 1; 211 | } 212 | 213 | -------------------------------------------------------------------------------- /src/lib/lua/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 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 (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 28 | OPR_CONCAT, 29 | OPR_EQ, OPR_LT, OPR_LE, 30 | OPR_NE, 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.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 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 46 | 47 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 48 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 49 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 50 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 51 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 52 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 53 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 54 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 55 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 56 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 57 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 58 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 59 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 60 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 61 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 62 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 63 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 64 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 65 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 66 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 67 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 68 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 69 | LUAI_FUNC int luaK_jump (FuncState *fs); 70 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 71 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 72 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 73 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 74 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 75 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 76 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 77 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 78 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 79 | expdesc *v2, int line); 80 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/lib/lua/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | 11 | #define lcorolib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | static int auxresume (lua_State *L, lua_State *co, int narg) { 21 | int status; 22 | if (!lua_checkstack(co, narg)) { 23 | lua_pushliteral(L, "too many arguments to resume"); 24 | return -1; /* error flag */ 25 | } 26 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 27 | lua_pushliteral(L, "cannot resume dead coroutine"); 28 | return -1; /* error flag */ 29 | } 30 | lua_xmove(L, co, narg); 31 | status = lua_resume(co, L, narg); 32 | if (status == LUA_OK || status == LUA_YIELD) { 33 | int nres = lua_gettop(co); 34 | if (!lua_checkstack(L, nres + 1)) { 35 | lua_pop(co, nres); /* remove results anyway */ 36 | lua_pushliteral(L, "too many results to resume"); 37 | return -1; /* error flag */ 38 | } 39 | lua_xmove(co, L, nres); /* move yielded values */ 40 | return nres; 41 | } 42 | else { 43 | lua_xmove(co, L, 1); /* move error message */ 44 | return -1; /* error flag */ 45 | } 46 | } 47 | 48 | 49 | static int luaB_coresume (lua_State *L) { 50 | lua_State *co = lua_tothread(L, 1); 51 | int r; 52 | luaL_argcheck(L, co, 1, "coroutine expected"); 53 | r = auxresume(L, co, lua_gettop(L) - 1); 54 | if (r < 0) { 55 | lua_pushboolean(L, 0); 56 | lua_insert(L, -2); 57 | return 2; /* return false + error message */ 58 | } 59 | else { 60 | lua_pushboolean(L, 1); 61 | lua_insert(L, -(r + 1)); 62 | return r + 1; /* return true + `resume' returns */ 63 | } 64 | } 65 | 66 | 67 | static int luaB_auxwrap (lua_State *L) { 68 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 69 | int r = auxresume(L, co, lua_gettop(L)); 70 | if (r < 0) { 71 | if (lua_isstring(L, -1)) { /* error object is a string? */ 72 | luaL_where(L, 1); /* add extra info */ 73 | lua_insert(L, -2); 74 | lua_concat(L, 2); 75 | } 76 | return lua_error(L); /* propagate error */ 77 | } 78 | return r; 79 | } 80 | 81 | 82 | static int luaB_cocreate (lua_State *L) { 83 | lua_State *NL; 84 | luaL_checktype(L, 1, LUA_TFUNCTION); 85 | NL = lua_newthread(L); 86 | lua_pushvalue(L, 1); /* move function to top */ 87 | lua_xmove(L, NL, 1); /* move function from L to NL */ 88 | return 1; 89 | } 90 | 91 | 92 | static int luaB_cowrap (lua_State *L) { 93 | luaB_cocreate(L); 94 | lua_pushcclosure(L, luaB_auxwrap, 1); 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_yield (lua_State *L) { 100 | return lua_yield(L, lua_gettop(L)); 101 | } 102 | 103 | 104 | static int luaB_costatus (lua_State *L) { 105 | lua_State *co = lua_tothread(L, 1); 106 | luaL_argcheck(L, co, 1, "coroutine expected"); 107 | if (L == co) lua_pushliteral(L, "running"); 108 | else { 109 | switch (lua_status(co)) { 110 | case LUA_YIELD: 111 | lua_pushliteral(L, "suspended"); 112 | break; 113 | case LUA_OK: { 114 | lua_Debug ar; 115 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 116 | lua_pushliteral(L, "normal"); /* it is running */ 117 | else if (lua_gettop(co) == 0) 118 | lua_pushliteral(L, "dead"); 119 | else 120 | lua_pushliteral(L, "suspended"); /* initial state */ 121 | break; 122 | } 123 | default: /* some error occurred */ 124 | lua_pushliteral(L, "dead"); 125 | break; 126 | } 127 | } 128 | return 1; 129 | } 130 | 131 | 132 | static int luaB_corunning (lua_State *L) { 133 | int ismain = lua_pushthread(L); 134 | lua_pushboolean(L, ismain); 135 | return 2; 136 | } 137 | 138 | 139 | static const luaL_Reg co_funcs[] = { 140 | {"create", luaB_cocreate}, 141 | {"resume", luaB_coresume}, 142 | {"running", luaB_corunning}, 143 | {"status", luaB_costatus}, 144 | {"wrap", luaB_cowrap}, 145 | {"yield", luaB_yield}, 146 | {NULL, NULL} 147 | }; 148 | 149 | 150 | 151 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 152 | luaL_newlib(L, co_funcs); 153 | return 1; 154 | } 155 | 156 | -------------------------------------------------------------------------------- /src/lib/lua/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lctype.h" 11 | 12 | #if !LUA_USE_CTYPE /* { */ 13 | 14 | #include 15 | 16 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 17 | 0x00, /* EOZ */ 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 19 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 23 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 24 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 25 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 26 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 27 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 28 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 29 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 30 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 32 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 33 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | }; 51 | 52 | #endif /* } */ 53 | -------------------------------------------------------------------------------- /src/lib/lua/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /src/lib/lua/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 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 getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | /* Active Lua function (given call info) */ 21 | #define ci_func(ci) (clLvalue((ci)->func)) 22 | 23 | 24 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 25 | const char *opname); 26 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); 27 | LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, 28 | const TValue *p2); 29 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 30 | const TValue *p2); 31 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 32 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/lib/lua/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 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) if (L->stack_last - L->top <= (n)) \ 17 | luaD_growstack(L, n); else condmovestack(L); 18 | 19 | 20 | #define incr_top(L) {L->top++; luaD_checkstack(L,0);} 21 | 22 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 23 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 24 | 25 | 26 | /* type of protected functions, to be ran by `runprotected' */ 27 | typedef void (*Pfunc) (lua_State *L, void *ud); 28 | 29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 30 | const char *mode); 31 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 32 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 33 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, 34 | int allowyield); 35 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 36 | ptrdiff_t oldtop, ptrdiff_t ef); 37 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 38 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 39 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 40 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 41 | 42 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 43 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /src/lib/lua/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 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) 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*sizeof(char),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, 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(ttypenv(o),D); 88 | switch (ttypenv(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: lua_assert(0); 102 | } 103 | } 104 | n=f->sizep; 105 | DumpInt(n,D); 106 | for (i=0; ip[i],D); 107 | } 108 | 109 | static void DumpUpvalues(const Proto* f, DumpState* D) 110 | { 111 | int i,n=f->sizeupvalues; 112 | DumpInt(n,D); 113 | for (i=0; iupvalues[i].instack,D); 116 | DumpChar(f->upvalues[i].idx,D); 117 | } 118 | } 119 | 120 | static void DumpDebug(const Proto* f, DumpState* D) 121 | { 122 | int i,n; 123 | DumpString((D->strip) ? NULL : f->source,D); 124 | n= (D->strip) ? 0 : f->sizelineinfo; 125 | DumpVector(f->lineinfo,n,sizeof(int),D); 126 | n= (D->strip) ? 0 : f->sizelocvars; 127 | DumpInt(n,D); 128 | for (i=0; ilocvars[i].varname,D); 131 | DumpInt(f->locvars[i].startpc,D); 132 | DumpInt(f->locvars[i].endpc,D); 133 | } 134 | n= (D->strip) ? 0 : f->sizeupvalues; 135 | DumpInt(n,D); 136 | for (i=0; iupvalues[i].name,D); 137 | } 138 | 139 | static void DumpFunction(const Proto* f, DumpState* D) 140 | { 141 | DumpInt(f->linedefined,D); 142 | DumpInt(f->lastlinedefined,D); 143 | DumpChar(f->numparams,D); 144 | DumpChar(f->is_vararg,D); 145 | DumpChar(f->maxstacksize,D); 146 | DumpCode(f,D); 147 | DumpConstants(f,D); 148 | DumpUpvalues(f,D); 149 | DumpDebug(f,D); 150 | } 151 | 152 | static void DumpHeader(DumpState* D) 153 | { 154 | lu_byte h[LUAC_HEADERSIZE]; 155 | luaU_header(h); 156 | DumpBlock(h,LUAC_HEADERSIZE,D); 157 | } 158 | 159 | /* 160 | ** dump Lua function as precompiled chunk 161 | */ 162 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) 163 | { 164 | DumpState D; 165 | D.L=L; 166 | D.writer=w; 167 | D.data=data; 168 | D.strip=strip; 169 | D.status=0; 170 | DumpHeader(&D); 171 | DumpFunction(f,&D); 172 | return D.status; 173 | } 174 | -------------------------------------------------------------------------------- /src/lib/lua/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 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 n) { 24 | Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; 25 | c->c.nupvalues = cast_byte(n); 26 | return c; 27 | } 28 | 29 | 30 | Closure *luaF_newLclosure (lua_State *L, int n) { 31 | Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; 32 | c->l.p = NULL; 33 | c->l.nupvalues = cast_byte(n); 34 | while (n--) c->l.upvals[n] = NULL; 35 | return c; 36 | } 37 | 38 | 39 | UpVal *luaF_newupval (lua_State *L) { 40 | UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; 41 | uv->v = &uv->u.value; 42 | setnilvalue(uv->v); 43 | return uv; 44 | } 45 | 46 | 47 | UpVal *luaF_findupval (lua_State *L, StkId level) { 48 | global_State *g = G(L); 49 | GCObject **pp = &L->openupval; 50 | UpVal *p; 51 | UpVal *uv; 52 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { 53 | GCObject *o = obj2gco(p); 54 | lua_assert(p->v != &p->u.value); 55 | lua_assert(!isold(o) || isold(obj2gco(L))); 56 | if (p->v == level) { /* found a corresponding upvalue? */ 57 | if (isdead(g, o)) /* is it dead? */ 58 | changewhite(o); /* resurrect it */ 59 | return p; 60 | } 61 | pp = &p->next; 62 | } 63 | /* not found: create a new one */ 64 | uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; 65 | uv->v = level; /* current value lives in the stack */ 66 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 67 | uv->u.l.next = g->uvhead.u.l.next; 68 | uv->u.l.next->u.l.prev = uv; 69 | g->uvhead.u.l.next = uv; 70 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 71 | return uv; 72 | } 73 | 74 | 75 | static void unlinkupval (UpVal *uv) { 76 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 77 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ 78 | uv->u.l.prev->u.l.next = uv->u.l.next; 79 | } 80 | 81 | 82 | void luaF_freeupval (lua_State *L, UpVal *uv) { 83 | if (uv->v != &uv->u.value) /* is it open? */ 84 | unlinkupval(uv); /* remove from open list */ 85 | luaM_free(L, uv); /* free upvalue */ 86 | } 87 | 88 | 89 | void luaF_close (lua_State *L, StkId level) { 90 | UpVal *uv; 91 | global_State *g = G(L); 92 | while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { 93 | GCObject *o = obj2gco(uv); 94 | lua_assert(!isblack(o) && uv->v != &uv->u.value); 95 | L->openupval = uv->next; /* remove from `open' list */ 96 | if (isdead(g, o)) 97 | luaF_freeupval(L, uv); /* free upvalue */ 98 | else { 99 | unlinkupval(uv); /* remove upvalue from 'uvhead' list */ 100 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 101 | uv->v = &uv->u.value; /* now current value lives here */ 102 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ 103 | g->allgc = o; 104 | luaC_checkupvalcolor(g, uv); 105 | } 106 | } 107 | } 108 | 109 | 110 | Proto *luaF_newproto (lua_State *L) { 111 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; 112 | f->k = NULL; 113 | f->sizek = 0; 114 | f->p = NULL; 115 | f->sizep = 0; 116 | f->code = NULL; 117 | f->cache = NULL; 118 | f->sizecode = 0; 119 | f->lineinfo = NULL; 120 | f->sizelineinfo = 0; 121 | f->upvalues = NULL; 122 | f->sizeupvalues = 0; 123 | f->numparams = 0; 124 | f->is_vararg = 0; 125 | f->maxstacksize = 0; 126 | f->locvars = NULL; 127 | f->sizelocvars = 0; 128 | f->linedefined = 0; 129 | f->lastlinedefined = 0; 130 | f->source = NULL; 131 | return f; 132 | } 133 | 134 | 135 | void luaF_freeproto (lua_State *L, Proto *f) { 136 | luaM_freearray(L, f->code, f->sizecode); 137 | luaM_freearray(L, f->p, f->sizep); 138 | luaM_freearray(L, f->k, f->sizek); 139 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 140 | luaM_freearray(L, f->locvars, f->sizelocvars); 141 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 142 | luaM_free(L, f); 143 | } 144 | 145 | 146 | /* 147 | ** Look for n-th local variable at line `line' in function `func'. 148 | ** Returns NULL if not found. 149 | */ 150 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 151 | int i; 152 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 153 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 154 | local_number--; 155 | if (local_number == 0) 156 | return getstr(f->locvars[i].varname); 157 | } 158 | } 159 | return NULL; /* not found */ 160 | } 161 | 162 | -------------------------------------------------------------------------------- /src/lib/lua/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 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); 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); 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_freeupval (lua_State *L, UpVal *uv); 29 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 30 | int pc); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/lib/lua/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 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 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSsweepstring 2 42 | #define GCSsweepudata 3 43 | #define GCSsweep 4 44 | #define GCSpause 5 45 | 46 | 47 | #define issweepphase(g) \ 48 | (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) 49 | 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) 51 | 52 | /* 53 | ** macros to tell when main invariant (white objects cannot point to black 54 | ** ones) must be kept. During a non-generational collection, the sweep 55 | ** phase may break the invariant, as objects turned white may point to 56 | ** still-black objects. The invariant is restored when sweep ends and 57 | ** all objects are white again. During a generational collection, the 58 | ** invariant must be kept all times. 59 | */ 60 | 61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** Outside the collector, the state in generational mode is kept in 66 | ** 'propagate', so 'keepinvariant' is always true. 67 | */ 68 | #define keepinvariantout(g) \ 69 | check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ 70 | g->gcstate <= GCSatomic) 71 | 72 | 73 | /* 74 | ** some useful bit tricks 75 | */ 76 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 77 | #define setbits(x,m) ((x) |= (m)) 78 | #define testbits(x,m) ((x) & (m)) 79 | #define bitmask(b) (1<<(b)) 80 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 81 | #define l_setbit(x,b) setbits(x, bitmask(b)) 82 | #define resetbit(x,b) resetbits(x, bitmask(b)) 83 | #define testbit(x,b) testbits(x, bitmask(b)) 84 | 85 | 86 | /* Layout for bit use in `marked' field: */ 87 | #define WHITE0BIT 0 /* object is white (type 0) */ 88 | #define WHITE1BIT 1 /* object is white (type 1) */ 89 | #define BLACKBIT 2 /* object is black */ 90 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ 91 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ 92 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ 93 | #define OLDBIT 6 /* object is old (only in generational mode) */ 94 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 95 | 96 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 97 | 98 | 99 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) 100 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) 101 | #define isgray(x) /* neither white nor black */ \ 102 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) 103 | 104 | #define isold(x) testbit((x)->gch.marked, OLDBIT) 105 | 106 | /* MOVE OLD rule: whenever an object is moved to the beginning of 107 | a GC list, its old bit must be cleared */ 108 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) 109 | 110 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 111 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 112 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) 113 | 114 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 115 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 116 | 117 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 118 | 119 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 120 | 121 | 122 | #define luaC_condGC(L,c) \ 123 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} 124 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) 125 | 126 | 127 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 128 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } 129 | 130 | #define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 131 | luaC_barrierback_(L,p); } 132 | 133 | #define luaC_objbarrier(L,p,o) \ 134 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 135 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } 136 | 137 | #define luaC_objbarrierback(L,p,o) \ 138 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } 139 | 140 | #define luaC_barrierproto(L,p,c) \ 141 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } 142 | 143 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 144 | LUAI_FUNC void luaC_step (lua_State *L); 145 | LUAI_FUNC void luaC_forcestep (lua_State *L); 146 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 147 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 148 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, 149 | GCObject **list, int offset); 150 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 151 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 152 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); 153 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 154 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); 155 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /src/lib/lua/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | /* 9 | ** If you embed Lua in your program and need to open the standard 10 | ** libraries, call luaL_openlibs in your program. If you need a 11 | ** different set of libraries, copy this file to your project and edit 12 | ** it to suit your needs. 13 | */ 14 | 15 | 16 | #define linit_c 17 | #define LUA_LIB 18 | 19 | #include "lua.h" 20 | 21 | #include "lualib.h" 22 | #include "lauxlib.h" 23 | 24 | 25 | /* 26 | ** these libs are loaded by lua.c and are readily available to any Lua 27 | ** program 28 | */ 29 | static const luaL_Reg loadedlibs[] = { 30 | {"_G", luaopen_base}, 31 | {LUA_LOADLIBNAME, luaopen_package}, 32 | {LUA_COLIBNAME, luaopen_coroutine}, 33 | {LUA_TABLIBNAME, luaopen_table}, 34 | {LUA_IOLIBNAME, luaopen_io}, 35 | {LUA_OSLIBNAME, luaopen_os}, 36 | {LUA_STRLIBNAME, luaopen_string}, 37 | {LUA_BITLIBNAME, luaopen_bit32}, 38 | {LUA_MATHLIBNAME, luaopen_math}, 39 | {LUA_DBLIBNAME, luaopen_debug}, 40 | {NULL, NULL} 41 | }; 42 | 43 | 44 | /* 45 | ** these libs are preloaded and must be required before used 46 | */ 47 | static const luaL_Reg preloadedlibs[] = { 48 | {NULL, NULL} 49 | }; 50 | 51 | 52 | LUALIB_API void luaL_openlibs (lua_State *L) { 53 | const luaL_Reg *lib; 54 | /* call open functions from 'loadedlibs' and set results to global table */ 55 | for (lib = loadedlibs; lib->func; lib++) { 56 | luaL_requiref(L, lib->name, lib->func, 1); 57 | lua_pop(L, 1); /* remove lib */ 58 | } 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ 60 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 61 | for (lib = preloadedlibs; lib->func; lib++) { 62 | lua_pushcfunction(L, lib->func); 63 | lua_setfield(L, -2, lib->name); 64 | } 65 | lua_pop(L, 1); /* remove _PRELOAD table */ 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/lib/lua/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 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 | 17 | 18 | /* 19 | * WARNING: if you change the order of this enumeration, 20 | * grep "ORDER RESERVED" 21 | */ 22 | enum RESERVED { 23 | /* terminal symbols denoted by reserved words */ 24 | TK_AND = FIRST_RESERVED, TK_BREAK, 25 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 26 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 28 | /* other terminal symbols */ 29 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, 30 | TK_NUMBER, TK_NAME, TK_STRING 31 | }; 32 | 33 | /* number of reserved words */ 34 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 35 | 36 | 37 | typedef union { 38 | lua_Number r; 39 | TString *ts; 40 | } SemInfo; /* semantics information */ 41 | 42 | 43 | typedef struct Token { 44 | int token; 45 | SemInfo seminfo; 46 | } Token; 47 | 48 | 49 | /* state of the lexer plus state of the parser when shared by all 50 | functions */ 51 | typedef struct LexState { 52 | int current; /* current character (charint) */ 53 | int linenumber; /* input line counter */ 54 | int lastline; /* line of last token `consumed' */ 55 | Token t; /* current token */ 56 | Token lookahead; /* look ahead token */ 57 | struct FuncState *fs; /* current function (parser) */ 58 | struct lua_State *L; 59 | ZIO *z; /* input stream */ 60 | Mbuffer *buff; /* buffer for tokens */ 61 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 62 | TString *source; /* current source name */ 63 | TString *envn; /* environment variable name */ 64 | char decpoint; /* locale decimal point */ 65 | } LexState; 66 | 67 | 68 | LUAI_FUNC void luaX_init (lua_State *L); 69 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 70 | TString *source, int firstchar); 71 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 72 | LUAI_FUNC void luaX_next (LexState *ls); 73 | LUAI_FUNC int luaX_lookahead (LexState *ls); 74 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 75 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/lib/lua/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 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 unsigned LUA_INT32 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 | #define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) 35 | 36 | 37 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 38 | 39 | /* 40 | ** conversion of pointer to integer 41 | ** this is for hashing only; there is no problem if the integer 42 | ** cannot hold the whole pointer value 43 | */ 44 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) 45 | 46 | 47 | 48 | /* type to ensure maximum alignment */ 49 | #if !defined(LUAI_USER_ALIGNMENT_T) 50 | #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } 51 | #endif 52 | 53 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 54 | 55 | 56 | /* result of a `usual argument conversion' over lua_Number */ 57 | typedef LUAI_UACNUMBER l_uacNumber; 58 | 59 | 60 | /* internal assertions for in-house debugging */ 61 | #if defined(lua_assert) 62 | #define check_exp(c,e) (lua_assert(c), (e)) 63 | /* to avoid problems with conditions too long */ 64 | #define lua_longassert(c) { if (!(c)) lua_assert(0); } 65 | #else 66 | #define lua_assert(c) ((void)0) 67 | #define check_exp(c,e) (e) 68 | #define lua_longassert(c) ((void)0) 69 | #endif 70 | 71 | /* 72 | ** assertion for checking API calls 73 | */ 74 | #if !defined(luai_apicheck) 75 | 76 | #if defined(LUA_USE_APICHECK) 77 | #include 78 | #define luai_apicheck(L,e) assert(e) 79 | #else 80 | #define luai_apicheck(L,e) lua_assert(e) 81 | #endif 82 | 83 | #endif 84 | 85 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) 86 | 87 | 88 | #if !defined(UNUSED) 89 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 90 | #endif 91 | 92 | 93 | #define cast(t, exp) ((t)(exp)) 94 | 95 | #define cast_byte(i) cast(lu_byte, (i)) 96 | #define cast_num(i) cast(lua_Number, (i)) 97 | #define cast_int(i) cast(int, (i)) 98 | #define cast_uchar(i) cast(unsigned char, (i)) 99 | 100 | 101 | /* 102 | ** non-return type 103 | */ 104 | #if defined(__GNUC__) 105 | #define l_noret void __attribute__((noreturn)) 106 | #elif defined(_MSC_VER) 107 | #define l_noret void __declspec(noreturn) 108 | #else 109 | #define l_noret void 110 | #endif 111 | 112 | 113 | 114 | /* 115 | ** maximum depth for nested C calls and syntactical nested non-terminals 116 | ** in a program. (Value must fit in an unsigned short int.) 117 | */ 118 | #if !defined(LUAI_MAXCCALLS) 119 | #define LUAI_MAXCCALLS 200 120 | #endif 121 | 122 | /* 123 | ** maximum number of upvalues in a closure (both C and Lua). (Value 124 | ** must fit in an unsigned char.) 125 | */ 126 | #define MAXUPVAL UCHAR_MAX 127 | 128 | 129 | /* 130 | ** type for virtual-machine instructions 131 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 132 | */ 133 | typedef lu_int32 Instruction; 134 | 135 | 136 | 137 | /* maximum stack for a Lua function */ 138 | #define MAXSTACK 250 139 | 140 | 141 | 142 | /* minimum size for the string table (must be power of 2) */ 143 | #if !defined(MINSTRTABSIZE) 144 | #define MINSTRTABSIZE 32 145 | #endif 146 | 147 | 148 | /* minimum size for string buffer */ 149 | #if !defined(LUA_MINBUFFER) 150 | #define LUA_MINBUFFER 32 151 | #endif 152 | 153 | 154 | #if !defined(lua_lock) 155 | #define lua_lock(L) ((void) 0) 156 | #define lua_unlock(L) ((void) 0) 157 | #endif 158 | 159 | #if !defined(luai_threadyield) 160 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 161 | #endif 162 | 163 | 164 | /* 165 | ** these macros allow user-specific actions on threads when you defined 166 | ** LUAI_EXTRASPACE and need to do something extra when a thread is 167 | ** created/deleted/resumed/yielded. 168 | */ 169 | #if !defined(luai_userstateopen) 170 | #define luai_userstateopen(L) ((void)L) 171 | #endif 172 | 173 | #if !defined(luai_userstateclose) 174 | #define luai_userstateclose(L) ((void)L) 175 | #endif 176 | 177 | #if !defined(luai_userstatethread) 178 | #define luai_userstatethread(L,L1) ((void)L) 179 | #endif 180 | 181 | #if !defined(luai_userstatefree) 182 | #define luai_userstatefree(L,L1) ((void)L) 183 | #endif 184 | 185 | #if !defined(luai_userstateresume) 186 | #define luai_userstateresume(L,n) ((void)L) 187 | #endif 188 | 189 | #if !defined(luai_userstateyield) 190 | #define luai_userstateyield(L,n) ((void)L) 191 | #endif 192 | 193 | /* 194 | ** lua_number2int is a macro to convert lua_Number to int. 195 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. 196 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. 197 | ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. 198 | ** luai_hashnum is a macro to hash a lua_Number value into an integer. 199 | ** The hash must be deterministic and give reasonable values for 200 | ** both small and large values (outside the range of integers). 201 | */ 202 | 203 | #if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ 204 | /* trick with Microsoft assembler for X86 */ 205 | 206 | #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} 207 | #define lua_number2integer(i,n) lua_number2int(i, n) 208 | #define lua_number2unsigned(i,n) \ 209 | {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} 210 | 211 | 212 | #elif defined(LUA_IEEE754TRICK) /* }{ */ 213 | /* the next trick should work on any machine using IEEE754 with 214 | a 32-bit int type */ 215 | 216 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; 217 | 218 | #if !defined(LUA_IEEEENDIAN) /* { */ 219 | #define LUAI_EXTRAIEEE \ 220 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; 221 | #define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) 222 | #else 223 | #define LUA_IEEEENDIANLOC LUA_IEEEENDIAN 224 | #define LUAI_EXTRAIEEE /* empty */ 225 | #endif /* } */ 226 | 227 | #define lua_number2int32(i,n,t) \ 228 | { LUAI_EXTRAIEEE \ 229 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ 230 | (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } 231 | 232 | #define luai_hashnum(i,n) \ 233 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ 234 | (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ 235 | 236 | #define lua_number2int(i,n) lua_number2int32(i, n, int) 237 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) 238 | 239 | /* the trick can be expanded to lua_Integer when it is a 32-bit value */ 240 | #if defined(LUA_IEEELL) 241 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) 242 | #endif 243 | 244 | #endif /* } */ 245 | 246 | 247 | /* the following definitions always work, but may be slow */ 248 | 249 | #if !defined(lua_number2int) 250 | #define lua_number2int(i,n) ((i)=(int)(n)) 251 | #endif 252 | 253 | #if !defined(lua_number2integer) 254 | #define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) 255 | #endif 256 | 257 | #if !defined(lua_number2unsigned) /* { */ 258 | /* the following definition assures proper modulo behavior */ 259 | #if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) 260 | #include 261 | #define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) 262 | #define lua_number2unsigned(i,n) \ 263 | ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) 264 | #else 265 | #define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) 266 | #endif 267 | #endif /* } */ 268 | 269 | 270 | #if !defined(lua_unsigned2number) 271 | /* on several machines, coercion from unsigned to double is slow, 272 | so it may be worth to avoid */ 273 | #define lua_unsigned2number(u) \ 274 | (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) 275 | #endif 276 | 277 | 278 | 279 | #if defined(ltable_c) && !defined(luai_hashnum) 280 | 281 | #include 282 | #include 283 | 284 | #define luai_hashnum(i,n) { int e; \ 285 | n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ 286 | lua_number2int(i, n); i += e; } 287 | 288 | #endif 289 | 290 | 291 | 292 | /* 293 | ** macro to control inclusion of some hard tests on stack reallocation 294 | */ 295 | #if !defined(HARDSTACKTESTS) 296 | #define condmovestack(L) ((void)0) 297 | #else 298 | /* realloc stack keeping its size */ 299 | #define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) 300 | #endif 301 | 302 | #if !defined(HARDMEMTESTS) 303 | #define condchangemem(L) condmovestack(L) 304 | #else 305 | #define condchangemem(L) \ 306 | ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) 307 | #endif 308 | 309 | #endif 310 | -------------------------------------------------------------------------------- /src/lib/lua/lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 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 ((lua_Number)(3.1415926535897932384626433832795)) 22 | #define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) 23 | 24 | 25 | 26 | static int math_abs (lua_State *L) { 27 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); 28 | return 1; 29 | } 30 | 31 | static int math_sin (lua_State *L) { 32 | lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); 33 | return 1; 34 | } 35 | 36 | static int math_sinh (lua_State *L) { 37 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); 38 | return 1; 39 | } 40 | 41 | static int math_cos (lua_State *L) { 42 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); 43 | return 1; 44 | } 45 | 46 | static int math_cosh (lua_State *L) { 47 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); 48 | return 1; 49 | } 50 | 51 | static int math_tan (lua_State *L) { 52 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); 53 | return 1; 54 | } 55 | 56 | static int math_tanh (lua_State *L) { 57 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); 58 | return 1; 59 | } 60 | 61 | static int math_asin (lua_State *L) { 62 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); 63 | return 1; 64 | } 65 | 66 | static int math_acos (lua_State *L) { 67 | lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); 68 | return 1; 69 | } 70 | 71 | static int math_atan (lua_State *L) { 72 | lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); 73 | return 1; 74 | } 75 | 76 | static int math_atan2 (lua_State *L) { 77 | lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), 78 | luaL_checknumber(L, 2))); 79 | return 1; 80 | } 81 | 82 | static int math_ceil (lua_State *L) { 83 | lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); 84 | return 1; 85 | } 86 | 87 | static int math_floor (lua_State *L) { 88 | lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); 89 | return 1; 90 | } 91 | 92 | static int math_fmod (lua_State *L) { 93 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 94 | luaL_checknumber(L, 2))); 95 | return 1; 96 | } 97 | 98 | static int math_modf (lua_State *L) { 99 | lua_Number ip; 100 | lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); 101 | lua_pushnumber(L, ip); 102 | lua_pushnumber(L, fp); 103 | return 2; 104 | } 105 | 106 | static int math_sqrt (lua_State *L) { 107 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); 108 | return 1; 109 | } 110 | 111 | static int math_pow (lua_State *L) { 112 | lua_Number x = luaL_checknumber(L, 1); 113 | lua_Number y = luaL_checknumber(L, 2); 114 | lua_pushnumber(L, l_mathop(pow)(x, y)); 115 | return 1; 116 | } 117 | 118 | static int math_log (lua_State *L) { 119 | lua_Number x = luaL_checknumber(L, 1); 120 | lua_Number res; 121 | if (lua_isnoneornil(L, 2)) 122 | res = l_mathop(log)(x); 123 | else { 124 | lua_Number base = luaL_checknumber(L, 2); 125 | if (base == (lua_Number)10.0) res = l_mathop(log10)(x); 126 | else res = l_mathop(log)(x)/l_mathop(log)(base); 127 | } 128 | lua_pushnumber(L, res); 129 | return 1; 130 | } 131 | 132 | #if defined(LUA_COMPAT_LOG10) 133 | static int math_log10 (lua_State *L) { 134 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); 135 | return 1; 136 | } 137 | #endif 138 | 139 | static int math_exp (lua_State *L) { 140 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); 141 | return 1; 142 | } 143 | 144 | static int math_deg (lua_State *L) { 145 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 146 | return 1; 147 | } 148 | 149 | static int math_rad (lua_State *L) { 150 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 151 | return 1; 152 | } 153 | 154 | static int math_frexp (lua_State *L) { 155 | int e; 156 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); 157 | lua_pushinteger(L, e); 158 | return 2; 159 | } 160 | 161 | static int math_ldexp (lua_State *L) { 162 | lua_Number x = luaL_checknumber(L, 1); 163 | int ep = luaL_checkint(L, 2); 164 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); 165 | return 1; 166 | } 167 | 168 | 169 | 170 | static int math_min (lua_State *L) { 171 | int n = lua_gettop(L); /* number of arguments */ 172 | lua_Number dmin = luaL_checknumber(L, 1); 173 | int i; 174 | for (i=2; i<=n; i++) { 175 | lua_Number d = luaL_checknumber(L, i); 176 | if (d < dmin) 177 | dmin = d; 178 | } 179 | lua_pushnumber(L, dmin); 180 | return 1; 181 | } 182 | 183 | 184 | static int math_max (lua_State *L) { 185 | int n = lua_gettop(L); /* number of arguments */ 186 | lua_Number dmax = luaL_checknumber(L, 1); 187 | int i; 188 | for (i=2; i<=n; i++) { 189 | lua_Number d = luaL_checknumber(L, i); 190 | if (d > dmax) 191 | dmax = d; 192 | } 193 | lua_pushnumber(L, dmax); 194 | return 1; 195 | } 196 | 197 | 198 | static int math_random (lua_State *L) { 199 | /* the `%' avoids the (rare) case of r==1, and is needed also because on 200 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ 201 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 202 | switch (lua_gettop(L)) { /* check number of arguments */ 203 | case 0: { /* no arguments */ 204 | lua_pushnumber(L, r); /* Number between 0 and 1 */ 205 | break; 206 | } 207 | case 1: { /* only upper limit */ 208 | lua_Number u = luaL_checknumber(L, 1); 209 | luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); 210 | lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ 211 | break; 212 | } 213 | case 2: { /* lower and upper limits */ 214 | lua_Number l = luaL_checknumber(L, 1); 215 | lua_Number u = luaL_checknumber(L, 2); 216 | luaL_argcheck(L, l <= u, 2, "interval is empty"); 217 | lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ 218 | break; 219 | } 220 | default: return luaL_error(L, "wrong number of arguments"); 221 | } 222 | return 1; 223 | } 224 | 225 | 226 | static int math_randomseed (lua_State *L) { 227 | srand(luaL_checkunsigned(L, 1)); 228 | (void)rand(); /* discard first value to avoid undesirable correlations */ 229 | return 0; 230 | } 231 | 232 | 233 | static const luaL_Reg mathlib[] = { 234 | {"abs", math_abs}, 235 | {"acos", math_acos}, 236 | {"asin", math_asin}, 237 | {"atan2", math_atan2}, 238 | {"atan", math_atan}, 239 | {"ceil", math_ceil}, 240 | {"cosh", math_cosh}, 241 | {"cos", math_cos}, 242 | {"deg", math_deg}, 243 | {"exp", math_exp}, 244 | {"floor", math_floor}, 245 | {"fmod", math_fmod}, 246 | {"frexp", math_frexp}, 247 | {"ldexp", math_ldexp}, 248 | #if defined(LUA_COMPAT_LOG10) 249 | {"log10", math_log10}, 250 | #endif 251 | {"log", math_log}, 252 | {"max", math_max}, 253 | {"min", math_min}, 254 | {"modf", math_modf}, 255 | {"pow", math_pow}, 256 | {"rad", math_rad}, 257 | {"random", math_random}, 258 | {"randomseed", math_randomseed}, 259 | {"sinh", math_sinh}, 260 | {"sin", math_sin}, 261 | {"sqrt", math_sqrt}, 262 | {"tanh", math_tanh}, 263 | {"tan", math_tan}, 264 | {NULL, NULL} 265 | }; 266 | 267 | 268 | /* 269 | ** Open math library 270 | */ 271 | LUAMOD_API int luaopen_math (lua_State *L) { 272 | luaL_newlib(L, mathlib); 273 | lua_pushnumber(L, PI); 274 | lua_setfield(L, -2, "pi"); 275 | lua_pushnumber(L, HUGE_VAL); 276 | lua_setfield(L, -2, "huge"); 277 | return 1; 278 | } 279 | 280 | -------------------------------------------------------------------------------- /src/lib/lua/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 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 "lgc.h" 18 | #include "lmem.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | 22 | 23 | 24 | /* 25 | ** About the realloc function: 26 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 27 | ** (`osize' is the old size, `nsize' is the new size) 28 | ** 29 | ** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no 30 | ** matter '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 *what) { 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, "too many %s (limit is %d)", what, limit); 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 | l_noret luaM_toobig (lua_State *L) { 67 | luaG_runerror(L, "memory allocation error: block too big"); 68 | } 69 | 70 | 71 | 72 | /* 73 | ** generic allocation routine. 74 | */ 75 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 76 | void *newblock; 77 | global_State *g = G(L); 78 | size_t realosize = (block) ? osize : 0; 79 | lua_assert((realosize == 0) == (block == NULL)); 80 | #if defined(HARDMEMTESTS) 81 | if (nsize > realosize && g->gcrunning) 82 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 83 | #endif 84 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 85 | if (newblock == NULL && nsize > 0) { 86 | api_check(L, nsize > realosize, 87 | "realloc cannot fail when shrinking a block"); 88 | if (g->gcrunning) { 89 | luaC_fullgc(L, 1); /* try to free some memory... */ 90 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 91 | } 92 | if (newblock == NULL) 93 | luaD_throw(L, LUA_ERRMEM); 94 | } 95 | lua_assert((nsize == 0) == (newblock == NULL)); 96 | g->GCdebt = (g->GCdebt + nsize) - realosize; 97 | return newblock; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /src/lib/lua/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 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 | 17 | /* 18 | ** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is 19 | ** always constant. 20 | ** The macro is somewhat complex to avoid warnings: 21 | ** +1 avoids warnings of "comparison has constant result"; 22 | ** cast to 'void' avoids warnings of "value unused". 23 | */ 24 | #define luaM_reallocv(L,b,on,n,e) \ 25 | (cast(void, \ 26 | (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ 27 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 28 | 29 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 30 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 31 | #define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) 32 | 33 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 34 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 35 | #define luaM_newvector(L,n,t) \ 36 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 37 | 38 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 39 | 40 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 41 | if ((nelems)+1 > (size)) \ 42 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 43 | 44 | #define luaM_reallocvector(L, v,oldn,n,t) \ 45 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 46 | 47 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 48 | 49 | /* not to be called directly */ 50 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 51 | size_t size); 52 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 53 | size_t size_elem, int limit, 54 | const char *what); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /src/lib/lua/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define lopcodes_c 9 | #define LUA_CORE 10 | 11 | 12 | #include "lopcodes.h" 13 | 14 | 15 | /* ORDER OP */ 16 | 17 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 18 | "MOVE", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADBOOL", 22 | "LOADNIL", 23 | "GETUPVAL", 24 | "GETTABUP", 25 | "GETTABLE", 26 | "SETTABUP", 27 | "SETUPVAL", 28 | "SETTABLE", 29 | "NEWTABLE", 30 | "SELF", 31 | "ADD", 32 | "SUB", 33 | "MUL", 34 | "DIV", 35 | "MOD", 36 | "POW", 37 | "UNM", 38 | "NOT", 39 | "LEN", 40 | "CONCAT", 41 | "JMP", 42 | "EQ", 43 | "LT", 44 | "LE", 45 | "TEST", 46 | "TESTSET", 47 | "CALL", 48 | "TAILCALL", 49 | "RETURN", 50 | "FORLOOP", 51 | "FORPREP", 52 | "TFORCALL", 53 | "TFORLOOP", 54 | "SETLIST", 55 | "CLOSURE", 56 | "VARARG", 57 | "EXTRAARG", 58 | NULL 59 | }; 60 | 61 | 62 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 63 | 64 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 65 | /* T A B C mode opcode */ 66 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 67 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 68 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 69 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 70 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 71 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 72 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 73 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 75 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 76 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 77 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 78 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 81 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 82 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 83 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 84 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 85 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 86 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 87 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 88 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 89 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 90 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 91 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 92 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 93 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 94 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 95 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 96 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 97 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 98 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 99 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 100 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 102 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 103 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 104 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 105 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 106 | }; 107 | 108 | -------------------------------------------------------------------------------- /src/lib/lua/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 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 | VNONRELOC, /* info = result register */ 27 | VLOCAL, /* info = local register */ 28 | VUPVAL, /* info = index of upvalue in 'upvalues' */ 29 | VINDEXED, /* t = table register/upvalue; idx = index R/K */ 30 | VJMP, /* info = instruction pc */ 31 | VRELOCABLE, /* info = instruction pc */ 32 | VCALL, /* info = instruction pc */ 33 | VVARARG /* info = instruction pc */ 34 | } expkind; 35 | 36 | 37 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 38 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 39 | 40 | typedef struct expdesc { 41 | expkind k; 42 | union { 43 | struct { /* for indexed variables (VINDEXED) */ 44 | short idx; /* index (R/K) */ 45 | lu_byte t; /* table (register or upvalue) */ 46 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 47 | } ind; 48 | int info; /* for generic use */ 49 | lua_Number nval; /* for VKNUM */ 50 | } u; 51 | int t; /* patch list of `exit when true' */ 52 | int f; /* patch list of `exit when false' */ 53 | } expdesc; 54 | 55 | 56 | /* description of active local variable */ 57 | typedef struct Vardesc { 58 | short idx; /* variable index in stack */ 59 | } Vardesc; 60 | 61 | 62 | /* description of pending goto statements and label statements */ 63 | typedef struct Labeldesc { 64 | TString *name; /* label identifier */ 65 | int pc; /* position in code */ 66 | int line; /* line where it appeared */ 67 | lu_byte nactvar; /* local level where it appears in current block */ 68 | } Labeldesc; 69 | 70 | 71 | /* list of labels or gotos */ 72 | typedef struct Labellist { 73 | Labeldesc *arr; /* array */ 74 | int n; /* number of entries in use */ 75 | int size; /* array size */ 76 | } Labellist; 77 | 78 | 79 | /* dynamic structures used by the parser */ 80 | typedef struct Dyndata { 81 | struct { /* list of active local variables */ 82 | Vardesc *arr; 83 | int n; 84 | int size; 85 | } actvar; 86 | Labellist gt; /* list of pending gotos */ 87 | Labellist label; /* list of active labels */ 88 | } Dyndata; 89 | 90 | 91 | /* control of blocks */ 92 | struct BlockCnt; /* defined in lparser.c */ 93 | 94 | 95 | /* state needed to generate code for a given function */ 96 | typedef struct FuncState { 97 | Proto *f; /* current function header */ 98 | Table *h; /* table to find (and reuse) elements in `k' */ 99 | struct FuncState *prev; /* enclosing function */ 100 | struct LexState *ls; /* lexical state */ 101 | struct BlockCnt *bl; /* chain of current blocks */ 102 | int pc; /* next position to code (equivalent to `ncode') */ 103 | int lasttarget; /* 'label' of last 'jump label' */ 104 | int jpc; /* list of pending jumps to `pc' */ 105 | int nk; /* number of elements in `k' */ 106 | int np; /* number of elements in `p' */ 107 | int firstlocal; /* index of first local var (in Dyndata array) */ 108 | short nlocvars; /* number of elements in 'f->locvars' */ 109 | lu_byte nactvar; /* number of active local variables */ 110 | lu_byte nups; /* number of upvalues */ 111 | lu_byte freereg; /* first free register */ 112 | } FuncState; 113 | 114 | 115 | LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 116 | Dyndata *dyd, const char *name, int firstchar); 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /src/lib/lua/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 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 | 19 | ** Some notes about garbage-collected objects: All objects in Lua must 20 | ** be kept somehow accessible until being freed. 21 | ** 22 | ** Lua keeps most objects linked in list g->allgc. The link uses field 23 | ** 'next' of the CommonHeader. 24 | ** 25 | ** Strings are kept in several lists headed by the array g->strt.hash. 26 | ** 27 | ** Open upvalues are not subject to independent garbage collection. They 28 | ** are collected together with their respective threads. Lua keeps a 29 | ** double-linked list with all open upvalues (g->uvhead) so that it can 30 | ** mark objects referred by them. (They are always gray, so they must 31 | ** be remarked in the atomic step. Usually their contents would be marked 32 | ** when traversing the respective threads, but the thread may already be 33 | ** dead, while the upvalue is still accessible through closures.) 34 | ** 35 | ** Objects with finalizers are kept in the list g->finobj. 36 | ** 37 | ** The list g->tobefnz links all objects being finalized. 38 | 39 | */ 40 | 41 | 42 | struct lua_longjmp; /* defined in ldo.c */ 43 | 44 | 45 | 46 | /* extra stack space to handle TM calls and some other extras */ 47 | #define EXTRA_STACK 5 48 | 49 | 50 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 51 | 52 | 53 | /* kinds of Garbage Collection */ 54 | #define KGC_NORMAL 0 55 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ 56 | #define KGC_GEN 2 /* generational collection */ 57 | 58 | 59 | typedef struct stringtable { 60 | GCObject **hash; 61 | lu_int32 nuse; /* number of elements */ 62 | int size; 63 | } stringtable; 64 | 65 | 66 | /* 67 | ** information about a call 68 | */ 69 | typedef struct CallInfo { 70 | StkId func; /* function index in the stack */ 71 | StkId top; /* top for this function */ 72 | struct CallInfo *previous, *next; /* dynamic call link */ 73 | short nresults; /* expected number of results from this function */ 74 | lu_byte callstatus; 75 | ptrdiff_t extra; 76 | union { 77 | struct { /* only for Lua functions */ 78 | StkId base; /* base for this function */ 79 | const Instruction *savedpc; 80 | } l; 81 | struct { /* only for C functions */ 82 | int ctx; /* context info. in case of yields */ 83 | lua_CFunction k; /* continuation in case of yields */ 84 | ptrdiff_t old_errfunc; 85 | lu_byte old_allowhook; 86 | lu_byte status; 87 | } c; 88 | } u; 89 | } CallInfo; 90 | 91 | 92 | /* 93 | ** Bits in CallInfo status 94 | */ 95 | #define CIST_LUA (1<<0) /* call is running a Lua function */ 96 | #define CIST_HOOKED (1<<1) /* call is running a debug hook */ 97 | #define CIST_REENTRY (1<<2) /* call is running on same invocation of 98 | luaV_execute of previous call */ 99 | #define CIST_YIELDED (1<<3) /* call reentered after suspension */ 100 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ 101 | #define CIST_STAT (1<<5) /* call has an error status (pcall) */ 102 | #define CIST_TAIL (1<<6) /* call was tail called */ 103 | #define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ 104 | 105 | 106 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) 107 | 108 | 109 | /* 110 | ** `global state', shared by all threads of this state 111 | */ 112 | typedef struct global_State { 113 | lua_Alloc frealloc; /* function to reallocate memory */ 114 | void *ud; /* auxiliary data to `frealloc' */ 115 | lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 116 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 117 | lu_mem GCmemtrav; /* memory traversed by the GC */ 118 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 119 | stringtable strt; /* hash table for strings */ 120 | TValue l_registry; 121 | unsigned int seed; /* randomized seed for hashes */ 122 | lu_byte currentwhite; 123 | lu_byte gcstate; /* state of garbage collector */ 124 | lu_byte gckind; /* kind of GC running */ 125 | lu_byte gcrunning; /* true if GC is running */ 126 | int sweepstrgc; /* position of sweep in `strt' */ 127 | GCObject *allgc; /* list of all collectable objects */ 128 | GCObject *finobj; /* list of collectable objects with finalizers */ 129 | GCObject **sweepgc; /* current position of sweep in list 'allgc' */ 130 | GCObject **sweepfin; /* current position of sweep in list 'finobj' */ 131 | GCObject *gray; /* list of gray objects */ 132 | GCObject *grayagain; /* list of objects to be traversed atomically */ 133 | GCObject *weak; /* list of tables with weak values */ 134 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ 135 | GCObject *allweak; /* list of all-weak tables */ 136 | GCObject *tobefnz; /* list of userdata to be GC */ 137 | UpVal uvhead; /* head of double-linked list of all open upvalues */ 138 | Mbuffer buff; /* temporary buffer for string concatenation */ 139 | int gcpause; /* size of pause between successive GCs */ 140 | int gcmajorinc; /* pause between major collections (only in gen. mode) */ 141 | int gcstepmul; /* GC `granularity' */ 142 | lua_CFunction panic; /* to be called in unprotected errors */ 143 | struct lua_State *mainthread; 144 | const lua_Number *version; /* pointer to version number */ 145 | TString *memerrmsg; /* memory-error message */ 146 | TString *tmname[TM_N]; /* array with tag-method names */ 147 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ 148 | } global_State; 149 | 150 | 151 | /* 152 | ** `per thread' state 153 | */ 154 | struct lua_State { 155 | CommonHeader; 156 | lu_byte status; 157 | StkId top; /* first free slot in the stack */ 158 | global_State *l_G; 159 | CallInfo *ci; /* call info for current function */ 160 | const Instruction *oldpc; /* last pc traced */ 161 | StkId stack_last; /* last free slot in the stack */ 162 | StkId stack; /* stack base */ 163 | int stacksize; 164 | unsigned short nny; /* number of non-yieldable calls in stack */ 165 | unsigned short nCcalls; /* number of nested C calls */ 166 | lu_byte hookmask; 167 | lu_byte allowhook; 168 | int basehookcount; 169 | int hookcount; 170 | lua_Hook hook; 171 | GCObject *openupval; /* list of open upvalues in this stack */ 172 | GCObject *gclist; 173 | struct lua_longjmp *errorJmp; /* current error recover point */ 174 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 175 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ 176 | }; 177 | 178 | 179 | #define G(L) (L->l_G) 180 | 181 | 182 | /* 183 | ** Union of all collectable objects 184 | */ 185 | union GCObject { 186 | GCheader gch; /* common header */ 187 | union TString ts; 188 | union Udata u; 189 | union Closure cl; 190 | struct Table h; 191 | struct Proto p; 192 | struct UpVal uv; 193 | struct lua_State th; /* thread */ 194 | }; 195 | 196 | 197 | #define gch(o) (&(o)->gch) 198 | 199 | /* macros to convert a GCObject into a specific value */ 200 | #define rawgco2ts(o) \ 201 | check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) 202 | #define gco2ts(o) (&rawgco2ts(o)->tsv) 203 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 204 | #define gco2u(o) (&rawgco2u(o)->uv) 205 | #define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) 206 | #define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) 207 | #define gco2cl(o) \ 208 | check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) 209 | #define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 210 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 211 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 212 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 213 | 214 | /* macro to convert any Lua object into a GCObject */ 215 | #define obj2gco(v) (cast(GCObject *, (v))) 216 | 217 | 218 | /* actual number of total bytes allocated */ 219 | #define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) 220 | 221 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 222 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 223 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 224 | LUAI_FUNC void luaE_freeCI (lua_State *L); 225 | 226 | 227 | #endif 228 | 229 | -------------------------------------------------------------------------------- /src/lib/lua/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 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 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to 23 | ** compute its hash 24 | */ 25 | #if !defined(LUAI_HASHLIMIT) 26 | #define LUAI_HASHLIMIT 5 27 | #endif 28 | 29 | 30 | /* 31 | ** equality for long strings 32 | */ 33 | int luaS_eqlngstr (TString *a, TString *b) { 34 | size_t len = a->tsv.len; 35 | lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); 36 | return (a == b) || /* same instance or... */ 37 | ((len == b->tsv.len) && /* equal length and ... */ 38 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 39 | } 40 | 41 | 42 | /* 43 | ** equality for strings 44 | */ 45 | int luaS_eqstr (TString *a, TString *b) { 46 | return (a->tsv.tt == b->tsv.tt) && 47 | (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); 48 | } 49 | 50 | 51 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 52 | unsigned int h = seed ^ cast(unsigned int, l); 53 | size_t l1; 54 | size_t step = (l >> LUAI_HASHLIMIT) + 1; 55 | for (l1 = l; l1 >= step; l1 -= step) 56 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); 57 | return h; 58 | } 59 | 60 | 61 | /* 62 | ** resizes the string table 63 | */ 64 | void luaS_resize (lua_State *L, int newsize) { 65 | int i; 66 | stringtable *tb = &G(L)->strt; 67 | /* cannot resize while GC is traversing strings */ 68 | luaC_runtilstate(L, ~bitmask(GCSsweepstring)); 69 | if (newsize > tb->size) { 70 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); 71 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; 72 | } 73 | /* rehash */ 74 | for (i=0; isize; i++) { 75 | GCObject *p = tb->hash[i]; 76 | tb->hash[i] = NULL; 77 | while (p) { /* for each node in the list */ 78 | GCObject *next = gch(p)->next; /* save next */ 79 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ 80 | gch(p)->next = tb->hash[h]; /* chain it */ 81 | tb->hash[h] = p; 82 | resetoldbit(p); /* see MOVE OLD rule */ 83 | p = next; 84 | } 85 | } 86 | if (newsize < tb->size) { 87 | /* shrinking slice must be empty */ 88 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); 89 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); 90 | } 91 | tb->size = newsize; 92 | } 93 | 94 | 95 | /* 96 | ** creates a new string object 97 | */ 98 | static TString *createstrobj (lua_State *L, const char *str, size_t l, 99 | int tag, unsigned int h, GCObject **list) { 100 | TString *ts; 101 | size_t totalsize; /* total size of TString object */ 102 | totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); 103 | ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; 104 | ts->tsv.len = l; 105 | ts->tsv.hash = h; 106 | ts->tsv.extra = 0; 107 | memcpy(ts+1, str, l*sizeof(char)); 108 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 109 | return ts; 110 | } 111 | 112 | 113 | /* 114 | ** creates a new short string, inserting it into string table 115 | */ 116 | static TString *newshrstr (lua_State *L, const char *str, size_t l, 117 | unsigned int h) { 118 | GCObject **list; /* (pointer to) list where it will be inserted */ 119 | stringtable *tb = &G(L)->strt; 120 | TString *s; 121 | if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) 122 | luaS_resize(L, tb->size*2); /* too crowded */ 123 | list = &tb->hash[lmod(h, tb->size)]; 124 | s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); 125 | tb->nuse++; 126 | return s; 127 | } 128 | 129 | 130 | /* 131 | ** checks whether short string exists and reuses it or creates a new one 132 | */ 133 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 134 | GCObject *o; 135 | global_State *g = G(L); 136 | unsigned int h = luaS_hash(str, l, g->seed); 137 | for (o = g->strt.hash[lmod(h, g->strt.size)]; 138 | o != NULL; 139 | o = gch(o)->next) { 140 | TString *ts = rawgco2ts(o); 141 | if (h == ts->tsv.hash && 142 | l == ts->tsv.len && 143 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 144 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ 145 | changewhite(o); /* resurrect it */ 146 | return ts; 147 | } 148 | } 149 | return newshrstr(L, str, l, h); /* not found; create a new string */ 150 | } 151 | 152 | 153 | /* 154 | ** new string (with explicit length) 155 | */ 156 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 157 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 158 | return internshrstr(L, str, l); 159 | else { 160 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 161 | luaM_toobig(L); 162 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); 163 | } 164 | } 165 | 166 | 167 | /* 168 | ** new zero-terminated string 169 | */ 170 | TString *luaS_new (lua_State *L, const char *str) { 171 | return luaS_newlstr(L, str, strlen(str)); 172 | } 173 | 174 | 175 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { 176 | Udata *u; 177 | if (s > MAX_SIZET - sizeof(Udata)) 178 | luaM_toobig(L); 179 | u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; 180 | u->uv.len = s; 181 | u->uv.metatable = NULL; 182 | u->uv.env = e; 183 | return u; 184 | } 185 | 186 | -------------------------------------------------------------------------------- /src/lib/lua/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 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 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 16 | 17 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) 18 | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 20 | (sizeof(s)/sizeof(char))-1)) 21 | 22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 23 | 24 | 25 | /* 26 | ** test whether a string is a reserved word 27 | */ 28 | #define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) 29 | 30 | 31 | /* 32 | ** equality for short strings, which are always internalized 33 | */ 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) 35 | 36 | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 43 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/lib/lua/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 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.tvk) 15 | #define gval(n) (&(n)->i_val) 16 | #define gnext(n) ((n)->i_key.nk.next) 17 | 18 | #define invalidateTMcache(t) ((t)->flags = 0) 19 | 20 | /* returns the key, given the value of a table entry */ 21 | #define keyfromval(v) \ 22 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 23 | 24 | 25 | LUAI_FUNC const TValue *luaH_getint (Table *t, int key); 26 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); 27 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 28 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 29 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 30 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 31 | LUAI_FUNC Table *luaH_new (lua_State *L); 32 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); 33 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 34 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 35 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 36 | LUAI_FUNC int luaH_getn (Table *t); 37 | 38 | 39 | #if defined(LUA_DEBUG) 40 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 41 | LUAI_FUNC int luaH_isdummy (Node *n); 42 | #endif 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/lib/lua/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.14.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 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 | static const char udatatypename[] = "userdata"; 23 | 24 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 25 | "no value", 26 | "nil", "boolean", udatatypename, "number", 27 | "string", "table", "function", udatatypename, "thread", 28 | "proto", "upval" /* these last two cases are used for tests only */ 29 | }; 30 | 31 | 32 | void luaT_init (lua_State *L) { 33 | static const char *const luaT_eventname[] = { /* ORDER TM */ 34 | "__index", "__newindex", 35 | "__gc", "__mode", "__len", "__eq", 36 | "__add", "__sub", "__mul", "__div", "__mod", 37 | "__pow", "__unm", "__lt", "__le", 38 | "__concat", "__call" 39 | }; 40 | int i; 41 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 43 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ 44 | } 45 | } 46 | 47 | 48 | /* 49 | ** function to be used with macro "fasttm": optimized for absence of 50 | ** tag methods 51 | */ 52 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 53 | const TValue *tm = luaH_getstr(events, ename); 54 | lua_assert(event <= TM_EQ); 55 | if (ttisnil(tm)) { /* no tag method? */ 56 | events->flags |= cast_byte(1u<metatable; 68 | break; 69 | case LUA_TUSERDATA: 70 | mt = uvalue(o)->metatable; 71 | break; 72 | default: 73 | mt = G(L)->mt[ttypenv(o)]; 74 | } 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/lib/lua/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 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_LEN, 24 | TM_EQ, /* last tag method with `fast' access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_DIV, 29 | TM_MOD, 30 | TM_POW, 31 | TM_UNM, 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 | #define ttypename(x) luaT_typenames_[(x) + 1] 47 | #define objtypename(x) ttypename(ttypenv(x)) 48 | 49 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 50 | 51 | 52 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 53 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 54 | TMS event); 55 | LUAI_FUNC void luaT_init (lua_State *L); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/lib/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/lua/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 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 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_BITLIBNAME "bit32" 33 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 34 | 35 | #define LUA_MATHLIBNAME "math" 36 | LUAMOD_API int (luaopen_math) (lua_State *L); 37 | 38 | #define LUA_DBLIBNAME "debug" 39 | LUAMOD_API int (luaopen_debug) (lua_State *L); 40 | 41 | #define LUA_LOADLIBNAME "package" 42 | LUAMOD_API int (luaopen_package) (lua_State *L); 43 | 44 | 45 | /* open all previous libraries */ 46 | LUALIB_API void (luaL_openlibs) (lua_State *L); 47 | 48 | 49 | 50 | #if !defined(lua_assert) 51 | #define lua_assert(x) ((void)0) 52 | #endif 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/lib/lua/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 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 | static l_noret error(LoadState* S, const char* why) 31 | { 32 | luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); 33 | luaD_throw(S->L,LUA_ERRSYNTAX); 34 | } 35 | 36 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 37 | #define LoadByte(S) (lu_byte)LoadChar(S) 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 39 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 40 | 41 | #if !defined(luai_verifycode) 42 | #define luai_verifycode(L,b,f) /* empty */ 43 | #endif 44 | 45 | static void LoadBlock(LoadState* S, void* b, size_t size) 46 | { 47 | if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); 48 | } 49 | 50 | static int LoadChar(LoadState* S) 51 | { 52 | char x; 53 | LoadVar(S,x); 54 | return x; 55 | } 56 | 57 | static int LoadInt(LoadState* S) 58 | { 59 | int x; 60 | LoadVar(S,x); 61 | if (x<0) error(S,"corrupted"); 62 | return x; 63 | } 64 | 65 | static lua_Number LoadNumber(LoadState* S) 66 | { 67 | lua_Number x; 68 | LoadVar(S,x); 69 | return x; 70 | } 71 | 72 | static TString* LoadString(LoadState* S) 73 | { 74 | size_t size; 75 | LoadVar(S,size); 76 | if (size==0) 77 | return NULL; 78 | else 79 | { 80 | char* s=luaZ_openspace(S->L,S->b,size); 81 | LoadBlock(S,s,size*sizeof(char)); 82 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 83 | } 84 | } 85 | 86 | static void LoadCode(LoadState* S, Proto* f) 87 | { 88 | int n=LoadInt(S); 89 | f->code=luaM_newvector(S->L,n,Instruction); 90 | f->sizecode=n; 91 | LoadVector(S,f->code,n,sizeof(Instruction)); 92 | } 93 | 94 | static void LoadFunction(LoadState* S, Proto* f); 95 | 96 | static void LoadConstants(LoadState* S, Proto* f) 97 | { 98 | int i,n; 99 | n=LoadInt(S); 100 | f->k=luaM_newvector(S->L,n,TValue); 101 | f->sizek=n; 102 | for (i=0; ik[i]); 103 | for (i=0; ik[i]; 106 | int t=LoadChar(S); 107 | switch (t) 108 | { 109 | case LUA_TNIL: 110 | setnilvalue(o); 111 | break; 112 | case LUA_TBOOLEAN: 113 | setbvalue(o,LoadChar(S)); 114 | break; 115 | case LUA_TNUMBER: 116 | setnvalue(o,LoadNumber(S)); 117 | break; 118 | case LUA_TSTRING: 119 | setsvalue2n(S->L,o,LoadString(S)); 120 | break; 121 | default: lua_assert(0); 122 | } 123 | } 124 | n=LoadInt(S); 125 | f->p=luaM_newvector(S->L,n,Proto*); 126 | f->sizep=n; 127 | for (i=0; ip[i]=NULL; 128 | for (i=0; ip[i]=luaF_newproto(S->L); 131 | LoadFunction(S,f->p[i]); 132 | } 133 | } 134 | 135 | static void LoadUpvalues(LoadState* S, Proto* f) 136 | { 137 | int i,n; 138 | n=LoadInt(S); 139 | f->upvalues=luaM_newvector(S->L,n,Upvaldesc); 140 | f->sizeupvalues=n; 141 | for (i=0; iupvalues[i].name=NULL; 142 | for (i=0; iupvalues[i].instack=LoadByte(S); 145 | f->upvalues[i].idx=LoadByte(S); 146 | } 147 | } 148 | 149 | static void LoadDebug(LoadState* S, Proto* f) 150 | { 151 | int i,n; 152 | f->source=LoadString(S); 153 | n=LoadInt(S); 154 | f->lineinfo=luaM_newvector(S->L,n,int); 155 | f->sizelineinfo=n; 156 | LoadVector(S,f->lineinfo,n,sizeof(int)); 157 | n=LoadInt(S); 158 | f->locvars=luaM_newvector(S->L,n,LocVar); 159 | f->sizelocvars=n; 160 | for (i=0; ilocvars[i].varname=NULL; 161 | for (i=0; ilocvars[i].varname=LoadString(S); 164 | f->locvars[i].startpc=LoadInt(S); 165 | f->locvars[i].endpc=LoadInt(S); 166 | } 167 | n=LoadInt(S); 168 | for (i=0; iupvalues[i].name=LoadString(S); 169 | } 170 | 171 | static void LoadFunction(LoadState* S, Proto* f) 172 | { 173 | f->linedefined=LoadInt(S); 174 | f->lastlinedefined=LoadInt(S); 175 | f->numparams=LoadByte(S); 176 | f->is_vararg=LoadByte(S); 177 | f->maxstacksize=LoadByte(S); 178 | LoadCode(S,f); 179 | LoadConstants(S,f); 180 | LoadUpvalues(S,f); 181 | LoadDebug(S,f); 182 | } 183 | 184 | /* the code below must be consistent with the code in luaU_header */ 185 | #define N0 LUAC_HEADERSIZE 186 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) 187 | #define N2 N1+2 188 | #define N3 N2+6 189 | 190 | static void LoadHeader(LoadState* S) 191 | { 192 | lu_byte h[LUAC_HEADERSIZE]; 193 | lu_byte s[LUAC_HEADERSIZE]; 194 | luaU_header(h); 195 | memcpy(s,h,sizeof(char)); /* first char already read */ 196 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); 197 | if (memcmp(h,s,N0)==0) return; 198 | if (memcmp(h,s,N1)!=0) error(S,"not a"); 199 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); 200 | if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); 201 | } 202 | 203 | /* 204 | ** load precompiled chunk 205 | */ 206 | Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 207 | { 208 | LoadState S; 209 | Closure* cl; 210 | if (*name=='@' || *name=='=') 211 | S.name=name+1; 212 | else if (*name==LUA_SIGNATURE[0]) 213 | S.name="binary string"; 214 | else 215 | S.name=name; 216 | S.L=L; 217 | S.Z=Z; 218 | S.b=buff; 219 | LoadHeader(&S); 220 | cl=luaF_newLclosure(L,1); 221 | setclLvalue(L,L->top,cl); incr_top(L); 222 | cl->l.p=luaF_newproto(L); 223 | LoadFunction(&S,cl->l.p); 224 | if (cl->l.p->sizeupvalues != 1) 225 | { 226 | Proto* p=cl->l.p; 227 | cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); 228 | cl->l.p=p; 229 | setclLvalue(L,L->top-1,cl); 230 | } 231 | luai_verifycode(L,buff,cl->l.p); 232 | return cl; 233 | } 234 | 235 | #define MYINT(s) (s[0]-'0') 236 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) 237 | #define FORMAT 0 /* this is the official format */ 238 | 239 | /* 240 | * make header for precompiled chunks 241 | * if you change the code below be sure to update LoadHeader and FORMAT above 242 | * and LUAC_HEADERSIZE in lundump.h 243 | */ 244 | void luaU_header (lu_byte* h) 245 | { 246 | int x=1; 247 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); 248 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); 249 | *h++=cast_byte(VERSION); 250 | *h++=cast_byte(FORMAT); 251 | *h++=cast_byte(*(char*)&x); /* endianness */ 252 | *h++=cast_byte(sizeof(int)); 253 | *h++=cast_byte(sizeof(size_t)); 254 | *h++=cast_byte(sizeof(Instruction)); 255 | *h++=cast_byte(sizeof(lua_Number)); 256 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ 257 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); 258 | } 259 | -------------------------------------------------------------------------------- /src/lib/lua/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 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 Closure* 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 (lu_byte* 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 | /* data to catch conversion errors */ 23 | #define LUAC_TAIL "\x19\x93\r\n\x1a\n" 24 | 25 | /* size in bytes of header of binary files */ 26 | #define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/lib/lua/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 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) (ttisstring(o) || (luaV_tostring(L, o))) 17 | 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) 19 | 20 | #define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) 21 | 22 | #define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) 23 | 24 | 25 | /* not to called directly */ 26 | LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); 27 | 28 | 29 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 30 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 31 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 32 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 33 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 34 | StkId val); 35 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 36 | StkId val); 37 | LUAI_FUNC void luaV_finishOp (lua_State *L); 38 | LUAI_FUNC void luaV_execute (lua_State *L); 39 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 40 | LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, 41 | const TValue *rc, TMS op); 42 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/lib/lua/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** Buffered streams 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) 29 | return EOZ; 30 | z->n = size - 1; /* discount char being returned */ 31 | z->p = buff; 32 | return cast_uchar(*(z->p++)); 33 | } 34 | 35 | 36 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 37 | z->L = L; 38 | z->reader = reader; 39 | z->data = data; 40 | z->n = 0; 41 | z->p = NULL; 42 | } 43 | 44 | 45 | /* --------------------------------------------------------------- read --- */ 46 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 47 | while (n) { 48 | size_t m; 49 | if (z->n == 0) { /* no bytes in buffer? */ 50 | if (luaZ_fill(z) == EOZ) /* try to read more */ 51 | return n; /* no more input; return number of missing bytes */ 52 | else { 53 | z->n++; /* luaZ_fill consumed first byte; put it back */ 54 | z->p--; 55 | } 56 | } 57 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 58 | memcpy(b, z->p, m); 59 | z->n -= m; 60 | z->p += m; 61 | b = (char *)b + m; 62 | n -= m; 63 | } 64 | return 0; 65 | } 66 | 67 | /* ------------------------------------------------------------------------ */ 68 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 69 | if (n > buff->buffsize) { 70 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 71 | luaZ_resizebuffer(L, buff, n); 72 | } 73 | return buff->buffer; 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/lib/lua/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 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 zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 36 | 37 | 38 | #define luaZ_resizebuffer(L, buff, size) \ 39 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ 40 | (buff)->buffsize = size) 41 | 42 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 43 | 44 | 45 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 46 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 47 | void *data); 48 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ 49 | 50 | 51 | 52 | /* --------- Private Part ------------------ */ 53 | 54 | struct Zio { 55 | size_t n; /* bytes still unread */ 56 | const char *p; /* current position in buffer */ 57 | lua_Reader reader; /* reader function */ 58 | void* data; /* additional data */ 59 | lua_State *L; /* Lua state (for reader) */ 60 | }; 61 | 62 | 63 | LUAI_FUNC int luaZ_fill (ZIO *z); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/lib/microtar/microtar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 `microtar.c` for details. 6 | */ 7 | 8 | #ifndef MICROTAR_H 9 | #define MICROTAR_H 10 | 11 | #include 12 | #include 13 | 14 | #define MTAR_VERSION "0.0.0" 15 | 16 | enum { 17 | MTAR_ESUCCESS = 0, 18 | MTAR_EFAILURE = -1, 19 | MTAR_EOPENFAIL = -2, 20 | MTAR_EREADFAIL = -3, 21 | MTAR_EWRITEFAIL = -4, 22 | MTAR_ESEEKFAIL = -5, 23 | MTAR_EBADCHKSUM = -6, 24 | MTAR_ENULLRECORD = -7, 25 | MTAR_ENOTFOUND = -8 26 | }; 27 | 28 | enum { 29 | MTAR_TREG = '0', 30 | MTAR_TLNK = '1', 31 | MTAR_TSYM = '2', 32 | MTAR_TCHR = '3', 33 | MTAR_TBLK = '4', 34 | MTAR_TDIR = '5', 35 | MTAR_TFIFO = '6' 36 | }; 37 | 38 | typedef struct { 39 | unsigned mode; 40 | unsigned owner; 41 | unsigned size; 42 | unsigned mtime; 43 | unsigned type; 44 | char name[100]; 45 | char linkname[100]; 46 | } mtar_header_t; 47 | 48 | 49 | typedef struct mtar_t mtar_t; 50 | 51 | struct mtar_t { 52 | int (*read)(mtar_t *tar, void *data, unsigned size); 53 | int (*write)(mtar_t *tar, const void *data, unsigned size); 54 | int (*seek)(mtar_t *tar, unsigned pos); 55 | int (*close)(mtar_t *tar); 56 | void *stream; 57 | unsigned pos; 58 | unsigned remaining_data; 59 | unsigned last_header; 60 | }; 61 | 62 | 63 | const char* mtar_strerror(int err); 64 | 65 | int mtar_open(mtar_t *tar, const char *filename, const char *mode); 66 | int mtar_close(mtar_t *tar); 67 | 68 | int mtar_seek(mtar_t *tar, unsigned pos); 69 | int mtar_rewind(mtar_t *tar); 70 | int mtar_next(mtar_t *tar); 71 | int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h); 72 | int mtar_read_header(mtar_t *tar, mtar_header_t *h); 73 | int mtar_read_data(mtar_t *tar, void *ptr, unsigned size); 74 | 75 | int mtar_write_header(mtar_t *tar, const mtar_header_t *h); 76 | int mtar_write_data(mtar_t *tar, const void *data, unsigned size); 77 | int mtar_write_file(mtar_t *tar, const char *name, const void *data, unsigned size); 78 | int mtar_finalize(mtar_t *tar); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/lib/stb/stb_image.c: -------------------------------------------------------------------------------- 1 | #define STB_IMAGE_IMPLEMENTATION 2 | #include "stb_image.h" 3 | -------------------------------------------------------------------------------- /src/lib/stb/stb_truetype.c: -------------------------------------------------------------------------------- 1 | #define STB_TRUETYPE_IMPLEMENTATION 2 | #include "stb_truetype.h" 3 | -------------------------------------------------------------------------------- /src/luaobj.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | 12 | #include "luaobj.h" 13 | 14 | 15 | int luaobj_newclass(lua_State *L, const char *name, const char *extends, 16 | int (*constructor)(lua_State*), luaL_Reg* reg 17 | ) { 18 | /* Creates and pushes a new metatable which represents a class containing the 19 | * functions in the `reg` argument. If the `extends` argument is not NULL 20 | * this class will use the specified class as a super class */ 21 | 22 | /* Build metatable */ 23 | luaL_newmetatable(L, name); 24 | /* Add type name string */ 25 | lua_pushstring(L, "__type"); 26 | lua_pushstring(L, name); 27 | lua_rawset(L, -3); 28 | /* Make and add func table */ 29 | lua_newtable(L); 30 | luaL_setfuncs(L, reg, 0); 31 | lua_pushstring(L, "__index"); 32 | lua_pushvalue(L, -2); 33 | lua_rawset(L, -4); 34 | /* Handle extended */ 35 | if (extends) { 36 | luaL_getmetatable(L, extends); 37 | /* Pull metatable functions from base class */ 38 | char *mtfields[] = { "__gc", "__tostring", NULL }; 39 | int i; 40 | for (i = 0; mtfields[i]; i++) { 41 | lua_getfield(L, -1, mtfields[i]); 42 | lua_setfield(L, -4, mtfields[i]); 43 | } 44 | lua_setmetatable(L, -2); 45 | } 46 | lua_pop(L, 1); /* Pop func table */ 47 | luaL_setfuncs(L, reg, 0); /* Set metatable's funcs */ 48 | lua_pop(L, 1); /* Pop metatable */ 49 | 50 | /* Return constructor */ 51 | lua_pushcfunction(L, constructor); 52 | 53 | return 1; 54 | } 55 | 56 | 57 | void luaobj_setclass(lua_State *L, uint32_t type, char *name) { 58 | /* Sets the the metatable of the member at the top of the stack to the 59 | * class-metatable of the given `name` */ 60 | luaobj_head_t *udata = lua_touserdata(L, -1); 61 | udata->type = type; 62 | luaL_getmetatable(L, name); 63 | if (lua_isnil(L, -1)) { 64 | luaL_error( 65 | L, "missing metatable: assure class '%s' is inited in love.c\n", name); 66 | } 67 | lua_setmetatable(L, -2); 68 | } 69 | 70 | 71 | void *luaobj_newudata(lua_State *L, int size) { 72 | /* Creates a udata of the requested size, plus space for the luaobj_head_t 73 | * header. Returns the pointer to the udata's body */ 74 | int s = size + sizeof(luaobj_head_t); 75 | luaobj_head_t *udata = lua_newuserdata(L, s); 76 | udata->type = 0; 77 | return udata + 1; 78 | } 79 | 80 | 81 | void *luaobj_checkudata(lua_State *L, int index, uint32_t type) { 82 | /* Checks the header of a luaobj udata at the given index, taking into 83 | * account super-classes it may have extended. Returns the udata's body if 84 | * it is of the correct class, else errors out */ 85 | index = lua_absindex(L, index); 86 | luaobj_head_t *udata = lua_touserdata(L, index); 87 | if (!udata || !(udata->type & type)) { 88 | luaL_argerror(L, index, "bad type"); 89 | } 90 | return udata + 1; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /src/luaobj.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 LUAOBJ_H 9 | #define LUAOBJ_H 10 | 11 | #include 12 | 13 | #include "lib/lua/lua.h" 14 | #include "lib/lua/lualib.h" 15 | #include "lib/lua/lauxlib.h" 16 | 17 | 18 | typedef struct { 19 | uint32_t type; 20 | } luaobj_head_t; 21 | 22 | 23 | /* Each mask should consist of its unique bit and the unique bit of all its 24 | * super classes */ 25 | #define LUAOBJ_TYPE_IMAGE (1 << 0) 26 | #define LUAOBJ_TYPE_QUAD (1 << 1) 27 | #define LUAOBJ_TYPE_FONT (1 << 2) 28 | #define LUAOBJ_TYPE_SOURCE (1 << 3) 29 | 30 | 31 | int luaobj_newclass(lua_State *L, const char *name, const char *extends, 32 | int (*constructor)(lua_State*), luaL_Reg* reg); 33 | void luaobj_setclass(lua_State *L, uint32_t type, char *name); 34 | void *luaobj_newudata(lua_State *L, int size); 35 | void *luaobj_checkudata(lua_State *L, int index, uint32_t type); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "lib/dmt/dmt.h" 15 | 16 | #include "luaobj.h" 17 | #include "vga.h" 18 | #include "audio.h" 19 | #include "keyboard.h" 20 | #include "filesystem.h" 21 | #include "mouse.h" 22 | #include "image.h" 23 | #include "palette.h" 24 | #include "package.h" 25 | 26 | 27 | static lua_State *L; 28 | 29 | static void deinit(void) { 30 | /* Deinit and clear up everything. Called at exit */ 31 | audio_deinit(); 32 | vga_deinit(); 33 | keyboard_deinit(); 34 | lua_close(L); 35 | filesystem_deinit(); 36 | if ( dmt_usage() > 0 ) { 37 | dmt_dump(stdout); 38 | } 39 | } 40 | 41 | 42 | static int onLuaPanic(lua_State *L) { 43 | vga_deinit(); 44 | const char *err = lua_tostring(L, -1); 45 | printf("lua panic: %s\n", err); 46 | return 0; 47 | } 48 | 49 | 50 | int luaopen_love(lua_State *L); 51 | 52 | int main(int argc, char **argv) { 53 | 54 | /* Handle package command */ 55 | if ( package_run(argc, argv) == PACKAGE_ESUCCESS ) { 56 | exit(EXIT_SUCCESS); 57 | } 58 | 59 | /* Init everything */ 60 | atexit(deinit); 61 | audio_init(); 62 | vga_init(); 63 | palette_init(); 64 | keyboard_init(); 65 | mouse_init(); 66 | 67 | /* Init lua */ 68 | L = luaL_newstate(); 69 | lua_atpanic(L, onLuaPanic); 70 | luaL_openlibs(L); 71 | luaL_requiref(L, "love", luaopen_love, 1); 72 | 73 | /* Create `love.argv` and fill with arguments */ 74 | lua_getglobal(L, "love"); 75 | if (!lua_isnil(L, -1)) { 76 | lua_newtable(L); 77 | int i; 78 | for (i = 0; i < argc; i++) { 79 | lua_pushstring(L, argv[i]); 80 | lua_rawseti(L, -2, i + 1); 81 | } 82 | lua_setfield(L, -2, "argv"); 83 | } 84 | lua_pop(L, 1); 85 | 86 | /* Init embedded scripts */ 87 | #include "nogame_lua.h" 88 | #include "boot_lua.h" 89 | struct { 90 | const char *name, *data; int size; 91 | } items[] = { 92 | { "nogame.lua", nogame_lua, sizeof(nogame_lua) }, 93 | { "boot.lua", boot_lua, sizeof(boot_lua) }, 94 | { NULL, NULL, 0 } 95 | }; 96 | int i; 97 | for (i = 0; items[i].name; i++) { 98 | int err = luaL_loadbuffer(L, items[i].data, items[i].size, items[i].name); 99 | if (err || lua_pcall(L, 0, 0, 0) != 0) { 100 | const char *str = lua_tostring(L, -1); 101 | fprintf(stderr, "Error: %s\n", str); 102 | abort(); 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /src/modules/l_audio.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "lib/cmixer/cmixer.h" 9 | #include "luaobj.h" 10 | 11 | 12 | int l_audio_setVolume(lua_State *L) { 13 | double n = luaL_checknumber(L, 1); 14 | cm_set_master_gain(n); 15 | return 0; 16 | } 17 | 18 | 19 | int l_source_new(lua_State *L); 20 | 21 | int luaopen_audio(lua_State *L) { 22 | luaL_Reg reg[] = { 23 | { "newSource", l_source_new }, 24 | { "setVolume", l_audio_setVolume }, 25 | { 0, 0 }, 26 | }; 27 | luaL_newlib(L, reg); 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /src/modules/l_event.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "luaobj.h" 9 | #include "event.h" 10 | 11 | 12 | int l_event_pump(lua_State *L) { 13 | event_pump(); 14 | return 0; 15 | } 16 | 17 | 18 | int l_event_poll(lua_State *L) { 19 | event_t e; 20 | if (event_poll(&e)) { 21 | lua_pushstring(L, event_typestr(e.type)); 22 | 23 | switch(e.type) { 24 | case EVENT_QUIT: 25 | lua_pushnumber(L, e.quit.status); 26 | return 2; 27 | 28 | case EVENT_KEYBOARD_PRESSED: 29 | case EVENT_KEYBOARD_RELEASED: 30 | lua_pushstring(L, e.keyboard.key); 31 | lua_pushstring(L, e.keyboard.key); 32 | lua_pushboolean(L, e.keyboard.isrepeat); 33 | return 4; 34 | 35 | case EVENT_KEYBOARD_TEXTINPUT: 36 | lua_pushstring(L, e.keyboard.text); 37 | return 2; 38 | 39 | case EVENT_MOUSE_MOVED: 40 | lua_pushnumber(L, e.mouse.x); 41 | lua_pushnumber(L, e.mouse.y); 42 | lua_pushnumber(L, e.mouse.dx); 43 | lua_pushnumber(L, e.mouse.dy); 44 | return 5; 45 | 46 | case EVENT_MOUSE_PRESSED: 47 | case EVENT_MOUSE_RELEASED: 48 | lua_pushnumber(L, e.mouse.x); 49 | lua_pushnumber(L, e.mouse.y); 50 | lua_pushnumber(L, e.mouse.button); 51 | return 4; 52 | } 53 | 54 | return 1; 55 | } 56 | 57 | return 0; 58 | } 59 | 60 | 61 | int l_event_quit(lua_State *L) { 62 | int status = luaL_optnumber(L, 1, 0); 63 | event_t e; 64 | e.type = EVENT_QUIT; 65 | e.quit.status = status; 66 | event_push(&e); 67 | return 0; 68 | } 69 | 70 | 71 | 72 | int luaopen_event(lua_State *L) { 73 | luaL_Reg reg[] = { 74 | { "pump", l_event_pump }, 75 | { "poll", l_event_poll }, 76 | { "quit", l_event_quit }, 77 | { 0, 0 }, 78 | }; 79 | luaL_newlib(L, reg); 80 | return 1; 81 | } 82 | -------------------------------------------------------------------------------- /src/modules/l_filesystem.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "filesystem.h" 9 | #include "luaobj.h" 10 | 11 | 12 | int l_filesystem_mount(lua_State *L) { 13 | const char *path = luaL_checkstring(L, 1); 14 | int err = filesystem_mount(path); 15 | if (err) { 16 | lua_pushnil(L); 17 | lua_pushstring(L, filesystem_strerror(err)); 18 | return 2; 19 | } 20 | lua_pushboolean(L, 1); 21 | return 1; 22 | } 23 | 24 | 25 | int l_filesystem_unmount(lua_State *L) { 26 | const char *path = luaL_checkstring(L, 1); 27 | int err = filesystem_unmount(path); 28 | if (err) { 29 | lua_pushnil(L); 30 | lua_pushstring(L, filesystem_strerror(err)); 31 | return 2; 32 | } 33 | lua_pushboolean(L, 1); 34 | return 1; 35 | } 36 | 37 | 38 | int l_filesystem_exists(lua_State *L) { 39 | const char *filename = luaL_checkstring(L, 1); 40 | lua_pushboolean( L, filesystem_exists(filename) ); 41 | return 1; 42 | } 43 | 44 | 45 | int l_filesystem_isFile(lua_State *L) { 46 | const char *filename = luaL_checkstring(L, 1); 47 | lua_pushboolean( L, filesystem_isFile(filename) ); 48 | return 1; 49 | } 50 | 51 | 52 | int l_filesystem_isDirectory(lua_State *L) { 53 | const char *filename = luaL_checkstring(L, 1); 54 | lua_pushboolean( L, filesystem_isDirectory(filename) ); 55 | return 1; 56 | } 57 | 58 | 59 | int l_filesystem_read(lua_State *L) { 60 | const char *filename = luaL_checkstring(L, 1); 61 | int size; 62 | void *data = filesystem_read(filename, &size); 63 | if (!data) { 64 | luaL_error(L, "could not read file"); 65 | } 66 | lua_pushlstring(L, data, size); 67 | filesystem_free(data); 68 | return 1; 69 | } 70 | 71 | 72 | int l_filesystem_setWriteDir(lua_State *L) { 73 | const char *path = luaL_checkstring(L, 1); 74 | int err = filesystem_setWriteDir(path); 75 | if (err) { 76 | lua_pushnil(L); 77 | lua_pushstring(L, filesystem_strerror(err)); 78 | return 2; 79 | } 80 | lua_pushboolean(L, 1); 81 | return 1; 82 | } 83 | 84 | 85 | int l_filesystem_write(lua_State *L) { 86 | size_t sz; 87 | const char *filename = luaL_checkstring(L, 1); 88 | const char *data = luaL_tolstring(L, 2, &sz); 89 | int err = filesystem_write(filename, data, sz); 90 | if (err) { 91 | luaL_error(L, "%s", filesystem_strerror(err)); 92 | } 93 | lua_pushboolean(L, 1); 94 | return 1; 95 | } 96 | 97 | 98 | int luaopen_filesystem(lua_State *L) { 99 | luaL_Reg reg[] = { 100 | { "mount", l_filesystem_mount }, 101 | { "unmount", l_filesystem_unmount }, 102 | { "exists", l_filesystem_exists }, 103 | { "isFile", l_filesystem_isFile }, 104 | { "isDirectory", l_filesystem_isDirectory }, 105 | { "read", l_filesystem_read }, 106 | { "setWriteDir", l_filesystem_setWriteDir }, 107 | { "write", l_filesystem_write }, 108 | { 0, 0 }, 109 | }; 110 | luaL_newlib(L, reg); 111 | return 1; 112 | } 113 | -------------------------------------------------------------------------------- /src/modules/l_font.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "font.h" 9 | #include "luaobj.h" 10 | 11 | #define CLASS_TYPE LUAOBJ_TYPE_FONT 12 | #define CLASS_NAME "Font" 13 | 14 | 15 | int l_font_new(lua_State *L) { 16 | const char *filename; 17 | int ptsize = 8; 18 | if ( lua_isnoneornil(L, 2) ) { 19 | filename = NULL; 20 | ptsize = luaL_optnumber(L, 1, ptsize); 21 | } else { 22 | filename = luaL_checkstring(L, 1); 23 | ptsize = luaL_optnumber(L, 2, ptsize); 24 | } 25 | font_t *self = luaobj_newudata(L, sizeof(*self)); 26 | luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); 27 | if (filename) { 28 | const char *err = font_init(self, filename, ptsize); 29 | if (err) luaL_error(L, err); 30 | } else { 31 | font_initEmbedded(self, ptsize); 32 | } 33 | return 1; 34 | } 35 | 36 | 37 | int l_font_gc(lua_State *L) { 38 | font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 39 | font_deinit(self); 40 | return 0; 41 | } 42 | 43 | 44 | int l_font_getWidth(lua_State *L) { 45 | font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 46 | const char *p = luaL_checkstring(L, 2); 47 | int width = 0; 48 | while (*p) { 49 | width += self->glyphs[(int) (*p++ & 127)].xadvance; 50 | } 51 | lua_pushinteger(L, width); 52 | return 1; 53 | } 54 | 55 | 56 | int l_font_getHeight(lua_State *L) { 57 | font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 58 | lua_pushinteger(L, self->height); 59 | return 1; 60 | } 61 | 62 | 63 | 64 | int luaopen_font(lua_State *L) { 65 | luaL_Reg reg[] = { 66 | { "new", l_font_new }, 67 | { "__gc", l_font_gc }, 68 | { "getWidth", l_font_getWidth }, 69 | { "getHeight", l_font_getHeight }, 70 | { 0, 0 }, 71 | }; 72 | luaobj_newclass(L, CLASS_NAME, NULL, l_font_new, reg); 73 | return 1; 74 | } 75 | -------------------------------------------------------------------------------- /src/modules/l_image.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "luaobj.h" 9 | #include "palette.h" 10 | #include "image.h" 11 | 12 | 13 | #define CLASS_TYPE LUAOBJ_TYPE_IMAGE 14 | #define CLASS_NAME "Image" 15 | 16 | 17 | int l_image_new(lua_State *L) { 18 | const char *filename = luaL_checkstring(L, 1); 19 | image_t *self = luaobj_newudata(L, sizeof(*self)); 20 | luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); 21 | const char *err = image_init(self, filename); 22 | if (err) luaL_error(L, err); 23 | return 1; 24 | } 25 | 26 | 27 | int l_image_newCanvas(lua_State *L) { 28 | int width = VGA_WIDTH; 29 | int height = VGA_HEIGHT; 30 | if (lua_gettop(L) > 0) { 31 | width = luaL_checknumber(L, 1); 32 | height = luaL_checknumber(L, 2); 33 | if (width <= 0) luaL_argerror(L, 1, "width must be larger than 0"); 34 | if (height <= 0) luaL_argerror(L, 2, "height must be larger than 0"); 35 | } 36 | image_t *self = luaobj_newudata(L, sizeof(*self)); 37 | luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); 38 | image_initBlank(self, width, height); 39 | return 1; 40 | } 41 | 42 | 43 | int l_image_gc(lua_State *L) { 44 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 45 | image_deinit(self); 46 | return 0; 47 | } 48 | 49 | 50 | int l_image_getDimensions(lua_State *L) { 51 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 52 | lua_pushinteger(L, self->width); 53 | lua_pushinteger(L, self->height); 54 | return 2; 55 | } 56 | 57 | 58 | int l_image_getWidth(lua_State *L) { 59 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 60 | lua_pushinteger(L, self->width); 61 | return 1; 62 | } 63 | 64 | 65 | int l_image_getHeight(lua_State *L) { 66 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 67 | lua_pushinteger(L, self->height); 68 | return 1; 69 | } 70 | 71 | 72 | int l_image_getPixel(lua_State *L) { 73 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 74 | int x = luaL_checknumber(L, 2); 75 | int y = luaL_checknumber(L, 3); 76 | if (x < 0 || x >= self->width || y < 0 || y >= self->height) { 77 | /* Return `nil` for out of bounds (same as transparent) */ 78 | lua_pushnil(L); 79 | return 1; 80 | } else { 81 | /* Return `nil` if color is transparent, else return 3 channel values */ 82 | int idx = self->data[x + y * self->width]; 83 | if (idx == 0) { 84 | lua_pushnil(L); 85 | return 1; 86 | } else { 87 | int rgb[3]; 88 | palette_idxToColor(idx, rgb); 89 | lua_pushinteger(L, rgb[0]); 90 | lua_pushinteger(L, rgb[1]); 91 | lua_pushinteger(L, rgb[2]); 92 | return 3; 93 | } 94 | } 95 | } 96 | 97 | 98 | int l_image_setPixel(lua_State *L) { 99 | image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 100 | int x = luaL_checknumber(L, 2); 101 | int y = luaL_checknumber(L, 3); 102 | if (lua_isnoneornil(L, 4)) { 103 | /* Set transparent */ 104 | image_setPixel(self, x, y, 0); 105 | image_setMaskPixel(self, x, y, 0xff); 106 | } else { 107 | /* Get color, set pixel and mask */ 108 | int r = luaL_checknumber(L, 4); 109 | int g = luaL_checknumber(L, 5); 110 | int b = luaL_checknumber(L, 6); 111 | int idx = palette_colorToIdx(r, g, b); 112 | if (idx < -1) { 113 | luaL_error(L, "color palette exhausted: use fewer unique colors"); 114 | } 115 | image_setPixel(self, x, y, idx); 116 | image_setMaskPixel(self, x, y, 0x0); 117 | } 118 | return 0; 119 | } 120 | 121 | 122 | int luaopen_image(lua_State *L) { 123 | luaL_Reg reg[] = { 124 | { "new", l_image_new }, 125 | { "__gc", l_image_gc }, 126 | { "getDimensions", l_image_getDimensions }, 127 | { "getWidth", l_image_getWidth }, 128 | { "getHeight", l_image_getHeight }, 129 | { "getPixel", l_image_getPixel }, 130 | { "setPixel", l_image_setPixel }, 131 | { 0, 0 }, 132 | }; 133 | luaobj_newclass(L, CLASS_NAME, NULL, l_image_new, reg); 134 | return 1; 135 | } 136 | -------------------------------------------------------------------------------- /src/modules/l_keyboard.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "keyboard.h" 10 | #include "luaobj.h" 11 | 12 | 13 | int l_keyboard_setKeyRepeat(lua_State *L) { 14 | keyboard_setKeyRepeat( lua_toboolean(L, 1) ); 15 | return 0; 16 | } 17 | 18 | 19 | int l_keyboard_isDown(lua_State *L) { 20 | int n = lua_gettop(L); 21 | int res = 0; 22 | int i; 23 | for (i = 1; i <= n; i++) { 24 | const char *key = luaL_checkstring(L, i); 25 | res |= keyboard_isDown(key); 26 | } 27 | lua_pushboolean(L, res); 28 | return 1; 29 | } 30 | 31 | 32 | int luaopen_keyboard(lua_State *L) { 33 | luaL_Reg reg[] = { 34 | { "setKeyRepeat", l_keyboard_setKeyRepeat }, 35 | { "isDown", l_keyboard_isDown }, 36 | { 0, 0 }, 37 | }; 38 | luaL_newlib(L, reg); 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /src/modules/l_love.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "luaobj.h" 9 | 10 | #define LOVE_VERSION "0.2.1" 11 | 12 | 13 | int l_love_getVersion(lua_State *L) { 14 | lua_pushstring(L, LOVE_VERSION); 15 | return 1; 16 | } 17 | 18 | 19 | int luaopen_image(lua_State *L); 20 | int luaopen_quad(lua_State *L); 21 | int luaopen_font(lua_State *L); 22 | int luaopen_source(lua_State *L); 23 | int luaopen_system(lua_State *L); 24 | int luaopen_event(lua_State *L); 25 | int luaopen_filesystem(lua_State *L); 26 | int luaopen_graphics(lua_State *L); 27 | int luaopen_audio(lua_State *L); 28 | int luaopen_timer(lua_State *L); 29 | int luaopen_keyboard(lua_State *L); 30 | int luaopen_mouse(lua_State *L); 31 | 32 | int luaopen_love(lua_State *L) { 33 | int i; 34 | /* Init classes -- all the built in classes are inited here as to create the 35 | * metatables required by their constructors. Any new classes must also be 36 | * registered here before they will work. */ 37 | int (*classes[])(lua_State *L) = { 38 | luaopen_image, 39 | luaopen_quad, 40 | luaopen_font, 41 | luaopen_source, 42 | NULL, 43 | }; 44 | for (i = 0; classes[i]; i++) { 45 | classes[i](L); 46 | lua_pop(L, 1); 47 | } 48 | 49 | /* Init love module */ 50 | luaL_Reg reg[] = { 51 | { "getVersion", l_love_getVersion }, 52 | { 0, 0 }, 53 | }; 54 | luaL_newlib(L, reg); 55 | 56 | /* Init submodules */ 57 | struct { char *name; int (*fn)(lua_State *L); } mods[] = { 58 | { "system", luaopen_system }, 59 | { "event", luaopen_event }, 60 | { "filesystem", luaopen_filesystem }, 61 | { "graphics", luaopen_graphics }, 62 | { "audio", luaopen_audio }, 63 | { "timer", luaopen_timer }, 64 | { "keyboard", luaopen_keyboard }, 65 | { "mouse", luaopen_mouse }, 66 | { 0 }, 67 | }; 68 | for (i = 0; mods[i].name; i++) { 69 | mods[i].fn(L); 70 | lua_setfield(L, -2, mods[i].name); 71 | } 72 | return 1; 73 | } 74 | -------------------------------------------------------------------------------- /src/modules/l_mouse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 "mouse.h" 9 | #include "luaobj.h" 10 | 11 | 12 | int l_mouse_getPosition(lua_State *L) { 13 | lua_pushinteger(L, mouse_getX()); 14 | lua_pushinteger(L, mouse_getY()); 15 | return 2; 16 | } 17 | 18 | 19 | int l_mouse_getX(lua_State *L) { 20 | lua_pushinteger(L, mouse_getX()); 21 | return 1; 22 | } 23 | 24 | 25 | int l_mouse_getY(lua_State *L) { 26 | lua_pushinteger(L, mouse_getY()); 27 | return 1; 28 | } 29 | 30 | 31 | int l_mouse_isDown(lua_State *L) { 32 | int n = lua_gettop(L); 33 | int res = 0; 34 | int i; 35 | for (i = 1; i <= n; i++) { 36 | int idx = luaL_checknumber(L, i) - 1; 37 | if (idx >= 0 && idx < MOUSE_BUTTON_MAX) { 38 | res |= mouse_isDown(idx); 39 | } 40 | } 41 | lua_pushboolean(L, res); 42 | return 1; 43 | } 44 | 45 | 46 | 47 | int luaopen_mouse(lua_State *L) { 48 | luaL_Reg reg[] = { 49 | { "getPosition", l_mouse_getPosition }, 50 | { "getX", l_mouse_getX }, 51 | { "getY", l_mouse_getY }, 52 | { "isDown", l_mouse_isDown }, 53 | { 0, 0 }, 54 | }; 55 | luaL_newlib(L, reg); 56 | return 1; 57 | } 58 | -------------------------------------------------------------------------------- /src/modules/l_quad.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | 12 | #include "lib/dmt/dmt.h" 13 | #include "quad.h" 14 | #include "luaobj.h" 15 | 16 | 17 | #define CLASS_TYPE LUAOBJ_TYPE_QUAD 18 | #define CLASS_NAME "Quad" 19 | 20 | 21 | int l_quad_new(lua_State *L) { 22 | quad_t *self = luaobj_newudata(L, sizeof(*self)); 23 | luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); 24 | self->x = luaL_checknumber(L, 1); 25 | self->y = luaL_checknumber(L, 2); 26 | self->width = luaL_checknumber(L, 3); 27 | self->height = luaL_checknumber(L, 4); 28 | return 1; 29 | } 30 | 31 | 32 | int l_quad_setViewport(lua_State *L) { 33 | quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 34 | self->x = luaL_checknumber(L, 2); 35 | self->y = luaL_checknumber(L, 3); 36 | self->width = luaL_checknumber(L, 4); 37 | self->height = luaL_checknumber(L, 5); 38 | return 0; 39 | } 40 | 41 | 42 | int l_quad_getViewport(lua_State *L) { 43 | quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 44 | lua_pushnumber(L, self->x); 45 | lua_pushnumber(L, self->y); 46 | lua_pushnumber(L, self->width); 47 | lua_pushnumber(L, self->height); 48 | return 4; 49 | } 50 | 51 | 52 | int luaopen_quad(lua_State *L) { 53 | luaL_Reg reg[] = { 54 | { "new", l_quad_new }, 55 | { "getViewport", l_quad_getViewport }, 56 | { "setViewport", l_quad_setViewport }, 57 | { 0, 0 }, 58 | }; 59 | luaobj_newclass(L, CLASS_NAME, NULL, l_quad_new, reg); 60 | return 1; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/modules/l_source.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include "lib/cmixer/cmixer.h" 10 | #include "filesystem.h" 11 | #include "luaobj.h" 12 | 13 | 14 | #define CLASS_TYPE LUAOBJ_TYPE_SOURCE 15 | #define CLASS_NAME "Source" 16 | 17 | 18 | typedef struct { 19 | cm_Source *source; 20 | void *data; 21 | } source_t; 22 | 23 | 24 | int l_source_new(lua_State *L) { 25 | const char *filename = luaL_checkstring(L, 1); 26 | /* Create object */ 27 | source_t *self = luaobj_newudata(L, sizeof(*self)); 28 | luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); 29 | memset(self, 0, sizeof(*self)); 30 | /* Load file */ 31 | int size; 32 | self->data = filesystem_read(filename, &size); 33 | if (!self->data) { 34 | luaL_error(L, "could not open file"); 35 | } 36 | /* Init source */ 37 | self->source = cm_new_source_from_mem(self->data, size); 38 | if (!self->source) { 39 | luaL_error(L, "%s", cm_get_error()); 40 | } 41 | /* Return object */ 42 | return 1; 43 | } 44 | 45 | 46 | int l_source_gc(lua_State *L) { 47 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 48 | if (self->source) cm_destroy_source(self->source); 49 | if (self->data) filesystem_free(self->data); 50 | return 0; 51 | } 52 | 53 | 54 | int l_source_setVolume(lua_State *L) { 55 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 56 | double n = luaL_checknumber(L, 2); 57 | cm_set_gain(self->source, n); 58 | return 0; 59 | } 60 | 61 | 62 | int l_source_setPitch(lua_State *L) { 63 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 64 | double n = luaL_checknumber(L, 2); 65 | cm_set_pitch(self->source, n); 66 | return 0; 67 | } 68 | 69 | 70 | int l_source_setLooping(lua_State *L) { 71 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 72 | int enable = lua_toboolean(L, 2); 73 | cm_set_loop(self->source, enable); 74 | return 0; 75 | } 76 | 77 | 78 | int l_source_getDuration(lua_State *L) { 79 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 80 | double n = cm_get_length(self->source); 81 | lua_pushnumber(L, n); 82 | return 1; 83 | } 84 | 85 | 86 | int l_source_isPlaying(lua_State *L) { 87 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 88 | lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PLAYING); 89 | return 1; 90 | } 91 | 92 | 93 | int l_source_isPaused(lua_State *L) { 94 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 95 | lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PAUSED); 96 | return 1; 97 | } 98 | 99 | 100 | int l_source_isStopped(lua_State *L) { 101 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 102 | lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_STOPPED); 103 | return 1; 104 | } 105 | 106 | 107 | int l_source_tell(lua_State *L) { 108 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 109 | double n = cm_get_position(self->source); 110 | lua_pushnumber(L, n); 111 | return 1; 112 | } 113 | 114 | 115 | int l_source_play(lua_State *L) { 116 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 117 | cm_play(self->source); 118 | return 0; 119 | } 120 | 121 | 122 | int l_source_pause(lua_State *L) { 123 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 124 | cm_pause(self->source); 125 | return 0; 126 | } 127 | 128 | 129 | int l_source_stop(lua_State *L) { 130 | source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); 131 | cm_stop(self->source); 132 | return 0; 133 | } 134 | 135 | 136 | int luaopen_source(lua_State *L) { 137 | luaL_Reg reg[] = { 138 | { "new", l_source_new }, 139 | { "__gc", l_source_gc }, 140 | { "setVolume", l_source_setVolume }, 141 | { "setPitch", l_source_setPitch }, 142 | { "setLooping", l_source_setLooping }, 143 | { "getDuration", l_source_getDuration }, 144 | { "isPlaying", l_source_isPlaying }, 145 | { "isPaused", l_source_isPaused }, 146 | { "isStopped", l_source_isStopped }, 147 | { "tell", l_source_tell }, 148 | { "play", l_source_play }, 149 | { "pause", l_source_pause }, 150 | { "stop", l_source_stop }, 151 | { 0, 0 }, 152 | }; 153 | luaobj_newclass(L, CLASS_NAME, NULL, l_source_new, reg); 154 | return 1; 155 | } 156 | -------------------------------------------------------------------------------- /src/modules/l_system.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include "lib/dmt/dmt.h" 11 | #include "luaobj.h" 12 | #include "vga.h" 13 | 14 | 15 | int l_system_getOS(lua_State *L) { 16 | lua_pushstring(L, "DOS"); 17 | return 1; 18 | } 19 | 20 | 21 | int l_system_getMemUsage(lua_State *L) { 22 | lua_pushnumber(L, lua_gc(L, LUA_GCCOUNT, 0) + dmt_usage() / 1024); 23 | return 1; 24 | } 25 | 26 | 27 | 28 | int luaopen_system(lua_State *L) { 29 | luaL_Reg reg[] = { 30 | { "getOS", l_system_getOS }, 31 | { "getMemUsage", l_system_getMemUsage }, 32 | { 0, 0 }, 33 | }; 34 | luaL_newlib(L, reg); 35 | return 1; 36 | } 37 | -------------------------------------------------------------------------------- /src/modules/l_timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include "luaobj.h" 11 | #include "image.h" 12 | #include "vga.h" 13 | 14 | long long timer_lastStep; 15 | double timer_lastDt; 16 | 17 | double timer_avgLastDt; 18 | double timer_avgAcc = 1; 19 | int timer_avgCount; 20 | double timer_avgTimer; 21 | 22 | 23 | int l_timer_step(lua_State *L) { 24 | /* Do delta */ 25 | long long now; 26 | /* Sometimes a call to uclock() will return a slightly earlier time than the 27 | * previous call, resulting in a negative delta time. The below loop keeps 28 | * trying for a proper value if this occurs. */ 29 | do { 30 | now = uclock(); 31 | timer_lastDt = (now - timer_lastStep) / (double) UCLOCKS_PER_SEC; 32 | } while (timer_lastDt < 0); 33 | timer_lastStep = now; 34 | /* Do average */ 35 | timer_avgAcc += timer_lastDt; 36 | timer_avgCount++; 37 | timer_avgTimer -= timer_lastDt; 38 | if (timer_avgTimer <= 0) { 39 | timer_avgLastDt = (timer_avgAcc / timer_avgCount); 40 | timer_avgTimer += 1; 41 | timer_avgAcc = 0; 42 | timer_avgCount = 0; 43 | } 44 | return 0; 45 | } 46 | 47 | 48 | int l_timer_sleep(lua_State *L) { 49 | delay(luaL_checknumber(L, 1) * 1000.); 50 | return 1; 51 | } 52 | 53 | 54 | int l_timer_getDelta(lua_State *L) { 55 | lua_pushnumber(L, timer_lastDt); 56 | return 1; 57 | } 58 | 59 | 60 | int l_timer_getAverageDelta(lua_State *L) { 61 | lua_pushnumber(L, timer_avgLastDt); 62 | return 1; 63 | } 64 | 65 | 66 | int l_timer_getFPS(lua_State *L) { 67 | lua_pushnumber(L, (int)(1. / timer_avgLastDt)); 68 | return 1; 69 | } 70 | 71 | 72 | int l_timer_getTime(lua_State *L) { 73 | lua_pushnumber(L, uclock() / (double) UCLOCKS_PER_SEC); 74 | return 1; 75 | } 76 | 77 | 78 | int luaopen_timer(lua_State *L) { 79 | luaL_Reg reg[] = { 80 | { "step", l_timer_step }, 81 | { "sleep", l_timer_sleep }, 82 | { "getDelta", l_timer_getDelta }, 83 | { "getAverageDelta", l_timer_getAverageDelta }, 84 | { "getFPS", l_timer_getFPS }, 85 | { "getTime", l_timer_getTime }, 86 | { 0, 0 }, 87 | }; 88 | luaL_newlib(L, reg); 89 | return 1; 90 | } 91 | -------------------------------------------------------------------------------- /src/mouse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | #include "luaobj.h" 12 | #include "mouse.h" 13 | #include "event.h" 14 | 15 | int mouse_inited; 16 | int mouse_x, mouse_y; 17 | int mouse_lastX, mouse_lastY; 18 | int mouse_buttonStates[MOUSE_BUTTON_MAX]; 19 | 20 | 21 | void mouse_init(void) { 22 | union REGS regs = {}; 23 | int86(0x33, ®s, ®s); 24 | mouse_inited = regs.x.ax ? 1 : 0; 25 | } 26 | 27 | 28 | void mouse_update(void) { 29 | if (!mouse_inited) { 30 | return; 31 | } 32 | 33 | /* Update mouse position */ 34 | union REGS regs = {}; 35 | regs.x.ax = 3; 36 | int86(0x33, ®s, ®s); 37 | mouse_x = regs.x.cx >> 1; 38 | mouse_y = regs.x.dx; 39 | 40 | /* Do moved event if mouse moved */ 41 | if (mouse_x != mouse_lastX || mouse_y != mouse_lastY) { 42 | event_t e; 43 | e.type = EVENT_MOUSE_MOVED; 44 | e.mouse.x = mouse_x; 45 | e.mouse.y = mouse_y; 46 | e.mouse.dx = mouse_x - mouse_lastX; 47 | e.mouse.dy = mouse_y - mouse_lastY; 48 | event_push(&e); 49 | } 50 | 51 | /* Update last position */ 52 | mouse_lastX = mouse_x; 53 | mouse_lastY = mouse_y; 54 | 55 | /* Update button states and push pressed/released events */ 56 | int i, t; 57 | for (i = 0; i < MOUSE_BUTTON_MAX; i++) { 58 | for (t = 0; t < 2; t++) { 59 | memset(®s, 0, sizeof(regs)); 60 | regs.x.ax = 5 + t; 61 | regs.x.bx = i; 62 | int86(0x33, ®s, ®s); 63 | if (regs.x.bx) { 64 | /* Push event */ 65 | event_t e; 66 | e.type = t == 0 ? EVENT_MOUSE_PRESSED : EVENT_MOUSE_RELEASED; 67 | e.mouse.button = i; 68 | e.mouse.x = mouse_x; 69 | e.mouse.y = mouse_y; 70 | event_push(&e); 71 | /* Set state */ 72 | mouse_buttonStates[i] = t == 0 ? 1 : 0; 73 | } 74 | } 75 | } 76 | } 77 | 78 | 79 | 80 | int mouse_isDown(int button) { 81 | return mouse_buttonStates[button]; 82 | } 83 | 84 | 85 | int mouse_getX(void) { 86 | return mouse_x; 87 | } 88 | 89 | 90 | int mouse_getY(void) { 91 | return mouse_y; 92 | } 93 | -------------------------------------------------------------------------------- /src/mouse.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 MOUSE_H 9 | #define MOUSE_H 10 | 11 | enum { 12 | MOUSE_BUTTON_LEFT, 13 | MOUSE_BUTTON_RIGHT, 14 | MOUSE_BUTTON_MIDDLE, 15 | MOUSE_BUTTON_MAX 16 | }; 17 | 18 | 19 | void mouse_init(void); 20 | void mouse_update(void); 21 | int mouse_isDown(int button); 22 | int mouse_getX(void); 23 | int mouse_getY(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/package.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "lib/microtar/microtar.h" 15 | 16 | #include "package.h" 17 | 18 | 19 | static void error(const char *fmt, ...) { 20 | va_list argp; 21 | printf("Package error: "); 22 | va_start(argp, fmt); 23 | vprintf(fmt, argp); 24 | va_end(argp); 25 | printf("\n"); 26 | exit(EXIT_FAILURE); 27 | } 28 | 29 | 30 | static int tar_stream_write(mtar_t *tar, const void *data, unsigned size) { 31 | unsigned res = fwrite(data, 1, size, tar->stream); 32 | if (res != size) { 33 | error("failed when writing to output file"); 34 | } 35 | return MTAR_ESUCCESS; 36 | } 37 | 38 | 39 | static void concat(char *dst, int dstsz, ...) { 40 | const char *s; 41 | va_list argp; 42 | int i = 0; 43 | va_start(argp, dstsz); 44 | while ( (s = va_arg(argp, const char*)) ) { 45 | while (*s) { 46 | dst[i++] = *s++; 47 | if (i == dstsz) { 48 | error("string length exceeds destination buffer"); 49 | } 50 | } 51 | } 52 | dst[i] = '\0'; 53 | va_end(argp); 54 | } 55 | 56 | 57 | static 58 | void concat_path(char *dst, int dstsz, const char *dir, const char *filename) { 59 | int dirlen = strlen(dir); 60 | if ( dir[dirlen - 1] == '/' || *dir == '\0' ) { 61 | concat(dst, dstsz, dir, filename, NULL); 62 | } else { 63 | concat(dst, dstsz, dir, "/", filename, NULL); 64 | } 65 | } 66 | 67 | 68 | static void write_file(mtar_t *tar, const char *inname, const char *outname) { 69 | FILE *fp = fopen(inname, "rb"); 70 | if (!fp) { 71 | error("couldn't open input file '%s'", inname); 72 | } 73 | 74 | /* Get size */ 75 | fseek(fp, 0, SEEK_END); 76 | int size = ftell(fp); 77 | fseek(fp, 0, SEEK_SET); 78 | 79 | /* Write header */ 80 | mtar_header_t h; 81 | memset(&h, 0, sizeof(h)); 82 | concat(h.name, sizeof(h.name), outname, NULL); 83 | h.size = size; 84 | h.mode = 0664; 85 | mtar_write_header(tar, &h); 86 | 87 | /* Write file */ 88 | int chr; 89 | while ( (chr = fgetc(fp)) != EOF ) { 90 | unsigned char byte = chr; 91 | mtar_write_data(tar, &byte, 1); 92 | } 93 | 94 | /* Close file and return ok */ 95 | fclose(fp); 96 | } 97 | 98 | 99 | static void write_dir(mtar_t *tar, const char *indir, const char *outdir) { 100 | char inbuf[256]; 101 | char outbuf[256]; 102 | struct dirent *ep; 103 | 104 | DIR *dir = opendir(indir); 105 | if (!dir) { 106 | error("couldn't open input dir '%s'", indir); 107 | } 108 | 109 | /* Write dir */ 110 | if (*outdir) { 111 | mtar_header_t h; 112 | memset(&h, 0, sizeof(h)); 113 | concat(h.name, sizeof(h.name), outdir, NULL); 114 | h.type = MTAR_TDIR; 115 | h.mode = 0775; 116 | mtar_write_header(tar, &h); 117 | } 118 | 119 | /* Write files */ 120 | while ( (ep = readdir(dir)) ) { 121 | /* Skip `.` and `..` */ 122 | if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) { 123 | continue; 124 | } 125 | /* Get full input name and full output name */ 126 | concat_path(inbuf, sizeof(inbuf), indir, ep->d_name); 127 | concat_path(outbuf, sizeof(outbuf), outdir, ep->d_name); 128 | /* Write */ 129 | DIR *d = opendir(inbuf); 130 | if (d) { 131 | closedir(d); 132 | write_dir(tar, inbuf, outbuf); 133 | } else { 134 | write_file(tar, inbuf, outbuf); 135 | } 136 | } 137 | 138 | closedir(dir); 139 | } 140 | 141 | 142 | void package_make(const char *indir, const char *outfile, const char *exefile, int type) { 143 | /* Open file */ 144 | FILE *fp = fopen(outfile, "wb"); 145 | if (!fp) { 146 | error("couldn't open output file"); 147 | } 148 | 149 | /* Copy .exe to file if exe type is set */ 150 | if (type == PACKAGE_TEXE) { 151 | FILE *exefp = fopen(exefile, "rb"); 152 | if (!exefp) { 153 | error("couldn't open .exe file"); 154 | } 155 | int chr; 156 | while ( (chr = fgetc(exefp)) != EOF ) { 157 | fputc(chr, fp); 158 | } 159 | fclose(exefp); 160 | } 161 | 162 | /* Get start of file (used for offset) */ 163 | int start = ftell(fp); 164 | 165 | /* Init tar writer */ 166 | mtar_t tar; 167 | memset(&tar, 0, sizeof(tar)); 168 | tar.write = tar_stream_write; 169 | tar.stream = fp; 170 | 171 | /* Write package data to file and finalize tar */ 172 | write_dir(&tar, indir, ""); 173 | mtar_finalize(&tar); 174 | 175 | /* Write "TAR\0" and offset int so we can find the .tar if it was appended 176 | * onto the end of the .exe */ 177 | int offset = ftell(fp) - start + 8; 178 | fwrite("TAR\0", 1, 4, fp); 179 | fwrite(&offset, 1, 4, fp); 180 | 181 | /* Done */ 182 | fclose(fp); 183 | } 184 | 185 | 186 | int package_run(int argc, char **argv) { 187 | /* Check for `--pack` argument; return failure if it isn't present */ 188 | if (argc < 2) { 189 | return PACKAGE_EFAILURE; 190 | } 191 | if ( strcmp(argv[1], "--pack") != 0 && strcmp(argv[1], "--PACK") != 0 ) { 192 | return PACKAGE_EFAILURE; 193 | } 194 | 195 | /* Check arguments */ 196 | if (argc < 4) { 197 | error("expected arguments: %s DIRNAME OUTFILE", argv[1]); 198 | } 199 | 200 | /* Set package type based on file extension */ 201 | int type = PACKAGE_TTAR; 202 | if ( strstr(argv[3], ".exe") || strstr(argv[3], ".EXE") ) { 203 | type = PACKAGE_TEXE; 204 | } 205 | 206 | /* Make package and return success*/ 207 | package_make(argv[2], argv[3], argv[0], type); 208 | return PACKAGE_ESUCCESS; 209 | } 210 | -------------------------------------------------------------------------------- /src/package.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 | enum { 9 | PACKAGE_TTAR, 10 | PACKAGE_TEXE 11 | }; 12 | 13 | enum { 14 | PACKAGE_ESUCCESS = 0, 15 | PACKAGE_EFAILURE = -1 16 | }; 17 | 18 | void package_make(const char *indir, const char *outfile, const char *exefile, int type); 19 | int package_run(int argc, char **argv); 20 | -------------------------------------------------------------------------------- /src/palette.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | 11 | #include "palette.h" 12 | #include "vga.h" 13 | 14 | #define MAX_IDX 256 15 | #define MAP_SIZE 1024 16 | #define MAP_MASK (MAP_SIZE - 1) 17 | 18 | struct { unsigned color; int idx; } palette_map[MAP_SIZE]; 19 | unsigned palette_palette[MAX_IDX]; 20 | int palette_nextIdx; 21 | int palette_inited; 22 | 23 | 24 | void palette_init(void) { 25 | if (palette_inited) return; 26 | palette_reset(); 27 | palette_inited = 1; 28 | } 29 | 30 | 31 | void palette_reset(void) { 32 | /* Reset nextIdx -- start at idx 1 as 0 is used for transparency */ 33 | palette_nextIdx = 1; 34 | /* Reset palette_map */ 35 | int i; 36 | for (i = 0; i < MAP_SIZE; i++) { 37 | palette_map[i].idx = -1; 38 | } 39 | } 40 | 41 | 42 | static unsigned hash(const void *data, int size) { 43 | unsigned hash = 5381; 44 | const unsigned char *p = data; 45 | while (size--) { 46 | hash = ((hash << 5) + hash) ^ *p++; 47 | } 48 | return hash; 49 | } 50 | 51 | 52 | int palette_colorToIdx(int r, int g, int b) { 53 | palette_init(); 54 | 55 | /* Make 24bit rgb color */ 56 | unsigned color = ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff); 57 | 58 | /* Hash color */ 59 | unsigned h = hash(&color, sizeof(color)); 60 | 61 | /* Find color in hashmap */ 62 | int i = h & MAP_MASK; 63 | while (palette_map[i].idx != -1) { 64 | if (palette_map[i].color == color) { 65 | return palette_map[i].idx; 66 | } 67 | i = (i + 1) & MAP_MASK; 68 | } 69 | 70 | /* Color wasn't found in hashmap -- Add to system palette and map */ 71 | if (palette_nextIdx >= MAX_IDX) { 72 | return -1; /* Return -1 for error if we've exceeded the palette capacity */ 73 | } 74 | int idx = palette_nextIdx++; 75 | 76 | /* Update internal palette table */ 77 | palette_palette[idx] = color; 78 | 79 | /* Update system palette */ 80 | vga_setPalette(idx, r, g, b); 81 | 82 | /* Add to hashmap and return idx */ 83 | palette_map[i].color = color; 84 | palette_map[i].idx = idx; 85 | return idx; 86 | } 87 | 88 | 89 | int palette_idxToColor(int idx, int *rgb) { 90 | /* Bounds check, return -1 on error */ 91 | if (idx <= 0 || idx >= MAX_IDX) { 92 | return -1; 93 | } 94 | 95 | /* Store color in array */ 96 | unsigned color = palette_palette[idx]; 97 | rgb[0] = (color ) & 0xff; /* r */ 98 | rgb[1] = (color >> 8) & 0xff; /* g */ 99 | rgb[2] = (color >> 16) & 0xff; /* b */ 100 | 101 | /* Return 0 for ok */ 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /src/palette.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 PALETTE_H 9 | #define PALETTE_H 10 | 11 | void palette_init(void); 12 | void palette_reset(void); 13 | int palette_colorToIdx(int r, int g, int b); 14 | int palette_idxToColor(int idx, int *rgb); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/quad.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 QUAD_H 9 | #define QUAD_H 10 | 11 | #include "luaobj.h" 12 | 13 | typedef struct { 14 | lua_Number x, y; 15 | lua_Number width, height; 16 | } quad_t; 17 | 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/soundblaster.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 Florian Kesseler 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 SOUNDBLASTER_H 9 | #define SOUNDBLASTER_H 10 | 11 | #include 12 | 13 | // Error codes 14 | #define SOUNDBLASTER_ENV_NOT_SET 1 15 | #define SOUNDBLASTER_ENV_INVALID 2 16 | #define SOUNDBLASTER_DOS_ERROR 3 17 | #define SOUNDBLASTER_RESET_ERROR 4 18 | #define SOUNDBLASTER_ALLOC_ERROR 5 19 | 20 | #define SOUNDBLASTER_SAMPLES_PER_BUFFER 2048 21 | 22 | typedef int16_t const* (*soundblaster_getSampleProc)(void); 23 | 24 | int soundblaster_init(soundblaster_getSampleProc sampleproc); 25 | void soundblaster_deinit(void); 26 | int soundblaster_getSampleRate(void); 27 | int soundblaster_getSampleBufferSize(void); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/vga.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "vga.h" 15 | 16 | int vga_inited = 0; 17 | 18 | 19 | void vga_init(void) { 20 | if (vga_inited) return; 21 | vga_inited = 1; 22 | union REGS regs = {}; 23 | regs.h.al = 0x13; 24 | int86(0x10, ®s, ®s); 25 | } 26 | 27 | 28 | void vga_deinit(void) { 29 | if (!vga_inited) return; 30 | vga_inited = 0; 31 | union REGS regs = {}; 32 | regs.h.al = 0x3; 33 | int86(0x10, ®s, ®s); 34 | } 35 | 36 | 37 | void vga_setPalette(int idx, int r, int g, int b) { 38 | outp(0x03c8, idx); 39 | outp(0x03c9, (r >> 2) & 0x3f); 40 | outp(0x03c9, (g >> 2) & 0x3f); 41 | outp(0x03c9, (b >> 2) & 0x3f); 42 | } 43 | 44 | 45 | void vga_update(pixel_t *buffer) { 46 | dosmemput(buffer, VGA_WIDTH * VGA_HEIGHT, 0xa0000); 47 | } 48 | -------------------------------------------------------------------------------- /src/vga.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017 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 VGA_H 9 | #define VGA_H 10 | 11 | #define VGA_WIDTH 320 12 | #define VGA_HEIGHT 200 13 | 14 | typedef unsigned char pixel_t; 15 | 16 | void vga_init(void); 17 | void vga_deinit(void); 18 | void vga_setPalette(int idx, int r, int g, int b); 19 | void vga_update(pixel_t *buffer); 20 | 21 | #endif 22 | --------------------------------------------------------------------------------