aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.win14
-rw-r--r--reference/networking.md40
-rw-r--r--spec/common.lua63
-rw-r--r--spec/headless/deviceinit.lua15
-rw-r--r--spec/headless/init.lua13
-rw-r--r--spec/server/init.lua20
-rw-r--r--spec/test1_spec.lua62
-rw-r--r--spec/test2_spec.lua297
-rw-r--r--spec/test3_spec.lua100
-rw-r--r--spec/test4_spec.lua170
-rw-r--r--spec/test5_spec.lua108
-rw-r--r--src/client/callbackhandeler.cpp73
-rw-r--r--src/client/lua_api/gui/iguibutton.cpp15
-rw-r--r--src/client/lua_api/gui/iguicheckbox.cpp17
-rw-r--r--src/client/lua_api/gui/iguicolorselector.cpp16
-rw-r--r--src/client/lua_api/gui/iguicombobox.cpp37
-rw-r--r--src/client/lua_api/gui/iguieditbox.cpp18
-rw-r--r--src/client/lua_api/gui/iguielement.cpp20
-rw-r--r--src/client/lua_api/gui/iguifiledialog.cpp13
-rw-r--r--src/client/lua_api/gui/iguiimage.cpp19
-rw-r--r--src/client/lua_api/gui/iguilabel.cpp7
-rw-r--r--src/client/lua_api/gui/iguispinbox.cpp11
-rw-r--r--src/client/lua_api/gui/iguitreeview.cpp14
-rw-r--r--src/client/lua_api/gui/iguiwindow.cpp12
-rw-r--r--src/client/lua_api/io/ifilesystem.cpp34
-rw-r--r--src/client/lua_api/load_gui.cpp11
-rw-r--r--src/client/lua_api/load_scene.cpp5
-rw-r--r--src/client/lua_api/scene/icamera.cpp61
-rw-r--r--src/client/lua_api/scene/igeneric.cpp72
-rw-r--r--src/client/lua_api/scene/ilight.cpp36
-rw-r--r--src/client/lua_api/scene/imesh.cpp3
-rw-r--r--src/client/lua_api/video/iimage.cpp29
-rw-r--r--src/client/lua_api/video/smaterial.cpp53
-rw-r--r--src/client/main.cpp4
-rw-r--r--src/server/lua_api/load_io.cpp85
-rw-r--r--src/shared/lua_api/load_common.cpp51
-rw-r--r--src/shared/lua_api/load_net.cpp28
-rw-r--r--src/shared/lua_api/phys/bcollider.cpp7
-rw-r--r--src/shared/lua_api/phys/bghostobject.cpp15
-rw-r--r--src/shared/lua_api/phys/bphysbox.cpp2
-rw-r--r--src/shared/lua_api/phys/bphysgeneric.cpp15
-rw-r--r--src/shared/lua_api/phys/bphysmodel.cpp19
42 files changed, 1171 insertions, 533 deletions
diff --git a/Makefile.win b/Makefile.win
index 059b3f1..bedd50e 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -6,6 +6,7 @@ CXX?=g++
MKDIR?=mkdir
RM?=rm -f
ECHO?=echo
+LD=g++
shared_objs=$(SHARED_SRC:src/shared/%=build/shared/%.o)
client_objs=$(CLIENT_SRC:src/client/%=build/client/%.o)
@@ -19,7 +20,8 @@ CLIENT_LIB_DIRS=\
-Llib/bullet/lib\
-Llib/irrlicht/lib/Win32-gcc\
-Llib/luajit/src\
- -Llib/nng/static
+ -Llib/nng/static\
+
CLIENT_LIBS=\
-lBulletDynamics\
@@ -33,8 +35,8 @@ CLIENT_LIBS=\
-lmswsock\
-ladvapi32\
-lwinmm\
- -lm\
- #-lstdc++
+ -lm
+ #-lstdc++-6
CFLAGS+=-DNNG_STATIC_LIB
ifeq ($(DEBUG), true)
@@ -51,13 +53,15 @@ clean:
$(RM) $(shared_objs)
$(RM) $(bins)
+nuke: clean
+
bin/client/bin/brokengine_client.exe : $(client_objs) $(shared_objs)
$(Q)echo "Linking $@"
- $(Q)$(CXX) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose
+ $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose
bin/server/bin/brokengine_server.exe : $(server_objs) $(shared_objs)
$(Q)echo "Linking $@"
- $(Q)$(CXX) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose
+ $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose
$(shared_objs) : build/shared/%.o : src/shared/%.cpp src/shared/%.hpp
$(Q)echo "CXX $@"
diff --git a/reference/networking.md b/reference/networking.md
new file mode 100644
index 0000000..087dd95
--- /dev/null
+++ b/reference/networking.md
@@ -0,0 +1,40 @@
+# Networking example
+
+A simple example of networking, ripped straight from the brok[en]gine test suite.
+
+
+### Client
+
+ local has_ponged = false
+ local socket = net.newsocket(net.PAIR)
+ socket:bind("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ print("socket receive triggered")
+ has_ponged = true
+ local message = stream:readstring()
+ assert(message == "ping")
+ socket:send(function(stream2)
+ stream2:writestring("pong")
+ end)
+ end
+ local i = os.time()
+ function GAME.tick()
+ if has_ponged then
+ GAME.exit()
+ end
+ if i - os.time() > 5 then
+ error("Failed")
+ end
+ end
+
+### Server
+
+ local socket = net.newsocket(net.PAIR)
+ socket:connect("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ local message = stream:readstring()
+ assert(message == "pong")
+ end
+ socket:send(function(stream)
+ stream:writestring("ping")
+ end)
diff --git a/spec/common.lua b/spec/common.lua
new file mode 100644
index 0000000..4df1a7c
--- /dev/null
+++ b/spec/common.lua
@@ -0,0 +1,63 @@
+local common = {}
+local game_bin = nil
+
+if package.config:sub(1,1) == "/" then -- linux or osx
+ game_bin = "bin/client/bin/brokengine_client"
+ server_bin = "bin/server/bin/brokengine_server"
+else -- windows
+ game_bin = "bin\\client\\bin\\brokengine_client.exe"
+ server_bin = "bin\\server\\bin\\brokengine_server.exe"
+end
+
+function common.rungame()
+ f = io.popen(game_bin .. " spec/headless","r")
+ d = f:read("*all")
+ f:close()
+ --print(d)
+ return d
+end
+
+function common.runboth()
+ --print("Running both")
+ --Do we have a race condition here? (Can client start and send it's message
+ --before the server is ready to accept?
+ f1 = io.popen(server_bin .. " spec/server","r")
+ f2 = io.popen(game_bin .. " spec/headless","r")
+ --print("Both ran...")
+ d1 = f1:read("*all")
+ d2 = f2:read("*all")
+ --print("Both read all")
+ f1:close()
+ f2:close()
+ --print("returning")
+ return d1, d2
+end
+
+function common.writegame(...)
+ f = io.open("spec/headless/init.lua","w")
+ data = {"GAME.crashy()"}
+ for _,v in pairs({...}) do
+ data[#data + 1] = v
+ end
+ data[#data + 1] = "\nGAME.exit()\n"
+ f:write(table.concat(data,"\n"))
+ f:close()
+end
+
+function common.writeserver(...)
+ f = io.open("spec/server/init.lua","w")
+ data = {...}
+ data[#data + 1] = "\nGAME.exit()\n"
+ f:write(table.concat(data,"\n"))
+ f:close()
+end
+
+function common.assert_game_runs()
+ assert.is_not_nil(common.rungame():find("\nGoodbye\n$"))
+end
+function common.assert_both_run()
+ local a,b = common.runboth()
+ assert.is_not_nil(a:find("\nGoodbye\n$"))
+ assert.is_not_nil(b:find("\nGoodbye\n$"))
+end
+return common
diff --git a/spec/headless/deviceinit.lua b/spec/headless/deviceinit.lua
new file mode 100644
index 0000000..6725820
--- /dev/null
+++ b/spec/headless/deviceinit.lua
@@ -0,0 +1,15 @@
+return {
+ ["Anti Alias"] = 16,
+ ["Bits Per Pixel"] = 16,
+ ["Device Type"] = "BEST",
+ ["Display Adapter"] = 0,
+ ["Double Buffer"] = true,
+ ["Multithreaded"] = false,
+ ["Driver Type"] = "NULL",
+ ["Fullscreen"] = false,
+ ["Stencil Buffer"] = true,
+ ["Stereo Buffer"] = false,
+ ["VSync"] = true,
+ ["Window Width"] = 640,
+ ["Window Height"] = 480,
+}
diff --git a/spec/headless/init.lua b/spec/headless/init.lua
new file mode 100644
index 0000000..a5cf357
--- /dev/null
+++ b/spec/headless/init.lua
@@ -0,0 +1,13 @@
+GAME.crashy()
+ local socket = net.newsocket(net.PAIR)
+ socket:connect("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ local message = stream:readstring()
+ assert(message == "pong")
+ end
+ socket:send(function(stream)
+ stream:writestring("ping")
+ end)
+
+
+GAME.exit()
diff --git a/spec/server/init.lua b/spec/server/init.lua
new file mode 100644
index 0000000..f895ba3
--- /dev/null
+++ b/spec/server/init.lua
@@ -0,0 +1,20 @@
+ local has_ponged = false
+ local socket = net.newsocket(net.PAIR)
+ socket:bind("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ print("Socket receive triggered")
+ has_ponged = true
+ local message = stream:readstring()
+ assert(message == "ping")
+ socket:send(function(stream2)
+ stream2:writestring("pong")
+ end)
+ end
+ function GAME.tick()
+ if has_ponged then
+ GAME.exit()
+ end
+ end
+
+
+GAME.exit()
diff --git a/spec/test1_spec.lua b/spec/test1_spec.lua
index 147abbd..01d6b0d 100644
--- a/spec/test1_spec.lua
+++ b/spec/test1_spec.lua
@@ -1,5 +1,10 @@
-print("Hello, world!")
+if not package.path:find("spec/%?%.lua;") then
+ print("including spec")
+ package.path = "./spec/?.lua;" .. package.path
+end
+_G.assert = assert
+local common = require("common")
--[[Create the headless client init file]]
local f = io.open("spec/headless/deviceinit.lua","w")
f:write([=[
@@ -21,44 +26,14 @@ return {
]=])
f:close()
-local game_bin = nil
-if package.config:sub(1,1) == "/" then -- linux or osx
- game_bin = "bin/client/bin/brokengine_client"
-else
- game_bin = "bin\\client\\bin\\brokengine_client.exe"
-end
-
-function rungame()
- f = io.popen(game_bin .. " spec/headless","r")
- d = f:read("*all")
- f:close()
- return d
-end
-
-function writegame(...)
- f = assert(io.open("spec/headless/init.lua","w"))
- data = {"GAME.crashy()"}
- for _,v in pairs({...}) do
- data[#data + 1] = v
- end
- data[#data + 1] = "\nGAME.exit()\n"
- f:write(table.concat(data))
- f:close()
-end
-
-function assert_game_runs()
- assert.truthy(rungame():find("\nGoodbye\n$"))
-end
-
describe("Brok[en]gine",function()
- it("should run",function()
- writegame()
- d = rungame()
- assert_game_runs()
+ it("should run #smoke",function()
+ common.writegame()
+ common.assert_game_runs()
end)
- it("should provide a lua environment",function()
- writegame("print(\"Hello from lua!\")")
- d = rungame()
+ it("should provide a lua environment #smoke",function()
+ common.writegame("print(\"Hello from lua!\")")
+ d = common.rungame()
assert.truthy(d:find("\nHello from lua!\n"))
end)
@@ -75,15 +50,16 @@ describe("Brok[en]gine",function()
windows = "newwindow",
}) do
it("should provide functions to make gui " .. k,function()
- writegame("assert(gui." .. v .. ")")
- assert_game_runs()
+ common.writegame("assert(gui." .. v .. ")")
+ common.assert_game_runs()
end)
end
it("should provide functions to get the width and height of the screen",function()
- writegame("assert(scrw)")
- assert_game_runs()
- writegame("assert(scrh)")
- assert_game_runs()
+ common.writegame("assert(scrw)")
+ common.assert_game_runs()
+ common.writegame("assert(scrh)")
+ common.assert_game_runs()
end)
+
end)
diff --git a/spec/test2_spec.lua b/spec/test2_spec.lua
index 6b90878..82ca33e 100644
--- a/spec/test2_spec.lua
+++ b/spec/test2_spec.lua
@@ -1,195 +1,102 @@
-
-do return end
-local test = require("u-test")
-
-function rungame()
- f = io.popen("bin\\client\\bin\\brokengine_client.exe spec/headless","r")
- d = f:read("*all")
- f:close()
- return d
-end
-
-function runboth()
- f1 = io.popen("bin\\server\\bin\\brokengine_server.exe spec/server","r")
- f2 = io.popen("bin\\client\\bin\\brokengine_client.exe spec/headless","r")
- d1 = f1:read("*all")
- d2 = f2:read("*all")
- f1:close()
- f2:close()
- return d1, d2
-end
-
-function writegame(...)
- f = io.open("spec/headless/init.lua","w")
- data = {"GAME.crashy()"}
- for _,v in pairs({...}) do
- data[#data + 1] = v
- end
- data[#data + 1] = "\nGAME.exit()\n"
- f:write(table.concat(data,"\n"))
- f:close()
-end
-
-function writeserver(...)
- f = io.open("spec/server/init.lua","w")
- data = {...}
- --data[#data + 1] = "\nGAME.exit()\n"
- f:write(table.concat(data,"\n"))
- f:close()
-end
-
-function assert_game_runs()
- test.is_not_nil(rungame():find("\nGoodbye\n$"))
-end
-function assert_both_run()
- local a,b = runboth()
- test.is_not_nil(a:find("\nGoodbye\n$"))
- test.is_not_nil(b:find("\nGoodbye\n$"))
-end
-
-test.game_runs = function()
- writegame("")
- assert_game_runs()
-end
-
-test.gui.elements_exist = function()
- for k,v in pairs({
- buttons = "newbutton",
- checkboxes = "newcheckbox",
- colorselectors = "newcolorselector",
- editboxes = "neweditbox",
- openfiledialogs = "newfileopendialog",
- images = "newiguiimage",
- labels = "newlabel",
- spinboxes = "newspinbox",
- treeviews = "newtreeview",
- windows = "newwindow",
- }) do
- writegame("assert(gui." .. v .. ")")
- assert_game_runs()
- end
-end
-
-test.gui.screen_functions = function()
- writegame("assert(scrw)")
- assert_game_runs()
- writegame("assert(scrh)")
- assert_game_runs()
-end
-
---#define PAIR 1
---#define BUS 2
---#define PUB 3
---#define SUB 4
---#define PULL 5
---#define PUSH 6
---#define REQ 7
---#define REP 8
---#define RESPOND 9
---#define SURVEY 10
-local protocols = {
- "PAIR", "BUS", "PUB", "SUB", "PULL", "PUSH", "REQ", "REP", "RESPOND", "SURVEY"
-}
-test.net.protocols_exist = function()
- for k,v in pairs(protocols) do
- writegame(string.format("assert(net.%s)",v))
- assert_game_runs()
- end
-end
-
-for _,sockettype in pairs(protocols) do
- for _,func in pairs({
- "bind","connect","send"
- }) do
- test.net[sockettype .. "_socket_has_" .. func .. "_function"] = function()
- writegame(string.format([[
- local socket = net.newsocket(net.%s)
- assert(socket.%s)
- assert(type(socket.%s) == "function")
- ]],sockettype,func,func))
- assert_game_runs()
- end
- end
-end
---test.net.functions_exist = function()
- --writegame("assert(net.newsocket and type(net.newsocket == 'function'))")
- --assert_game_runs()
- --for _,sockettype in pairs(protocols) do
- --for _,func in pairs({
- --}) do
- --writegame(string.format([[
- --local socket = net.newsocket(net.%s)
- --assert(socket.%s)
- --assert(type(socket.%s) == "function")
- --]],sockettype,func,func))
- --assert_game_runs()
- --end
- --end
---end
-
-test.net.protocol_pair = function()
- writeserver([[
- local has_ponged = false
- local socket = net.newsocket(net.PAIR)
- socket:bind("tcp://127.0.0.1:5555")
- function socket:receive(stream)
- print("Socket receive triggered")
- has_ponged = true
- local message = stream:readstring()
- assert(message == "ping")
- socket:send(function(stream2)
- stream2:writestring("pong")
- end)
- end
- function GAME.tick()
- if has_ponged then
- GAME.exit()
- end
- end
- ]])
- writegame([[
- local socket = net.newsocket(net.PAIR)
- socket:connect("tcp://127.0.0.1:5555")
- function socket:receive(stream)
- local message = stream:readstring()
- assert(message == "pong")
- end
- socket:send(function(stream)
- stream:writestring("ping")
- end)
- ]])
- assert_both_run()
-end
-
---test.net.protocol_pubsub = function()
- --writeserver([[
- --local counter = 0
- --local max_count = 10000 --How long to live for,
- ----since we can't detect when the user
- ----sends the message
- --local socket = net.newsocket(net.PUB)
- --socket:bind("tcp://127.0.0.1:5555")
- --function GAME.tick()
- --if counter < max_count then
- --counter = counter + 1
- --socket:send(function(stream)
- --stream:writestring("ping")
- --end)
- --else
- --GAME.exit()
- --end
- --end
- --]])
- --writegame([[
- --local socket = net.newsocket(net.SUB)
- --socket:connect("tcp://127.0.0.1:5555")
- --local oldgameexit = GAME.exit
- --socket:receive(function(stream)
- --assert(stream:readstring() == "ping")
- --oldgameexit()
- --end)
- --function GAME.exit() return end --Stop the client from exiting
- --]])
---end
-
-test.summary()
+
+--do return end
+--local test = require("u-test")
+if not package.path:find("spec/%?%.lua;") then
+ print("including spec")
+ package.path = "./spec/?.lua;" .. package.path
+end
+local common = require("common")
+_G.assert = assert
+
+describe("gui library", function()
+ for k,v in pairs({
+ buttons = "newbutton",
+ checkboxes = "newcheckbox",
+ colorselectors = "newcolorselector",
+ editboxes = "neweditbox",
+ openfiledialogs = "newfileopendialog",
+ images = "newiguiimage",
+ labels = "newlabel",
+ spinboxes = "newspinbox",
+ treeviews = "newtreeview",
+ windows = "newwindow",
+ }) do
+ it("should have a function to create " .. k,function()
+ common.writegame("assert(gui." .. v .. ")")
+ common.assert_game_runs()
+ end)
+ end
+ it("should have a function to check the screen's width",function()
+ common.writegame("assert(scrw)")
+ common.assert_game_runs()
+ end)
+ it("should have a function to check the screen's height", function()
+ common.writegame("assert(scrh)")
+ common.assert_game_runs()
+ end)
+end)
+
+
+local protocols = {
+ "PAIR", "BUS", "PUB", "SUB", "PULL", "PUSH", "REQ", "REP", "RESPOND", "SURVEY"
+}
+describe("network library",function()
+ for _,v in pairs(protocols) do
+ it("should have a constant for the " .. v .. " protocol",function()
+ common.writegame(string.format("assert(net.%s)",v))
+ common.assert_game_runs()
+ end)
+ end
+ it("should have a function to create a new socket",function()
+ common.writegame("assert(net.newsocket)")
+ common.assert_game_runs()
+ end)
+ for _,v in pairs(protocols) do
+ for _,j in pairs{"bind","connect","send"} do
+ it(string.format("should be able to create a %s socket with a %s method",v,j))
+ common.writegame(string.format([[
+ local socket = net.newsocket(net.%s)
+ assert(socket.%s)
+ assert(type(socket.%s) == "function")
+ ]],v,j,j))
+ common.assert_game_runs()
+ end
+ end
+ it("should be able to set up a PAIR connection and send data through #smoke",function()
+ common.writeserver([[
+ local has_ponged = false
+ local socket = net.newsocket(net.PAIR)
+ socket:bind("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ print("socket receive triggered")
+ has_ponged = true
+ local message = stream:readstring()
+ assert(message == "ping")
+ socket:send(function(stream2)
+ stream2:writestring("pong")
+ end)
+ end
+ local i = os.time()
+ function GAME.tick()
+ if has_ponged then
+ GAME.exit()
+ end
+ if i - os.time() > 5 then
+ error("Failed")
+ end
+ end
+ ]])
+ common.writegame([[
+ local socket = net.newsocket(net.PAIR)
+ socket:connect("tcp://127.0.0.1:5555")
+ function socket:receive(stream)
+ local message = stream:readstring()
+ assert(message == "pong")
+ end
+ socket:send(function(stream)
+ stream:writestring("ping")
+ end)
+ ]])
+ common.assert_both_run()
+ end)
+end)
diff --git a/spec/test3_spec.lua b/spec/test3_spec.lua
index 8861b0c..e0c4c93 100644
--- a/spec/test3_spec.lua
+++ b/spec/test3_spec.lua
@@ -1,97 +1,13 @@
-local game_bin = nil
-if package.config:sub(1,1) == "/" then -- linux or osx
- game_bin = "bin/client/bin/brokengine_client"
- server_bin = "bin/server/bin/brokengine_server"
-else
- game_bin = "bin\\client\\bin\\brokengine_client.exe"
- server_bin = "bin\\server\\bin\\brokengine_server.exe"
+if not package.path:find("spec/%?%.lua;") then
+ print("including spec")
+ package.path = "./spec/?.lua;" .. package.path
end
+local common = require("common")
+_G.assert = assert
-function rungame()
- f = io.popen(game_bin .. " spec/headless","r")
- d = f:read("*all")
- f:close()
- return d
-end
-
-function runboth()
- --print("Running both")
- --Do we have a race condition here? (Can client start and send it's message
- --before the server is ready to accept?
- f1 = io.popen(server_bin .. " spec/server","r")
- f2 = io.popen(game_bin .. " spec/headless","r")
- --print("Both ran...")
- d1 = f1:read("*all")
- d2 = f2:read("*all")
- --print("Both read all")
- f1:close()
- f2:close()
- --print("returning")
- return d1, d2
-end
-
-function writegame(...)
- f = io.open("spec/headless/init.lua","w")
- data = {"GAME.crashy()"}
- for _,v in pairs({...}) do
- data[#data + 1] = v
- end
- data[#data + 1] = "\nGAME.exit()\n"
- f:write(table.concat(data,"\n"))
- f:close()
-end
-
-function writeserver(...)
- f = io.open("spec/server/init.lua","w")
- data = {...}
- data[#data + 1] = "\nGAME.exit()\n"
- f:write(table.concat(data,"\n"))
- f:close()
-end
-
-function assert_game_runs()
- test.is_not_nil(rungame():find("\nGoodbye\n$"))
-end
-function assert_both_run()
- local a,b = runboth()
- assert.is_not_nil(a:find("\nGoodbye\n$"))
- assert.is_not_nil(b:find("\nGoodbye\n$"))
-end
-describe("networking",function()
- it("should communicate with PAIR sockets",function()
- writeserver([[
- local has_ponged = false
- local socket = net.newsocket(net.PAIR)
- socket:bind("tcp://127.0.0.1:5555")
- function socket:receive(stream)
- print("Socket receive triggered")
- has_ponged = true
- local message = stream:readstring()
- assert(message == "ping")
- socket:send(function(stream2)
- stream2:writestring("pong")
- end)
- end
- function GAME.tick()
- if has_ponged then
- GAME.exit()
- end
- end
- ]])
- --print("writing game...")
- writegame([[
- local socket = net.newsocket(net.PAIR)
- socket:connect("tcp://127.0.0.1:5555")
- function socket:receive(stream)
- local message = stream:readstring()
- assert(message == "pong")
- end
- socket:send(function(stream)
- stream:writestring("ping")
- end)
- ]])
- --print("asserting both run...")
- assert_both_run()
+describe("physics library",function()
+ it("should have methods to create a physics box",function()
+
end)
end)
diff --git a/spec/test4_spec.lua b/spec/test4_spec.lua
new file mode 100644
index 0000000..93c4e70
--- /dev/null
+++ b/spec/test4_spec.lua
@@ -0,0 +1,170 @@
+local game_bin = nil
+if package.config:sub(1,1) == "/" then -- linux or osx
+ game_bin = "bin/client/bin/brokengine_client"
+else
+ game_bin = "bin\\client\\bin\\brokengine_client.exe"
+end
+
+function rungame()
+ f = io.popen(game_bin .. " spec/headless","r")
+ d = f:read("*all")
+ f:close()
+ return d
+end
+
+function writegame(...)
+ f = assert(io.open("spec/headless/init.lua","w"))
+ data = {"GAME.crashy()"}
+ for _,v in pairs({...}) do
+ data[#data + 1] = v
+ end
+ data[#data + 1] = "\nGAME.exit()\n"
+ f:write(table.concat(data))
+ f:close()
+end
+
+function assert_game_runs()
+ local results = rungame()
+ assert.truthy(results:find("\nGoodbye\n$"), results)
+end
+
+gui_api = {
+ button = {
+ func = "gui.newbutton",
+ params = {
+ {
+ name = "dimensions",
+ required = true,
+ type = "rect4d",
+ },
+ {
+ name = "default_text",
+ required = true,
+ type = "string",
+ },
+ {
+ name = "parent",
+ required = false,
+ type = "guielement",
+ },
+ },
+ callbacks = {
+ "onClick", "onFocus", "onUnfocus", "onHover", "onLeave"
+ }
+ },
+ fileopendialog = {
+ func = "gui.newfileopendialog",
+ params = {
+ {
+ name = "title",
+ required = false,
+ type = "string",
+ },
+ {
+ name = "path",
+ required = false,
+ type = "filepath",
+ },
+ {
+ name = "parent",
+ required = false,
+ type = "guielement",
+ },
+ {
+ name = "modal",
+ required = false,
+ type = "boolean",
+ }
+ },
+ callbacks = {
+ "onDirectorySelect","onFileSelect","onCanceled"
+ }
+ },
+ label = {
+ func = "gui.newlabel",
+ params = {
+ {
+ name = "pos",
+ required = true,
+ type = "rect4d",
+ },
+ {
+ name = "text",
+ required = true,
+ type = "string",
+ },
+ {
+ name = "parent",
+ required = false,
+ type = "guielement",
+ }
+ },
+ callbacks = {
+
+ }
+ },
+}
+
+--[[For some reason these can't be local, _ENV dosn't find them.]]
+local function mr()
+ return string.format("%d",math.floor(math.random()*100))
+end
+function generate_rect4d()
+ return string.format("{{%d,%d},{%d,%d}}",mr(),mr(),mr(),mr())
+end
+function generate_string()
+ return "\"test!\""
+end
+function generate_guielement()
+ return "gui.getroot()"
+end
+function generate_filepath()
+ return "\".\""
+end
+function generate_boolean()
+ return "true"
+end
+describe("Brok[en]gine",function()
+ describe("gui system",function()
+ for k,v in pairs(gui_api) do
+ describe(k,function()
+ local paramstring = {}
+ local num_optional_args = 0
+ local num_required_args = 0
+ for i,j in pairs(v.params) do
+ assert(_ENV["generate_" .. j.type], "Could not find a generator for type: " .. j.type)
+ if j.required then
+ num_required_args = num_required_args + 1
+ else
+ num_optional_args = num_optional_args + 1
+ end
+ paramstring[#paramstring + 1] = _ENV["generate_" .. j.type]()
+ end
+ for i = num_required_args, num_required_args + num_optional_args do
+ it(string.format(" with %d params", i),function()
+ local truncated_params = {}
+ for j = 1, i do
+ truncated_params[j] = paramstring[j]
+ end
+ local game_file = string.format("%s(%s)",v.func,table.concat(truncated_params, ","))
+ --print("running:",game_file)
+ writegame(game_file)
+ assert_game_runs()
+ end)
+ it(string.format(" 100 elemants with %d params", i),function()
+ local game_file = {}
+ for j = 1,100 do
+ local truncated_params = {}
+ for k = 1, i do
+ truncated_params[k] = paramstring[k]
+ end
+ game_file[#game_file + 1] = string.format("%s(%s)",v.func,table.concat(truncated_params, ","))
+ end
+ writegame(table.concat(game_file,"\n"))
+ assert_game_runs()
+ end)
+ end
+ end)
+ end
+ end)
+end)
diff --git a/spec/test5_spec.lua b/spec/test5_spec.lua
new file mode 100644
index 0000000..b4b9333
--- /dev/null
+++ b/spec/test5_spec.lua
@@ -0,0 +1,108 @@
+--[[
+physics things
+]]
+package.path = "./spec/?.lua;" .. package.path
+_G.assert = assert
+local common = require("common")
+
+local spawn_1_box = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {0,0,0}, 0)
+GAME.exit()
+]]
+
+local spawn_several_boxes = [[
+GAME.crashy()
+for i = 1,100 do
+ phys.newphysbox({8,8,8}, {0,10 * i,0}, 0)
+end
+GAME.exit()
+]]
+
+describe("physics",function()
+ it("should be able to spawn a physics box on the client",function()
+ common.writegame(spawn_1_box)
+ common.assert_game_runs()
+ end)
+ it("should be able to spawn several physics boxes on the client", function()
+ common.writegame(spawn_several_boxes)
+ common.assert_game_runs()
+ end)
+
+end)
+
+local getpos_exists = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {0,0,0}, 0)
+local pos = box:getpos()
+for i = 1,3 do
+ assert(pos[i] == 0, "Position is not 0")
+end
+GAME.exit()
+]]
+local getpos_works = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {10,20,30}, 0)
+local pos = box:getpos()
+assert(pos[1] == 10)
+assert(pos[2] == 20)
+assert(pos[3] == 30)
+GAME.exit()
+]]
+local setpos_exists = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {10,20,30}, 0)
+box:setpos({0,0,0})
+local pos = box:getpos()
+for i = 1,3 do
+ assert(pos[i] == 0)
+end
+GAME.exit()
+]]
+local setpos_works = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {0,0,0}, 0)
+box:setpos({10,20,30})
+local pos = box:getpos()
+assert(pos[1] == 10)
+assert(pos[2] == 20)
+assert(pos[3] == 30)
+GAME.exit()
+]]
+local falls = [[
+GAME.crashy()
+local box = phys.newphysbox({8,8,8}, {0,10,0}, 1)
+local ticks = 0
+GAME.tick = function()
+ print("Tick running...")
+ if box:getpos()[2] < 0 then
+ print("Getpos[2] is less, it is ", box:getpos()[2])
+ GAME.exit()
+ end
+ ticks = ticks + 1
+ assert(ticks < 1)
+end
+]]
+describe("physics box", function()
+ it("should have a .getpos() function",function()
+ common.writegame(getpos_exists)
+ common.assert_game_runs()
+ end)
+ it("should have a .getpos() function that returns the box's position",function()
+ common.writegame(getpos_works)
+ common.assert_game_runs()
+ end)
+ it("should have a .setpos() function",function()
+ common.writegame(setpos_exists)
+ common.assert_game_runs()
+ end)
+ it("should have a .setpos() function that sets the box's position",function()
+ common.writegame(setpos_works)
+ common.assert_game_runs()
+ end)
+ it("should fall when given mass",function()
+ --print("About to write should fall when given mass...")
+ common.writegame(falls)
+ common.assert_game_runs()
+ end)
+end)
diff --git a/src/client/callbackhandeler.cpp b/src/client/callbackhandeler.cpp
index d522e84..b6c0321 100644
--- a/src/client/callbackhandeler.cpp
+++ b/src/client/callbackhandeler.cpp
@@ -18,9 +18,6 @@ using namespace gui;
using namespace std;
extern lua_State* L;
-/***
-@module GAME
-*/
std::map<IGUIElement*, int> guielements;
//For basic events
@@ -90,8 +87,23 @@ bool GlobalEventReceiver::OnEvent(const SEvent& e){
printf("done getting gui element\n");
const char* fieldname;
switch(get){
+/***
+(Callback)Called when an @{iguiwindow} is focused
+If the function returns true, the element will not be focused.
+@function iguiwindow:onFocus()
+*/
case EGET_ELEMENT_FOCUSED: fieldname = "onFocus"; break;
+/***
+(Callback)Called when an @{iguiwindow} is unfocused
+If the function returns true, the element will not be unfocused.
+@function iguiwindow:onUnfocus()
+*/
case EGET_ELEMENT_FOCUS_LOST: fieldname = "onUnfocus"; break;
+/***
+(Callback)Called when an @{iguielement is hovered over with the mouse.
+If an element has child elements, you also get this call for each child element.
+@function iguielement:onHover()
+*/
case EGET_ELEMENT_HOVERED: fieldname = "onHover"; break;
case EGET_ELEMENT_LEFT: fieldname = "onLeave"; break;
case EGET_ELEMENT_CLOSED: fieldname = "onClose"; break;
@@ -160,6 +172,14 @@ Detects when the mouse moves across the game.
*/
switch(se.Event){
case EMIE_MOUSE_MOVED:{
+/***
+(Callback)Detects mouse movement
+Called whenever the mouse is moved
+@function GAME.onMouseMove(x,y,button)
+@tparam number x The x position that the mouse now occupies
+@tparam number y The y position that the mouse now occupies
+@tparam number button Will be EMIE_MOUSE_MOVED.
+*/
return callMouse(L,"onMouseMove",se.X,se.Y,se.Event);
}
break;
@@ -167,29 +187,74 @@ Detects when the mouse moves across the game.
case EMIE_RMOUSE_PRESSED_DOWN:
case EMIE_MMOUSE_PRESSED_DOWN:{
printf("Mouse down\n");
+/***
+(Callback)Detects mouse presses.
+Called whenever the a mouse button has been pressed
+@function GAME.onMouseDown(x,y,button)
+@tparam number x The x position of the mouse
+@tparam number y The y position of the mouse
+@tparam number button Which mouse button was pressed. Will be one of:
+EMIE_LMOUSE_PRESSED_DOWN, EMIE_RMOUSE_PRESSED_DOWN, or EMIE_MMOUSE_PRESSED_DOWN
+*/
return callMouse(L,"onMouseDown",se.X,se.Y,se.Event);
}
break;
case EMIE_LMOUSE_LEFT_UP:
case EMIE_RMOUSE_LEFT_UP:
case EMIE_MMOUSE_LEFT_UP:{
- printf("Mouse up\n");
+/***
+(Callback)Detects mouse presses.
+Detects when the mouse has been released.
+@function GAME.onMouseUp(x,y,button)
+@tparam number x The x position of the mouse on the screen (in pixels)
+@tparam number y The y position of the mouse
+@tparam number button The mouse key that was clicked, will be one of:
+EMIE_LMOUSE_LEFT_UP, EMIE_RMOUSE_LEFT_UP, or EMIE_MMOUSE_LEFT_UP.
+*/
return callMouse(L,"onMouseUp",se.X,se.Y,se.Event);
}
break;
case EMIE_MOUSE_WHEEL:{
+/***
+(Callback)Detects mouse scroll wheel.
+Triggered whenever the scroll wheel moves up or down.
+@function GAME.onMouseWheel(x,y,direction)
+@tparam number x The x position of the mouse
+@tparam number y The y position of the mouse
+@tparam number direction The direction of the scroll wheel, -1, 0 or 1
+*/
return callMouse(L,"onMouseWheel",se.X,se.Y,se.Wheel);
}
break;
case EMIE_RMOUSE_DOUBLE_CLICK:
case EMIE_MMOUSE_DOUBLE_CLICK:
case EMIE_LMOUSE_DOUBLE_CLICK:{
+/***
+(Callback)Detects double clicking.
+Tirggered whenever the user double clicked in the screen. The speed for double
+clicking is system defined, and may not be the same across platforms.
+@function GAME.onDoubleClick(x,y,button)
+@tparam number x The x position of the mouse
+@tparam number y The y position of the mouse
+@tparam number button Which button was double clicked. Will be one of:
+EMIE_RMOUSE_DOUBLE_CLICK, EMIE_LMOUSE_DOUBLE_CLICK, or EMIE_MMOUSE_DOUBLE_CLICK
+*/
return callMouse(L,"onDoubleClick",se.X,se.Y,se.Event);
}
break;
case EMIE_RMOUSE_TRIPLE_CLICK:
case EMIE_MMOUSE_TRIPLE_CLICK:
case EMIE_LMOUSE_TRIPLE_CLICK:{
+/***
+(Callback)Detects triple clicking.
+Triggered whenever the user tripple clicks on the screen. The speed for tripple
+clicking is system defined, and may not be the same across platforms.
+@function GAME.onTripleClick(x,y,button)
+@tparam number x The x position of the mouse
+@tparam number y The y position of the mouse
+@tparam number button Which button was tripple clicked. Will be one of:
+EMIE_RMOUSE_TRIPLE_CLICK, EMIE_MMOUSE_TRIPLE_CLICK, EMIE_LMOUSE_TRIPLE_CLICK
+*/
return callMouse(L,"onTripleClick",se.X,se.Y,se.Event);
}
break;
diff --git a/src/client/lua_api/gui/iguibutton.cpp b/src/client/lua_api/gui/iguibutton.cpp
index 3d4580b..cdbea77 100644
--- a/src/client/lua_api/gui/iguibutton.cpp
+++ b/src/client/lua_api/gui/iguibutton.cpp
@@ -17,9 +17,6 @@ extern "C" {
#include <shared/util/hashmap.hpp>
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace core;
using namespace gui;
@@ -30,16 +27,16 @@ char lhashkey[20];
/***
Creates a new button.
Buttons may have the following fields set for callbacks:
+
.onClick(self)
- .onFocus(self)
- .onUnfocus(self)
- .onHover(self)
- .onLeave(self)
-@function newbutton()
+
+It may additionally call any @{iguielement} callbacks
+
+@function gui.newbutton()
@tparam rect dimensions The rectangle to place the button at. If the box has a parent,
it is offset from the upper-left of the parent element.
@tparam string default_text The default text to have in the button
-@tparam ?iguielement parent The parent element of the button.
+@tparam? iguielement parent The parent element of the button.
@treturn iguibutton The button element
*/
//gui.newbutton({{sx,sy},{ex,ey}},"text"[,parent])
diff --git a/src/client/lua_api/gui/iguicheckbox.cpp b/src/client/lua_api/gui/iguicheckbox.cpp
index 6413883..365b75d 100644
--- a/src/client/lua_api/gui/iguicheckbox.cpp
+++ b/src/client/lua_api/gui/iguicheckbox.cpp
@@ -8,9 +8,6 @@ extern "C" {
#include "iguielement.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace gui;
using namespace core;
@@ -26,11 +23,11 @@ following fields, which they will call for callbacks:
It may additionally call any @{iguielement} callbacks
-@function newcheckbox()
+@function gui.newcheckbox()
@tparam rect dimensions The rectangle to place the box at. If the box has a parent,
it is offset from the upper-left of the parent element.
@tparam string default_text The default text to have in the edit box
-@tparam ?iguielement parent The parent element of the edit box
+@tparam? iguielement parent The parent element of the edit box
@treturn iguieditbox The edit box element
*/
//new({startx,starty},{endx,endy},"checkbox_name"[,ud_parent])
@@ -59,6 +56,11 @@ int newiguicheckbox(lua_State* L){
return 1;
}
+/***
+Is the checkbox checked.
+@function iguicheckbox:ischecked()
+@treturn boolean Is this checkbox checked?
+*/
//ischecked(self)
int ischecked(lua_State *L){
lua_getfield(L,-1,"guielement");
@@ -69,6 +71,11 @@ int ischecked(lua_State *L){
return 1;
}
+/***
+Set the state of the checkbox.
+@function iguicheckbox:setchecked(set)
+@tparam boolean set Should this checkbox be checked? (false to uncheck)
+*/
//setchecked(self, checked)
int setchecked(lua_State *L){
int should = lua_toboolean(L,-1);
diff --git a/src/client/lua_api/gui/iguicolorselector.cpp b/src/client/lua_api/gui/iguicolorselector.cpp
index 8a61c6d..5a11394 100644
--- a/src/client/lua_api/gui/iguicolorselector.cpp
+++ b/src/client/lua_api/gui/iguicolorselector.cpp
@@ -10,9 +10,6 @@ extern "C" {
#include "iguielement.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace gui;
using namespace core;
@@ -20,10 +17,11 @@ using namespace core;
extern IrrlichtDevice* device;
/***
-@function newcolorselector()
-Creates a new checkbox
+Creates a new Color selector.
+Creates a dialog box that allows the user to select a color. TODO:Broken?
+@function gui.newcolorselector()
@tparam string title The title for this color selector
-@tparam ?iguielement parent The parent element of the edit box
+@tparam? iguielement parent The parent element of the edit box
@treturn iguicolorselector The color selector element
*/
//newcolorselector("title"[,parent])
@@ -61,6 +59,12 @@ static const luaL_reg iguicolorselector_m[] = {
{0,0},
};
+/***
+A dialog that allows the user to select a color
+@class iguicolorselector
+@inherits guielement
+*/
+
int iguicolorselector_register(lua_State* L){//
luaL_newmetatable(L,"gui.colorselector");//m{gui.checkbox}
luaL_register(L,NULL,iguielement_m);
diff --git a/src/client/lua_api/gui/iguicombobox.cpp b/src/client/lua_api/gui/iguicombobox.cpp
index 43c66f1..a9c4137 100644
--- a/src/client/lua_api/gui/iguicombobox.cpp
+++ b/src/client/lua_api/gui/iguicombobox.cpp
@@ -11,9 +11,6 @@ extern "C" {
#include <shared/lua_api/common.hpp>
#include <client/lua_api/gui/iguicombobox.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace core;
using namespace gui;
@@ -24,10 +21,10 @@ extern IrrlichtDevice* device;
Creates a new combo box.
Buttons may have the following fields set for callbacks:
`.onChange(self)`
-@function newcombobox()
+@function gui.newcombobox()
@tparam rect dimensions The rectangle to place the button at. If the box has a parent,
it is offset from the upper-left of the parent element.
-@tparam ?iguielement parent The parent element of the button.
+@tparam? iguielement parent The parent element of the button.
@treturn iguicombobox The combo box element
*/
//gui.newcombobox({{sx,sy},{ex,ey}}[,parent])
@@ -60,7 +57,15 @@ static int newiguicombobox(lua_State* L){
return 1;
}
-//{combobox}.addItem(self,text,id)
+/***
+Add an item to the combo box
+Adds an option to this combo box, with a given id for when it it selected
+@function iguicombobox:additem(text,id)
+@tparam string text The text to add to the combo box
+@tparam number id The id to return from getselected() when this option is
+selected
+*/
+//{combobox}.add(self,text,id)
int additem(lua_State *L){
int id = lua_tonumber(L,-1);
lua_pop(L,1);//self,text
@@ -78,6 +83,12 @@ int additem(lua_State *L){
return 0;
}
+/***
+Get the selected item.
+Returns the number for the selected item, set with add()
+@function iguicombobox:get()
+@treturn number The item number that is currently selected
+*/
// {combobox}.getselected(self)
int getselected(lua_State *L){
lua_getfield(L,-1,"guielement");//self,ud_guielement
@@ -88,7 +99,13 @@ int getselected(lua_State *L){
return 1;
}
-//{combobox}.removeitem(self,id)
+/***
+Remove an item
+Removes an item from the combo box at the given id. Id's are assigned with add()
+@function iguicombobox:remove()
+@tparam number id The id number of the item to remove
+*/
+//{combobox}.remove(self,id)
int removeitem(lua_State *L){
int idx = lua_tonumber(L,-1);//self,id
lua_pop(L,1);//self
@@ -105,9 +122,9 @@ static const luaL_reg iguicombobox_f[] = {
};
static const luaL_reg iguicombobox_m[] = {
- {"addItem", additem},
- {"getSelected", getselected},
- {"removeItem", removeitem},
+ {"add", additem},
+ {"get", getselected},
+ {"remove", removeitem},
{0,0},
};
diff --git a/src/client/lua_api/gui/iguieditbox.cpp b/src/client/lua_api/gui/iguieditbox.cpp
index 7de3f37..409c2fc 100644
--- a/src/client/lua_api/gui/iguieditbox.cpp
+++ b/src/client/lua_api/gui/iguieditbox.cpp
@@ -12,10 +12,6 @@ extern "C" {
#include <shared/util/hashmap.hpp>
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
-
using namespace irr;
using namespace core;
using namespace gui;
@@ -23,11 +19,11 @@ using namespace gui;
extern IrrlichtDevice* device;
/***
-@function neweditbox()
-Creates a new text entry box
+Creates a new text entry box.
+@function gui.neweditbox()
@tparam rect dimensions The rectangle to place the box at. If the box has a parent, it is offset from the upper-left of the parent element.
-@tparam ?iguielement parent The parent element of the edit box
-@tparam ?string default_text The default text to have in the edit box
+@tparam? iguielement parent The parent element of the edit box
+@tparam? string default_text The default text to have in the edit box
@treturn iguieditbox The edit box element
*/
//gui.neweditbox({{sx,sy},{ex,ey}}[,parent][,"default text"])
@@ -73,6 +69,12 @@ static int newiguieditbox(lua_State* L){
return 1;
}
+/***
+Set the edit box to multiline mode.
+Allow / disallow the edit box to accept newlines.
+@function iguieditbox:setmultiline(enable)
+@tparam boolean enable Should the edit box allow newlines?
+*/
//self:setmultiline(bool_enabled)
int set_multiline(lua_State *L){
int should = lua_toboolean(L,-1);
diff --git a/src/client/lua_api/gui/iguielement.cpp b/src/client/lua_api/gui/iguielement.cpp
index db7669a..17ec4a5 100644
--- a/src/client/lua_api/gui/iguielement.cpp
+++ b/src/client/lua_api/gui/iguielement.cpp
@@ -1,5 +1,5 @@
/*This file defines some things that all igui stuff can do*/
-/***
+/*
All gui elements inherit from iguielement.
Some functions (like settext()) do different things for different elements.
All gui elements can call the following callbacks:
@@ -9,7 +9,6 @@ All gui elements can call the following callbacks:
onHover(self)
onLeave(self)
-@classmod iguielement
*/
extern "C" {
#include <lua.h>
@@ -28,9 +27,10 @@ using namespace core;
using namespace gui;
extern IrrlichtDevice *device;
+
/***
Move an element (by an offset) from it's current position
-@function guielement:move()
+@function iguielement:move()
@tparam vector2d position The offset to move this element by
*/
//move({element},{x,y}) -> nil
@@ -51,7 +51,7 @@ int moveiguielement(lua_State* L){
/***
Set the visibility of this element
-@function guielement:setvisible()
+@function iguielement:setvisible()
@tparam boolean visible Should this element be visible?
*/
int setvisible(lua_State *L){
@@ -69,7 +69,7 @@ int setvisible(lua_State *L){
/***
Find the rectangle that an element occupies
-@function guielement:getabsrect()
+@function iguielement:getabsrect()
@treturn rect The rectangle that this element occupies
*/
//getabsrect({element})-> {{sx,sy},{ex,ey}}
@@ -91,7 +91,7 @@ int getiguiclippingrect(lua_State* L){
/***
Find the rectangle that an element occupies that is visible to the user
-@function guielement:getabsclippingrect()
+@function iguielement:getabsclippingrect()
@treturn rect The rectangle that this element occupies that is visible to the user
*/
//getabsclippingrect({element}) :: {{sx,sy},{ex,ey}}
@@ -112,7 +112,7 @@ int getiguiabsclippingrect(lua_State *L){
/***
Find the relative rectangle that this element occupies
-@function guielement:getrelrect()
+@function iguielement:getrelrect()
@treturn rect The rectangle that this element occupies relative to it's parent
*/
int getiguirelrect(lua_State *L){
@@ -135,7 +135,7 @@ Sets the text of the element
This function may do different things to different gui elements.
For example, on a window, it sets the title.
On a button, it sets the button's text.
-@function guielement:settext()
+@function iguielement:settext()
@tparam string text The text to set on the element
*/
//setText({guielement},"text") :: nil
@@ -168,7 +168,7 @@ int setrelrect(lua_State *L){
/***
-@function guielement:gettext()
+@function iguielement:gettext()
@treturn string The caption text of the element. For input element like
editboxes, this returns the text that the edit box contains.
*/
@@ -189,7 +189,7 @@ int getiguitext(lua_State* L){
/***
Removes a gui element, and any child elements
-@function guielement:remove()
+@function iguielement:remove()
*/
//remove({self})
int removeiguielement(lua_State* L){
diff --git a/src/client/lua_api/gui/iguifiledialog.cpp b/src/client/lua_api/gui/iguifiledialog.cpp
index d717673..9b789cb 100644
--- a/src/client/lua_api/gui/iguifiledialog.cpp
+++ b/src/client/lua_api/gui/iguifiledialog.cpp
@@ -17,9 +17,6 @@ extern "C" {
#include <shared/util/hashmap.hpp>
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace core;
using namespace gui;
@@ -27,17 +24,17 @@ using namespace gui;
extern IrrlichtDevice* device;
/***
-@function newfileopendialog()
Creates a new dialog to open a file.
The file creation window may have the following fields set for callbacks:
.onDirectorySelect(self)
.onFileSelect(self)
.onCanceled(self)
-@tparam ?string title The rectangle to place the button at. If the box has a parent,
+@function gui.newfileopendialog()
+@tparam? string title The rectangle to place the button at. If the box has a parent,
it is offset from the upper-left of the parent element.
-@tparam ?string path The path to open the file dialog to
-@tparam ?iguielement parent The parent element of the button.
-@tparam ?boolean modal If other gui elements can be interacted with before this element is closed
+@tparam? string path The path to open the file dialog to
+@tparam? iguielement parent The parent element of the button.
+@tparam? boolean modal If other gui elements can be interacted with before this element is closed
@treturn iguifileopendialog The button element
*/
//gui.newfileopendialog(["title"][,"path"][,parent][,modal])
diff --git a/src/client/lua_api/gui/iguiimage.cpp b/src/client/lua_api/gui/iguiimage.cpp
index 267cbd2..81f6568 100644
--- a/src/client/lua_api/gui/iguiimage.cpp
+++ b/src/client/lua_api/gui/iguiimage.cpp
@@ -17,9 +17,6 @@ extern "C" {
#include "../../callbackhandeler.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace video;
using namespace gui;
@@ -28,14 +25,14 @@ extern IrrlichtDevice* device;
extern IGUIEnvironment* env;
/***
-@function newiguiimage()
+@function gui.newiguiimage()
Creates a new guielement with an image.
The size of the iguielement is the same as the itexture used for it's creation.
@tparam vector2d position The upper-left hand corner of the element.
it is offset from the upper-left of the parent element.
@tparam number alpha The transparency of the element.
@tparam itexture texture The texture to display on this element.
-@tparam ?iguielement parent The parent element of the button.
+@tparam? iguielement parent The parent element of the button.
@treturn iguifileopendialog The button element
*/
//newiguiimage({startx,starty},alpha,{itexture}[,parent]) -> {guielement}
@@ -70,6 +67,12 @@ static int newiguiimage(lua_State* L){
return 1;
}
+/***
+Set the color of the image
+Sets the color offset (additive color) for the image.
+@function iguiimage:setcolor(color c)
+@tparam color color The color to set the image as
+*/
//setcolor(self,{r,g,b,a})
int setcolor(lua_State* L){
long r,g,b,a;
@@ -81,6 +84,12 @@ int setcolor(lua_State* L){
return 0;
}
+/***
+Set the image of the element
+Sets the image for the element. TODO: Memory leak of old images?
+@function iguiimage:setimage(itexture texture)
+@tparam itexture texture The texture to set this image element to
+*/
//setimage(self,itexture)
int setimage(lua_State *L){
lua_getfield(L,-1,"texture");//{iguiimg},{itex}
diff --git a/src/client/lua_api/gui/iguilabel.cpp b/src/client/lua_api/gui/iguilabel.cpp
index 529d680..bcb1778 100644
--- a/src/client/lua_api/gui/iguilabel.cpp
+++ b/src/client/lua_api/gui/iguilabel.cpp
@@ -17,21 +17,18 @@ extern "C" {
#include "../../callbackhandeler.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace gui;
extern IrrlichtDevice* device;
/***
-@function newlabel()
+@function gui.newlabel()
Creates a new label to display text.
@tparam rect pos The position of the label, reletive to the upper-left of it's
parent element, or the root window if parent is nil.
@tparam string text The text to display on this label.
-@tparam ?iguielement parent The parent element of the button.
+@tparam? iguielement parent The parent element of the button.
@treturn iguilabel The label element
*/
//gui.newlabel({{sx,sy},{ex,ey}},"text"[,parent]) :: {guielement}
diff --git a/src/client/lua_api/gui/iguispinbox.cpp b/src/client/lua_api/gui/iguispinbox.cpp
index 7cb1775..25ecbde 100644
--- a/src/client/lua_api/gui/iguispinbox.cpp
+++ b/src/client/lua_api/gui/iguispinbox.cpp
@@ -12,9 +12,6 @@ extern "C" {
#include <shared/util/hashmap.hpp>
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace core;
using namespace gui;
@@ -22,13 +19,13 @@ using namespace gui;
extern IrrlichtDevice* device;
/***
-@function newspinbox()
+@function gui.newspinbox()
Creates a new spinbox
@tparam rect dimensions The rectangle to place the button at. If the box has a parent,
it is offset from the upper-left of the parent element.
-@tparam ?string default_text The default text to display in the spinbox.
-@tparam ?iguielement parent The parent element of the button.
-@tparam ?boolean border Display a border around the spinbox
+@tparam? string default_text The default text to display in the spinbox.
+@tparam? iguielement parent The parent element of the button.
+@tparam? boolean border Display a border around the spinbox
@treturn iguibutton The button element
*/
//gui.newspinbox({{sx,sy},{ex,ey}}[,"text"][,parent][,border])
diff --git a/src/client/lua_api/gui/iguitreeview.cpp b/src/client/lua_api/gui/iguitreeview.cpp
index 68aa3cc..3778a50 100644
--- a/src/client/lua_api/gui/iguitreeview.cpp
+++ b/src/client/lua_api/gui/iguitreeview.cpp
@@ -11,25 +11,21 @@ extern "C" {
#include "client/callbackhandeler.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace core;
using namespace gui;
-
extern IrrlichtDevice* device;
/***
-@function newtreeview()
+@function gui.newtreeview()
Creates a new tree view
@tparam dimensions rect The rectangle to place the tree view at.
If the box has a parent, it is offset from the upper-left of the parent element.
-@tparam ?iguielement parent The parent element of the button.
-@tparam ?boolean draw_background Should we draw a background for the tree view?
-@tparam ?boolean vertical_scroll Should there be a vertical scroll bar?
-@tparam ?boolean horizonal_scroll Should there be a horizontal scroll bar?
+@tparam? iguielement parent The parent element of the button.
+@tparam? boolean draw_background Should we draw a background for the tree view?
+@tparam? boolean vertical_scroll Should there be a vertical scroll bar?
+@tparam? boolean horizonal_scroll Should there be a horizontal scroll bar?
@treturn iguitreeview The tree view element
*/
//gui.newtreeview({{sx,sy},{ex,ey}},[,parent][,draw_background][,vertical_scroll][,horizontal_scroll])
diff --git a/src/client/lua_api/gui/iguiwindow.cpp b/src/client/lua_api/gui/iguiwindow.cpp
index 236fd5d..70f26e4 100644
--- a/src/client/lua_api/gui/iguiwindow.cpp
+++ b/src/client/lua_api/gui/iguiwindow.cpp
@@ -17,18 +17,15 @@ extern "C" {
#include "../../callbackhandeler.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module gui
-*/
using namespace irr;
using namespace gui;
/***
-@function newwindow()
Creates a new gui window .
+@function gui.newwindow()
@tparam rect dimensions The rectangle to create the window at.
@tparam string title_text The text to show in the title bar of the window
-@tparam ?iguielement parent The parent element of the window.
+@tparam? iguielement parent The parent element of the window.
@treturn iguiwindow The window element
In return to the usual gui element calls, IGUI window may call a `onClose()` callback.
@@ -84,6 +81,11 @@ static const luaL_reg iguiwindow_m[] = {
{0, 0},
};
+/***
+A window that you can add other gui elements to.
+@class iguiwindow
+@inherits iguielement
+*/
int iguiwindow_register(lua_State* L, IrrlichtDevice* d){
luaL_newmetatable(L,"gui.window");//m{gui.window}
lua_newtable(L);
diff --git a/src/client/lua_api/io/ifilesystem.cpp b/src/client/lua_api/io/ifilesystem.cpp
index 252b61b..12aab78 100644
--- a/src/client/lua_api/io/ifilesystem.cpp
+++ b/src/client/lua_api/io/ifilesystem.cpp
@@ -1,8 +1,5 @@
#include "ifilesystem.hpp"
-/***
-@module io
-*/
using namespace irr;
using namespace io;
@@ -11,7 +8,7 @@ extern IrrlichtDevice* device;
/***
A list of files in the current direcotry.
-@function list()
+@function io.list()
@treturn array The files and directories in the current directory.
*/
// io.list()
@@ -36,7 +33,7 @@ int listfilesin(lua_State *L){
/***
Changes the current directory of the program
-@function cd(dir)
+@function io.cd(dir)
@tparam string dir The directory to change to
*/
// io.cd("directory")
@@ -52,10 +49,10 @@ int changedirectory(lua_State *L){
Logs some text with Irrlicht.
`level` may be any of:
io.LOG_DEBUG, io.LOG_INFO, io.LOG_WARN, io.LOG_ERROR, io.LOG_NONE
-@function log(text,level[,hint])
+@function io.log(text,level[,hint])
@tparam string text The text to log
@tparam log_level_enum level The log level
-@tparam string hint An optional hint to supply with the log
+@tparam? string hint An optional hint to supply with the log
*/
// io.log("text",level)
// io.log("text",level[,"hint"])
@@ -83,7 +80,7 @@ int logmessage(lua_State *L){
Sets what output gets logged, and what gets ignored.
level may be any of:
io.LOG_DEBUG, io.LOG_INFO, io.LOG_WARN, io.LOG_ERROR, io.LOG_NONE
-@function set_log_level(level)
+@function io.set_log_level(level)
@tparam number level the minimul level of log to capture
*/
//io.set_log_level(level)
@@ -120,14 +117,35 @@ void ifilesystem_register(lua_State* L){
lua_getglobal(L,"io");//{io}
luaL_register(L,NULL,ifilesystem_f);
+/***
+Debugging log level
+@field io.LOG_DEBUG
+*/
lua_pushnumber(L,ELL_DEBUG);
lua_setfield(L,-2,"LOG_DEBUG");
+/***
+Informational log level
+@field io.LOG_INTO
+*/
lua_pushnumber(L,ELL_INFORMATION);
lua_setfield(L,-2,"LOG_INFO");
+/***
+Warning log level
+@field io.LOG_WARN
+*/
lua_pushnumber(L,ELL_WARNING);
lua_setfield(L,-2,"LOG_WARN");
+/***
+Error log level
+@field io.LOG_ERROR
+*/
lua_pushnumber(L,ELL_ERROR);
lua_setfield(L,-2,"LOG_ERROR");
+/***
+Nonetype log level.
+Use this with @{io#set_log_level} if you don't want to log anything.
+@field io.LOG_NONE
+*/
lua_pushnumber(L,ELL_NONE);
lua_setfield(L,-2,"LOG_NONE");
diff --git a/src/client/lua_api/load_gui.cpp b/src/client/lua_api/load_gui.cpp
index 64b9711..18fe78f 100644
--- a/src/client/lua_api/load_gui.cpp
+++ b/src/client/lua_api/load_gui.cpp
@@ -1,6 +1,5 @@
-/***
+/*
Utilities for drawing GUI things on the screen
-@module gui
*/
#include <stdio.h>
@@ -47,11 +46,19 @@ int screenheight(lua_State* L);
int getroot(lua_State *L);
/***
+Get the width of the screen.
+Get the width of the screen in pixels. This should have been set with the options
+in @{deviceinit.lua}, but may change of the course of the application's life (ex,
+if the user resizes the screen)
@function gui.scrw()
@treturn number The width of the screen
*/
/***
+Get the height of the screen.
+Get the height of the screen in pixels. This should have been set with the options
+in @{deviceinit.lua}, but may change of the course of the application's life (ex,
+if the user resizes the screen)
@function gui.scrh()
@treturn number The height of the screen
*/
diff --git a/src/client/lua_api/load_scene.cpp b/src/client/lua_api/load_scene.cpp
index c605581..f64fc26 100644
--- a/src/client/lua_api/load_scene.cpp
+++ b/src/client/lua_api/load_scene.cpp
@@ -11,8 +11,10 @@ extern "C" {
#include "scene/icamera.hpp"
#include "scene/imesh.hpp"
#include "scene/ilight.hpp"
+#include <shared/lua_api/common.hpp>
using namespace irr;
+using namespace video;
extern IrrlichtDevice* device;
@@ -25,6 +27,9 @@ void load_scenefuncs(lua_State* L){
imesh_register(L);
ilight_register(L);
+ //INode flags
+ set_const(L,EMF_WIREFRAME);
+
//lua_pop(L, 1);
}
diff --git a/src/client/lua_api/scene/icamera.cpp b/src/client/lua_api/scene/icamera.cpp
index 003f2ad..34b3447 100644
--- a/src/client/lua_api/scene/icamera.cpp
+++ b/src/client/lua_api/scene/icamera.cpp
@@ -22,6 +22,20 @@ using namespace core;
extern IrrlichtDevice* device;
+/***
+Create a maya camera
+Creates a camera that can be controlled with maya style controls by default,
+click and drag rotates the camera, while right click and mouse up/down zooms
+in or out.
+@function scene.newmayacamera()
+@treturn iscenemayacamera
+*/
+/***
+A maya camera.
+A camera that can be controlled similar to the 3d modeling software "Maya"
+@class iscenemayacamera
+@inherits iscenecamera
+*/
static int newiscenemayacamera(lua_State* L){
printf("createing maya camera!\n");
ISceneManager* smgr = device->getSceneManager();
@@ -38,6 +52,20 @@ static int newiscenemayacamera(lua_State* L){
return 1;
}
+/***
+Create an fps camera.
+Create a camera with default first person shooter controls. The camera and
+be rotated with the mouse, and moved with the arrow keys.
+@function scene.newfpscamera()
+@treturn iscenefpscamera The camera
+*/
+/***
+A camera with default FPS controls
+An FPS camera can be controlled with the arrow keys, and rotated with the mouse
+by default.
+@class iscenefpscamera
+@inherits iscenecamera
+*/
// ifpscamera.new()
static int newiscenefpscamera(lua_State* L){//
ISceneManager* smgr = device->getSceneManager();
@@ -60,6 +88,21 @@ static int newiscenefpscamera(lua_State* L){//
return 1;
}
+/***
+Create a new camera
+Creates a new camera at the given position.
+@function scene.newiscenecamera(vector3d position, vector3d lookat, iscenenode parent)
+@tparam vector3d position The position to create the camera in
+@tparam vector3d lookat A vector for the camera to look at. Use this to set it's rotation.
+@tparam? iscenenode parent A node to parent this camera to. If the parent moves, the camera will move with it.
+@treturn iscenecamera The camera
+*/
+/***
+A camera.
+The world is rendered through cameras.
+@class iscenecamera
+@inherits iscenenode
+*/
//iscenecamera.new(Vector position, Vector lookat,{node=parent})
static int newiscenecamera(lua_State* L){
printf("Createing camera!\n");
@@ -98,6 +141,12 @@ static int newiscenecamera(lua_State* L){
return 1;
}
+/***
+Lock on
+Should the camera be locked on to something?
+@function iscenecamera:bindtarget(boolean bind)
+@tparam boolean bind Should the camera be locked on to it's "lookat"?
+*/
//camera:bind_target(bool) :: nil
static int icamerabindtarget(lua_State *L){
int should_bind = lua_toboolean(L,-1);//{node=ud_cam},bool_shouldbind
@@ -110,6 +159,12 @@ static int icamerabindtarget(lua_State *L){
return 0;
}
+/***
+Gets the target of a camera
+Gets the vector that a camera is looking at
+@function iscenecamera:gettarget()
+@treturn vector3d The vector that the camera is looking at
+*/
//camera:gettarget() :: v3f
static int icameragettarget(lua_State *L){
lua_getfield(L,-1,"node");
@@ -120,6 +175,12 @@ static int icameragettarget(lua_State *L){
return 1;
}
+/***
+Set the camera's target
+Forcefully set the rotation the camera should be looking
+@function iscenecamera:settarget(vector3d target)
+@tparam vector3d target The vector that the camera should be looking at
+*/
//camera:settarget(v3f)
static int icamerasettarget(lua_State *L){
double x,y,z;
diff --git a/src/client/lua_api/scene/igeneric.cpp b/src/client/lua_api/scene/igeneric.cpp
index dcac022..a0c33b3 100644
--- a/src/client/lua_api/scene/igeneric.cpp
+++ b/src/client/lua_api/scene/igeneric.cpp
@@ -14,14 +14,8 @@ using namespace core;
using namespace scene;
using namespace video;
-/***
-@classmod iscenenode
-*/
-
extern IrrlichtDevice* device;
-
-
/***
Get the position of a scene element.
@function iscenenode:getpos()
@@ -82,13 +76,74 @@ int iscenesetangle(lua_State* L){//{node=ud_ISceneNode},{x,y,z}
}
/***
+Gets the material of a scene element.
+To check if to materials are equal, compare their .texture fields, these hold
+a light userdata.
+@function iscenenode:getmaterial()
+@treturn smaterial The material that was applied to this node
+*/
+//iscenenode:getmaterial({node=ud_ISceneNode},texture_number=0) :: {texture=ud_itexture}
+int iscenegetmaterial(lua_State *L){
+ int args = lua_gettop(L);
+ u32 layer = 0;
+ if(args == 2){
+ layer = lua_tonumber(L,-1);
+ lua_pop(L,1);
+ }
+ lua_getfield(L,-1,"node");
+ ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1);
+ lua_pop(L,2);//
+ SMaterial mat = i->getMaterial(layer);
+ ITexture *tex = mat.getTexture(0);
+ printf("got texutre:%p\n",(void*)tex);
+ lua_newtable(L);//{}
+ lua_pushlightuserdata(L,tex);//{},ud_texture
+ lua_setfield(L,-2,"texture");//{material}
+ luaL_getmetatable(L,"video.smaterial");//{material},{material_m}
+ lua_setmetatable(L,-2);//{material}
+ return 1;
+}
+
+/***
+Gets the number of materials on a scene node.
+@function iscenenode:getmaterialcount()
+@treturn number The number of materials on this node
+*/
+//iscenenode:getmaterialcount()
+int iscenegetmaterialcount(lua_State *L){
+ lua_getfield(L,-1,"node");
+ ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1);
+ lua_pop(L,2);//
+ u32 count = i->getMaterialCount();
+ lua_pushnumber(L,count);
+ return 1;
+}
+
+/***
+Sets a flag on the material
+@function iscenenode:setmaterialflag(flag,on)
+@tparam number flag The flag to modify
+@tparam boolean on Should the flag be set
+*/
+//iscenenode:setmaterialflag(flag,on)
+int iscenesetmaterialflag(lua_State *L){
+ int on = lua_toboolean(L,-1);
+ E_MATERIAL_FLAG flag = (E_MATERIAL_FLAG)lua_tonumber(L,-2);
+ lua_pop(L,2);
+ lua_getfield(L,-1,"node");
+ ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1);
+ lua_pop(L,2);//
+ i->setMaterialFlag(flag,on == 1);
+ return 0;
+}
+
+/***
Set the mateiral of a scene element.
@function iscenenode:setmaterial()
@tparam texture texture The texture to apply to this material
*/
//iscenesetmaterialtexture({node=ud_ISceneNode},{texture=ud_itexture},texture_number=0)
int iscenesetmaterial(lua_State *L){
- printf("Calling generic iscenesetmaterial function\n");
int args = lua_gettop(L);
u32 layer = 0;
if(args == 3){
@@ -220,6 +275,9 @@ extern const luaL_reg igeneric_m[] = {
{"getang", iscenegetangle},
{"setang", iscenesetangle},
{"setmaterialtexture", iscenesetmaterial},
+ {"getmaterial", iscenegetmaterial},
+ {"getmaterialcount", iscenegetmaterialcount},
+ {"setmaterialflag", iscenesetmaterialflag},
{"getname", iscenegetname},
{"setname", iscenesetname},
{"setscale", iscenesetscale},
diff --git a/src/client/lua_api/scene/ilight.cpp b/src/client/lua_api/scene/ilight.cpp
index 1e292ee..e405443 100644
--- a/src/client/lua_api/scene/ilight.cpp
+++ b/src/client/lua_api/scene/ilight.cpp
@@ -23,6 +23,21 @@ using namespace core;
extern IrrlichtDevice* device;
+/***
+Create a light
+Creates a light that illuminates the surrounding objects dynamically.
+@function scene.newlight(number radius, vector3d position)
+@tparam number radius The radius that the light should shine
+@tparam vector3d position The position to create the light at
+@treturn iscenelight The created light
+*/
+/***
+A light.
+Lights illuminate the scene nodes arounded them based on mesh vertexes. You
+probably want to bake the lightmap instead of using light nodes.
+@class iscenelight
+@inherits iscenenode
+*/
//{} :: scene.newlight(radius, {v3 position})
static int newiscenelight(lua_State* L){
printf("Createing light!\n");
@@ -48,6 +63,12 @@ static int newiscenelight(lua_State* L){
}
+/***
+Sets the light type
+Different light types illuminate the surrounding meshes in different ways.
+@function iscenelight:settype(number type)
+@tparam number type The type the light should be
+*/
//settype(self,const)
int settype(lua_State *L){
video::E_LIGHT_TYPE type = (video::E_LIGHT_TYPE)lua_tonumber(L,-1);//self,type
@@ -60,8 +81,6 @@ int settype(lua_State *L){
}
static const luaL_reg ilight_m[] = {
- {"getpos", iscenegetpos},
- {"setpos", iscenesetpos},
{"settype", settype},
{0, 0},
};
@@ -72,8 +91,20 @@ void ilight_register(lua_State* L){
lua_pushcfunction(L,newiscenelight);//{scene},newiscenelight()
lua_setfield(L,-2,"newlight");//{scene}
+/***
+A point light
+@field scene.ELT_POINT
+*/
set_const(L,ELT_POINT);
+/***
+A spot light
+@field scene.ELT_SPOT
+*/
set_const(L,ELT_SPOT);
+/***
+A sun light
+@field scene.ELT_DIRECTIONAL
+*/
set_const(L,ELT_DIRECTIONAL);
lua_pop(L,1);//
@@ -81,6 +112,7 @@ void ilight_register(lua_State* L){
luaL_newmetatable(L,"scene.ilight");//scene.ilight
lua_newtable(L);//scene.ilight,{}
luaL_register(L, NULL, ilight_m);//scene.ilight,{}
+ luaL_register(L, NULL, igeneric_m);
lua_setfield(L,-2,"__index");//scene.ilight
lua_pop(L,1);
diff --git a/src/client/lua_api/scene/imesh.cpp b/src/client/lua_api/scene/imesh.cpp
index 8ed357c..479da15 100644
--- a/src/client/lua_api/scene/imesh.cpp
+++ b/src/client/lua_api/scene/imesh.cpp
@@ -16,9 +16,6 @@ extern "C" {
#include "igeneric.hpp"
#include <shared/lua_api/common.hpp>
-/***
-@module scene
-*/
using namespace irr;
using namespace scene;
using namespace core;
diff --git a/src/client/lua_api/video/iimage.cpp b/src/client/lua_api/video/iimage.cpp
index 4c7795d..3655b64 100644
--- a/src/client/lua_api/video/iimage.cpp
+++ b/src/client/lua_api/video/iimage.cpp
@@ -4,10 +4,6 @@
#include <shared/lua_api/common.hpp>
-/***
-@module video
-*/
-
using namespace irr;
using namespace video;
@@ -17,7 +13,7 @@ extern IVideoDriver* driver;
/***
Creates a new irrlicht image.
A newly created image will be fully white by default.
-@function newiimage(format, size)
+@function video.newiimage(format, size)
@tparam enum_color_format format The format for the image
@tparam vec2d size The size of the image
@treturn iimage The image
@@ -44,7 +40,7 @@ int newiimage(lua_State* L){
Creates a new irrlicht image.
Creates a new irrlicht image from a file. The format and width/height will be
taken from the image file.
-@function newiimagefromfile(path)
+@function video.newiimagefromfile(path)
@tparam string path The file path of the image file
@treturn iimage The loaded image
*/
@@ -138,7 +134,7 @@ int getiimagepixel(lua_State* L){
/***
Returns the dimensions of the image
@function iimage:getDimensions()
-@treturn vec2i dimensions The dimensions of the image
+@treturn vec2i The dimensions of the image
*/
//getdimensions({self})
int getiimagedimensions(lua_State *L){
@@ -162,10 +158,29 @@ void iimage_register(lua_State* L){
driver = device->getVideoDriver();
lua_getglobal(L,"video");//{}
+/***
+1 bit alpha, 5 bits red, blue, and green (16 bit)
+@field video.ECF_A1R5G5B5
+*/
set_const(L,ECF_A1R5G5B5);
+/***
+5 bit red, 6 bit green, 5 bit blue
+@field video.ECF_R5G6B5
+*/
set_const(L,ECF_R5G6B5);
+/***
+8 bit red, blue, green, and alpha
+@field video.ECF_A8R8G8B8
+*/
set_const(L,ECF_A8R8G8B8);
+/***
+1 channel with 16 bit floating point.
+1 channel 16 bit floating point. Uses the red channel. Floating point images may only be used for render targets.
+@field video.ECF_R16F
+@see @{render_targets}
+*/
set_const(L,ECF_R16F);
+//TODO: finish documenting these
set_const(L,ECF_G16R16F);
set_const(L,ECF_A16B16G16R16F);
set_const(L,ECF_R32F);
diff --git a/src/client/lua_api/video/smaterial.cpp b/src/client/lua_api/video/smaterial.cpp
index 510748c..4ed6a46 100644
--- a/src/client/lua_api/video/smaterial.cpp
+++ b/src/client/lua_api/video/smaterial.cpp
@@ -9,7 +9,15 @@ extern "C" {
using namespace irr::video;
-/*This probably needs a _gc metamethod*/
+/***
+Creates a new material.
+Creates a new material that can then be used on an @{iscenenode}
+WARNING: this item is not currently garbage collected, be careful not to make
+more smaterials than you need.
+@function video.newsmaterial()
+@treturn smaterial The new material
+*/
+/*TODO: This probably needs a _gc metamethod*/
//newsmaterial()
int newsmaterial(lua_State* L){
@@ -24,6 +32,14 @@ int newsmaterial(lua_State* L){
return 1;
}
+/***
+Sets a texture for this material.
+Sets a texture for the material on the given index. For more information on
+what each texture of a material does, see the irrlicht documentation.
+@function smaterial:settexture(index,texture)
+@tparam number index The index of the texture in the material
+@tparam itexture texture The texture to use
+*/
//setTexture(self,int_num,{ITexture texture})
int setTexture(lua_State* L){
lua_getfield(L,-1,"texture");
@@ -38,6 +54,13 @@ int setTexture(lua_State* L){
return 0;
}
+/***
+Sets a flag on this material.
+Sets the given flag on the material
+@function smaterial:setflag(flag,state)
+@tparam number flag The flag to set, see @{video} for flags.
+@tparam boolean state The state to set the flag in
+*/
//{Material},flag,state
int setFlag(lua_State* L){
int b = lua_toboolean(L,-1);//{material},flag,state
@@ -52,8 +75,8 @@ int setFlag(lua_State* L){
}
static const luaL_reg smaterial_m[] = {
- {"setTexture", setTexture},
- {"setFlag", setFlag},
+ {"settexture", setTexture},
+ {"setflag", setFlag},
{0,0},
};
@@ -73,6 +96,30 @@ void smaterial_register(lua_State* L){
lua_getglobal(L,"video");//{}
+ /***
+ A table of constants for the material class.
+ @field EMF_WIREFRAME - enable wireframe
+ @field EMF_POINTCLOUD - displays the texture as a pointcloud instead of a solid face
+ @field EMF_GOURAUD_SHADING
+ @field EMF_LIGHTING
+ @field EMF_ZBUFFER
+ @field EMF_ZWRITE_ENABLE
+ @field EMF_BACK_FACE_CULLING
+ @field EMF_FRONT_FACE_CULLING
+ @field EMF_BILINEAR_FILTER
+ @field EMF_TRILINEAR_FILTER
+ @field EMF_ANISOTROPIC_FILTER
+ @field EMF_FOG_ENABLE
+ @field EMF_NORMALIZE_NORMALS
+ @field EMF_TEXTURE_WRAP
+ @field EMF_ANTI_ALIASING
+ @field EMF_COLOR_MASK
+ @field EMF_COLOR_MATERIAL
+ @field EMF_USE_MIP_MAPS
+ @field EMF_BLEND_OPERATION
+ @field EMF_POLYGON_OFFSET
+ @table .video.
+ */
set_const(L,EMF_WIREFRAME);
set_const(L,EMF_POINTCLOUD);
set_const(L,EMF_GOURAUD_SHADING);
diff --git a/src/client/main.cpp b/src/client/main.cpp
index 98b2f61..2d93828 100644
--- a/src/client/main.cpp
+++ b/src/client/main.cpp
@@ -129,8 +129,8 @@ int main(int argc, char *argv[]){
//Create a new lua state, this gets shared everywhere
//Set the path for lua
- putenv("LUA_PATH=?.lua");
- putenv("LUA_CPATH=../bin/?.dll");
+ putenv((char*)"LUA_PATH=../data/?.lua");
+ putenv((char*)"LUA_CPATH=../bin/?.dll");
lua_State *state = luaL_newstate();
L = state;
printf("Created lua state at %p\n",L);
diff --git a/src/server/lua_api/load_io.cpp b/src/server/lua_api/load_io.cpp
index 278d7a7..0a20311 100644
--- a/src/server/lua_api/load_io.cpp
+++ b/src/server/lua_api/load_io.cpp
@@ -10,54 +10,55 @@ extern "C" {
#include <stdlib.h>
#include <dirent.h>
-#define epath "../data"
-#define epathlen sizeof(epath)
+//#define epath "../data"
+//#define epathlen sizeof(epath)
/*Add an io.dir(path) function, which lists all the files in (path)*/
-int dirpath(lua_State *L){
- if(!lua_isstring(L,-1)){
- lua_pushstring(L,"io.dir() requires a string as argument #1");
- lua_error(L);
- }
- size_t pathstrlen;
- const char *pathstr = lua_tolstring(L,-1,&pathstrlen);
- //printf("got pathstr: %s\n",pathstr);
- //char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for /
- //memcpy(tpathstr,epath,epathlen);
- //tpathstr[epathlen] = '/';
- //memcpy(tpathstr+epathlen,pathstr,pathstrlen);
- //tpathstr[pathstrlen + epathlen + 1] = '\0';
- //printf("tpathstr is: \"%s\"\n",tpathstr);
- //lua_pop(L,1);
- DIR *dir;
- struct dirent *ent;
- const char *tpathstr = pathstr;
- dir = opendir(tpathstr);
- if(dir == NULL){
- perror("Cannot open");
- lua_pushstring(L,"Failed to open directory: ");
- lua_pushstring(L,tpathstr);
- lua_concat(L,2);
- lua_error(L);
- }
- int i = 1;
- ent = readdir(dir);
- lua_newtable(L);
- while( (ent = readdir(dir)) != NULL){
- lua_pushinteger(L,i);
- lua_pushstring(L,ent->d_name);
- lua_settable(L,-3);
- i++;
- }
- closedir(dir);
- return 1;
-}
+//UPDATE: Moved to shared code
+//int dirpath(lua_State *L){
+ //if(!lua_isstring(L,-1)){
+ //lua_pushstring(L,"io.dir() requires a string as argument #1");
+ //lua_error(L);
+ //}
+ //size_t pathstrlen;
+ //const char *pathstr = lua_tolstring(L,-1,&pathstrlen);
+ ////printf("got pathstr: %s\n",pathstr);
+ ////char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for /
+ ////memcpy(tpathstr,epath,epathlen);
+ ////tpathstr[epathlen] = '/';
+ ////memcpy(tpathstr+epathlen,pathstr,pathstrlen);
+ ////tpathstr[pathstrlen + epathlen + 1] = '\0';
+ ////printf("tpathstr is: \"%s\"\n",tpathstr);
+ ////lua_pop(L,1);
+ //DIR *dir;
+ //struct dirent *ent;
+ //const char *tpathstr = pathstr;
+ //dir = opendir(tpathstr);
+ //if(dir == NULL){
+ //perror("Cannot open");
+ //lua_pushstring(L,"Failed to open directory: ");
+ //lua_pushstring(L,tpathstr);
+ //lua_concat(L,2);
+ //lua_error(L);
+ //}
+ //int i = 1;
+ //ent = readdir(dir);
+ //lua_newtable(L);
+ //while( (ent = readdir(dir)) != NULL){
+ //lua_pushinteger(L,i);
+ //lua_pushstring(L,ent->d_name);
+ //lua_settable(L,-3);
+ //i++;
+ //}
+ //closedir(dir);
+ //return 1;
+//}
void load_iofuncs(lua_State* L){
lua_getglobal(L,"io");
- lua_pushcfunction(L,dirpath);
- lua_setfield(L,-2,"dir");
+ //lua_pushcfunction(L,dirpath);
+ //lua_setfield(L,-2,"dir");
lua_pop(L,1);
}
diff --git a/src/shared/lua_api/load_common.cpp b/src/shared/lua_api/load_common.cpp
index 1eca598..188cd30 100644
--- a/src/shared/lua_api/load_common.cpp
+++ b/src/shared/lua_api/load_common.cpp
@@ -5,6 +5,13 @@ extern "C" {
#include <lauxlib.h>
#include <lualib.h>
}
+//Open group
+#include <dirent.h>//for io.dir("file/path")
+#include <sys/types.h>//required before sys/stat.h on windows
+#include <sys/stat.h>//for io.time("path/to.file")
+#include <fcntl.h>
+#include <errno.h>//For better errors
+
using namespace std::chrono;
//Gets the time
@@ -16,6 +23,45 @@ int get_time(lua_State* L){
return 1;
}
+char *epath;
+size_t epathlen;
+/*Add an io.dir(path) function, which lists all the files in (path)*/
+int dirpath(lua_State *L){
+ if(!lua_isstring(L,-1)){
+ lua_pushstring(L,"io.dir() requires a string as argument #1");
+ lua_error(L);
+ }
+ size_t pathstrlen;
+ const char *pathstr = lua_tolstring(L,-1,&pathstrlen);
+ char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for /
+ memcpy(tpathstr,epath,epathlen);
+ tpathstr[epathlen] = '/';
+ memcpy(tpathstr+epathlen+1,pathstr,pathstrlen);
+ tpathstr[pathstrlen + epathlen + 1] = '\0';
+ lua_pop(L,1);
+ DIR *dir;
+ struct dirent *ent;
+ dir = opendir(tpathstr);
+ if(dir == NULL){
+ perror("Cannot open");
+ lua_pushstring(L,"Failed to open directory: ");
+ lua_pushstring(L,tpathstr);
+ lua_concat(L,2);
+ lua_error(L);
+ }
+ int i = 1;
+ ent = readdir(dir);
+ lua_newtable(L);
+ while( (ent = readdir(dir)) != NULL){
+ lua_pushinteger(L,i);
+ lua_pushstring(L,ent->d_name);
+ lua_settable(L,-3);
+ i++;
+ }
+ closedir(dir);
+ return 1;
+}
+
void loadCommonLibs(lua_State* L){
lua_getglobal(L,"GAME");
lua_pushcfunction(L,make_crashy);
@@ -23,6 +69,11 @@ void loadCommonLibs(lua_State* L){
lua_pop(L,1);
lua_pushcfunction(L,get_time);
lua_setglobal(L,"get_time");
+
+ lua_getglobal(L,"io");
+ lua_pushcfunction(L,dirpath);
+ lua_setfield(L,-2,"dir");
+ lua_pop(L,1);
}
void gameloop_common(lua_State* L){
diff --git a/src/shared/lua_api/load_net.cpp b/src/shared/lua_api/load_net.cpp
index b377cc5..bff55cf 100644
--- a/src/shared/lua_api/load_net.cpp
+++ b/src/shared/lua_api/load_net.cpp
@@ -1,11 +1,11 @@
-/***
+/*
+TODO:Fix documentation or find a better home for this example code.
The net library
Exposes various structs, constants, and functions for passing messages
A list of protocols that can be used when creating sockets.
The number values below are only for refrence. You should use net.PAIR, net.BUS,
ect.
-@module net
@usage
--Server
local s = net.newsocket(net.REP)
@@ -67,7 +67,7 @@ extern "C" {
/***
1 to 1 protocol.
-@field PAIR 1
+@field net.PAIR
*/
#define PAIR 1
@@ -75,63 +75,63 @@ extern "C" {
Many to many protocol.
When this socket sends messages, it does not receive a copy of the message
it just sent.
-@field BUS 2
+@field net.BUS
*/
#define BUS 2
/***
Publish protocol.
The first half of the pub/sub protocol.
-@field PUB 3
+@field net.PUB
*/
#define PUB 3
/***
Subscribe protocol
The second half of the pub/sub protocol.
-@field SUB 4
+@field net.SUB
*/
#define SUB 4
/***
Pull protocol.
The first half of the push/pull protocol.
-@field PULL 5
+@field net.PULL
*/
#define PULL 5
/***
Push protocol.
The second half of the push/pull protocol.
-@field PUSH 6
+@field net.PUSH
*/
#define PUSH 6
/***
Request protocol.
The first half of the request/reply protocol.
-@field REQ 7
+@field net.REQ
*/
#define REQ 7
/***
Reply protocol.
The second half of the request/reply protocol.
-@field REP 8
+@field net.REP
*/
#define REP 8
/***
Respond protocol.
The second half of the survey/respond protocol.
-@field RESPOND 9
+@field net.RESPOND
*/
#define RESPOND 9
/***
Survey protocol.
The first half of the survey/respond protocol.
-@field SURVEY 10
+@field net.SURVEY
*/
#define SURVEY 10
@@ -597,8 +597,8 @@ int netclose(lua_State* L){//{socket}
}
/***
-@field fd
-@table net.socket
+The opaque socket descriptor for this socket.
+@field socket.fd The descriptor
@domain shared
*/
diff --git a/src/shared/lua_api/phys/bcollider.cpp b/src/shared/lua_api/phys/bcollider.cpp
index 91c34fd..caefd3e 100644
--- a/src/shared/lua_api/phys/bcollider.cpp
+++ b/src/shared/lua_api/phys/bcollider.cpp
@@ -1,3 +1,10 @@
+/*
+A wrapper for the btCollisionObject class.
+Most of the methods that bullet exposes for the btCollisionObject are wrapped
+here, any subclass of btCollisionObject should register methods defined
+here in it's metatable's __index.
+*/
+
extern "C" {
#include <lua.h>
#include <lauxlib.h>
diff --git a/src/shared/lua_api/phys/bghostobject.cpp b/src/shared/lua_api/phys/bghostobject.cpp
index 63f790c..5657b5f 100644
--- a/src/shared/lua_api/phys/bghostobject.cpp
+++ b/src/shared/lua_api/phys/bghostobject.cpp
@@ -109,7 +109,7 @@ int bghostconvexsweep(lua_State *L){
btVector3 hw, hn;
hw = cb->m_hitPointWorld;
hn = cb->m_hitNormalWorld;
- btCollisionObject *co = cb->m_hitCollisionObject;
+ const btCollisionObject *co = cb->m_hitCollisionObject;
lua_newtable(L);//{}
lua_pushboolean(L,cb->hasHit() ? 1 : 0);
@@ -118,12 +118,17 @@ int bghostconvexsweep(lua_State *L){
lua_setfield(L,-2,"pos");
pushvector3d(L,hn.x(),hn.y(),hn.z());
lua_setfield(L,-2,"normal");
+
lua_getglobal(L,"phys");//{},{phys}
lua_getfield(L,-1,"colliders");//{},{phys},{phys.colliders}
- lua_pushlightuserdata(L,co);//{},{phys},{phys.colliders},ud_collisionobject
- lua_gettable(L,-2);//{},{phys},{phys.colliders},ud_collisionobject,{rb} or nil
- lua_setfield(L,-5,"what");//{},{phys},{phys.colliders},ud_collisionobject
- lua_pop(L,3);//{}
+ lua_pushlightuserdata(L,(void*)co);//{},{phys},{phys.colliders},ud_collisionobject
+ lua_gettable(L,-2);//{},{phys},{phys.colliders},{rb} or nil
+ if(lua_isnil(L,-1)){
+ lua_pop(L,3);//{}
+ }else{
+ lua_setfield(L,-4,"what");//{},{phys},{phys.colliders}
+ lua_pop(L,2);//{}
+ }
delete cb;
return 1;
diff --git a/src/shared/lua_api/phys/bphysbox.cpp b/src/shared/lua_api/phys/bphysbox.cpp
index 569f3f9..66f112d 100644
--- a/src/shared/lua_api/phys/bphysbox.cpp
+++ b/src/shared/lua_api/phys/bphysbox.cpp
@@ -107,7 +107,7 @@ int newbphysbox(lua_State* L){
//Set it's metatable
luaL_getmetatable(L, "phys.physbox");//{},{phys.physbox}
lua_setmetatable(L, -2);//{}
-
+
return 1;
}
diff --git a/src/shared/lua_api/phys/bphysgeneric.cpp b/src/shared/lua_api/phys/bphysgeneric.cpp
index 4500ce0..eed9112 100644
--- a/src/shared/lua_api/phys/bphysgeneric.cpp
+++ b/src/shared/lua_api/phys/bphysgeneric.cpp
@@ -8,11 +8,6 @@ extern "C" {
#include <shared/lua_api/common.hpp>
#include <shared/phys/physcommon.hpp>
-/***
-@module phys
-*/
-
-
/*Physics things from lua have the form of:
{
type = "rigidbody"
@@ -243,6 +238,7 @@ int applyimpulse(lua_State *L){
popvector3d(L,&x,&y,&z);
btRigidBody *r = popRigidBody(L);
r->applyImpulse(btVector3(x,y,z),btVector3(ox,oy,oz));
+ r->activate();
return 0;
}
@@ -265,6 +261,14 @@ int setrotation(lua_State *L){
return 0;
}
+//rigidbody:getmass() :: number
+int getmass(lua_State *L){
+ btRigidBody *r = popRigidBody(L);
+ double m = r->getMass();
+ lua_pushnumber(L,m);
+ return 1;
+}
+
/*
@@ -310,6 +314,7 @@ extern const luaL_reg brigidbody_m[] = {
{"setangfactor", setangfactor},
{"setflags", setflags},
{"setrotation", setrotation},
+ {"getmass", getmass},
//{"testcontact", testcontact},
{NULL, NULL}
};
diff --git a/src/shared/lua_api/phys/bphysmodel.cpp b/src/shared/lua_api/phys/bphysmodel.cpp
index 0c8e3bf..375d68b 100644
--- a/src/shared/lua_api/phys/bphysmodel.cpp
+++ b/src/shared/lua_api/phys/bphysmodel.cpp
@@ -24,6 +24,10 @@ extern "C" {
extern btDiscreteDynamicsWorld* World;
extern std::list<btRigidBody*> Objects;
+//btRigidBody* load_obj(tinyobj_attrib_t attrib, tinyobj_shape_t *shapes, size_t num){
+ //btTriangleMesh *trimesh = new btTriangleMesh();
+//}
+
//TODO: This will break in the future, see github.com/syoyo/tinyobjloader-c/issues/16
//"physicfile",mass[,position][,lookat] :: ud_rigidbody
void makebphysmodel(lua_State *L){
@@ -67,6 +71,9 @@ void makebphysmodel(lua_State *L){
if(err != TINYOBJ_SUCCESS){
printf("Tinyobj failed to load model:%s\n",ppath);
}
+ //for(size_t s = 0; s < meshcount; s++){
+ //btRigidBody *rb = load_obj(attrib,shapes,s);
+ //}
//u32 meshcount = pmesh->getMeshBufferCount();
//__mingw_printf("attrib.num_vertices: %u\n",attrib.num_vertices);
//__mingw_printf("attrib.num_faces: %u\n",attrib.num_faces);
@@ -81,7 +88,7 @@ void makebphysmodel(lua_State *L){
float v2 = vs[1];
float v3 = vs[2];
vertexes[i] = btVector3(v1,v2,v3);
- printf("Adding vertex %lld at (%f,%f,%f)\n",i,v1,v2,v3);
+ //printf("Adding vertex %lld at (%f,%f,%f)\n",i,v1,v2,v3);
}
//printf("Finished finding or adding vertexes\n");
for(size_t i = 0; i < attrib.num_faces - 1; i+= 3){ //0 - y to num_faces - 1
@@ -94,14 +101,14 @@ void makebphysmodel(lua_State *L){
v2 = vertexes[i2.v_idx];
v3 = vertexes[i3.v_idx];
trimesh->addTriangle(vertexes[i1.v_idx],vertexes[i2.v_idx],vertexes[i3.v_idx],false);//Some triangles are "the wrong way round",
- printf("Adding triangle:(%d,%d,%d)\n",i1.v_idx,i2.v_idx,i3.v_idx);
- //trimesh->addTriangle(vertexes[i3.v_idx],vertexes[i2.v_idx],vertexes[i1.v_idx],true);//double-side all triangles
+ //printf("Adding triangle:(%d,%d,%d)\n",i1.v_idx,i2.v_idx,i3.v_idx);
+ trimesh->addTriangle(vertexes[i3.v_idx],vertexes[i2.v_idx],vertexes[i1.v_idx],true);//double-side all triangles
}
//printf("Finished adding triangle indicies\n");
//printf("Done building trimesh\n");
- //btGImpactShapeInterface *shape = new btGImpactMeshShape(trimesh);
- btConvexTriangleMeshShape *shape = new btConvexTriangleMeshShape(trimesh);
- //shape->updateBound();
+ //btConvexTriangleMeshShape *shape = new btConvexTriangleMeshShape(trimesh);
+ btGImpactShapeInterface *shape = new btGImpactMeshShape(trimesh);
+ shape->updateBound();
//btCollisionShape *shape = new btBvhTriangleMeshShape(trimesh,true);
btTransform tr;
tr.setIdentity();