diff options
author | Robert Vollmert <rvollmert@gmx.net> | 2009-10-19 23:38:08 +0200 |
---|---|---|
committer | Robert Vollmert <rvollmert@gmx.net> | 2009-10-20 00:44:30 +0200 |
commit | fac213f26779fde815580d9c06ea3db367f50942 (patch) | |
tree | 417beb6d0db403567f626be78455e59565d5a093 /crawl-ref/source | |
parent | 725154d095f6ff449d16597201294b7fe99dd215 (diff) | |
download | crawl-ref-fac213f26779fde815580d9c06ea3db367f50942.tar.gz crawl-ref-fac213f26779fde815580d9c06ea3db367f50942.zip |
Split out builder functions from dlua.cc.
Also minor cleanup.
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/dlua.cc | 222 | ||||
-rw-r--r-- | crawl-ref/source/l_dgn_bf.cc | 225 | ||||
-rw-r--r-- | crawl-ref/source/l_dgnevt.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/l_libs.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/makefile.obj | 1 |
5 files changed, 233 insertions, 222 deletions
diff --git a/crawl-ref/source/dlua.cc b/crawl-ref/source/dlua.cc index c61cd50450..3fbb628d77 100644 --- a/crawl-ref/source/dlua.cc +++ b/crawl-ref/source/dlua.cc @@ -11,7 +11,6 @@ #include "dlua.h" #include "l_libs.h" -#include "mapdef.h" #include "tags.h" template <typename list, typename lpush> @@ -303,225 +302,6 @@ void luaopen_setmeta(lua_State *ls, lua_settable(ls, -3); } -static void luaopen_dgnevent(lua_State *ls) -{ - luaopen_setmeta(ls, "dgnevent", dgnevent_lib, DEVENT_METATABLE); -} - -// Return the integer stored in the table (on the stack) with the key name. -// If the key doesn't exist or the value is the wrong type, return defval. -static int _table_int(lua_State *ls, int idx, const char *name, int defval) -{ - lua_pushstring(ls, name); - lua_gettable(ls, idx < 0 ? idx - 1 : idx); - bool nil = lua_isnil(ls, idx); - bool valid = lua_isnumber(ls, idx); - if (!nil && !valid) - luaL_error(ls, "'%s' in table, but not an int.", name); - int ret = (!nil && valid ? lua_tonumber(ls, idx) : defval); - lua_pop(ls, 1); - return (ret); -} - -// Return the character stored in the table (on the stack) with the key name. -// If the key doesn't exist or the value is the wrong type, return defval. -static char _table_char(lua_State *ls, int idx, const char *name, char defval) -{ - lua_pushstring(ls, name); - lua_gettable(ls, idx < 0 ? idx - 1 : idx); - bool nil = lua_isnil(ls, idx); - bool valid = lua_isstring(ls, idx); - if (!nil && !valid) - luaL_error(ls, "'%s' in table, but not a string.", name); - - char ret = defval; - if (!nil && valid) - { - const char *str = lua_tostring(ls, idx); - if (str[0] && !str[1]) - ret = str[0]; - else - luaL_error(ls, "'%s' has more than one character.", name); - } - lua_pop(ls, 1); - return (ret); -} - -// Return the string stored in the table (on the stack) with the key name. -// If the key doesn't exist or the value is the wrong type, return defval. -static const char* _table_str(lua_State *ls, int idx, const char *name, const char *defval) -{ - lua_pushstring(ls, name); - lua_gettable(ls, idx < 0 ? idx - 1 : idx); - bool nil = lua_isnil(ls, idx); - bool valid = lua_isstring(ls, idx); - if (!nil && !valid) - luaL_error(ls, "'%s' in table, but not a string.", name); - const char *ret = (!nil && valid ? lua_tostring(ls, idx) : defval); - lua_pop(ls, 1); - return (ret); -} - -// Return the boolean stored in the table (on the stack) with the key name. -// If the key doesn't exist or the value is the wrong type, return defval. -static bool _table_bool(lua_State *ls, int idx, const char *name, bool defval) -{ - lua_pushstring(ls, name); - lua_gettable(ls, idx < 0 ? idx - 1 : idx); - bool nil = lua_isnil(ls, idx); - bool valid = lua_isboolean(ls, idx); - if (!nil && !valid) - luaL_error(ls, "'%s' in table, but not a bool.", name); - bool ret = (!nil && valid ? lua_toboolean(ls, idx) : defval); - lua_pop(ls, 1); - return (ret); -} - -#define BF_INT(ls, val, def) int val = _table_int(ls, -1, #val, def); -#define BF_CHAR(ls, val, def) char val = _table_char(ls, -1, #val, def); -#define BF_STR(ls, val, def) const char *val = _table_str(ls, -1, #val, def); -#define BF_BOOL(ls, val, def) bool val = _table_bool(ls, -1, #val, def); - -static void bf_octa_room(lua_State *ls, map_lines &lines) -{ - int default_oblique = std::min(lines.width(), lines.height()) / 2 - 1; - BF_INT(ls, oblique, default_oblique); - BF_CHAR(ls, outside, 'x'); - BF_CHAR(ls, inside, '.'); - BF_STR(ls, replace, "."); - - coord_def tl, br; - if (!lines.find_bounds(replace, tl, br)) - return; - - for (rectangle_iterator ri(tl, br); ri; ++ri) - { - const coord_def mc = *ri; - char glyph = lines(mc); - if (replace[0] && !strchr(replace, glyph)) - continue; - - int ob = 0; - ob += std::max(oblique + tl.x - mc.x, 0); - ob += std::max(oblique + mc.x - br.x, 0); - - bool is_inside = (mc.y >= tl.y + ob && mc.y <= br.y - ob); - lines(mc) = is_inside ? inside : outside; - } -} - -static void bf_smear(lua_State *ls, map_lines &lines) -{ - BF_INT(ls, iterations, 1); - BF_CHAR(ls, smear, 'x'); - BF_STR(ls, onto, "."); - BF_BOOL(ls, boxy, false); - - const int max_test_per_iteration = 10; - int sanity = 0; - int max_sanity = iterations * max_test_per_iteration; - - for (int i = 0; i < iterations; i++) - { - bool diagonals, straights; - coord_def mc; - - do - { - do - { - sanity++; - mc.x = random_range(1, lines.width() - 2); - mc.y = random_range(1, lines.height() - 2); - } - while (onto[0] && !strchr(onto, lines(mc))); - - // Prevent too many iterations. - if (sanity > max_sanity) - return; - - // Is there a "smear" feature along the diagonal from mc? - diagonals = lines(coord_def(mc.x+1, mc.y+1)) == smear || - lines(coord_def(mc.x-1, mc.y+1)) == smear || - lines(coord_def(mc.x-1, mc.y-1)) == smear || - lines(coord_def(mc.x+1, mc.y-1)) == smear; - - // Is there a "smear" feature up, down, left, or right from mc? - straights = lines(coord_def(mc.x+1, mc.y)) == smear || - lines(coord_def(mc.x-1, mc.y)) == smear || - lines(coord_def(mc.x, mc.y+1)) == smear || - lines(coord_def(mc.x, mc.y-1)) == smear; - } - while (!straights && (boxy || !diagonals)); - - lines(mc) = smear; - } -} - -static void bf_extend(lua_State *ls, map_lines &lines) -{ - BF_INT(ls, height, 1); - BF_INT(ls, width, 1); - BF_CHAR(ls, fill, 'x'); - - lines.extend(width, height, fill); -} - -typedef void (*bf_func)(lua_State *ls, map_lines &lines); -struct bf_entry -{ - const char* name; - bf_func func; -}; - -// Create a separate list of builder funcs so that we can automatically -// generate a list of closures for them, rather than individually -// and explicitly exposing them to the dgn namespace. -static struct bf_entry bf_map[] = -{ - { "map_octa_room", &bf_octa_room }, - { "map_smear", &bf_smear }, - { "map_extend", &bf_extend } -}; - -static int dgn_call_builder_func(lua_State *ls) -{ - // This function gets called for all the builder functions that - // operate on map_lines. - - MAP(ls, 1, map); - if (!lua_istable(ls, 2) && !lua_isfunction(ls, 2)) - return luaL_argerror(ls, 2, "Expected table"); - - bf_func *func = (bf_func *)lua_topointer(ls, lua_upvalueindex(1)); - if (!func) - return luaL_error(ls, "Expected C function in closure upval"); - - // Put the table on top. - lua_settop(ls, 2); - - // Call the builder func itself. - (*func)(ls, map->map); - - return (0); -} - -static void _register_builder_funcs(lua_State *ls) -{ - lua_getglobal(ls, "dgn"); - - const size_t num_entries = sizeof(bf_map) / sizeof(bf_entry); - for (size_t i = 0; i < num_entries; i++) - { - // Push a closure with the C function into the dgn table. - lua_pushlightuserdata(ls, &bf_map[i].func); - lua_pushcclosure(ls, &dgn_call_builder_func, 1); - lua_setfield(ls, -2, bf_map[i].name); - } - - lua_pop(ls, 1); -} - void init_dungeon_lua() { lua_stack_cleaner clean(dlua); @@ -544,7 +324,7 @@ void init_dungeon_lua() luaopen_mapmarker(dlua); luaopen_ray(dlua); - _register_builder_funcs(dlua); + register_builder_funcs(dlua); register_mapdef_tables(dlua); } diff --git a/crawl-ref/source/l_dgn_bf.cc b/crawl-ref/source/l_dgn_bf.cc new file mode 100644 index 0000000000..ac7fd04a42 --- /dev/null +++ b/crawl-ref/source/l_dgn_bf.cc @@ -0,0 +1,225 @@ +/* + * File: l_dgnbf.cc + * Summary: Dungeon lua builder functions. + */ + +#include "AppHdr.h" + +#include "dlua.h" +#include "l_libs.h" + +#include "mapdef.h" + +// Return the integer stored in the table (on the stack) with the key name. +// If the key doesn't exist or the value is the wrong type, return defval. +static int _table_int(lua_State *ls, int idx, const char *name, int defval) +{ + lua_pushstring(ls, name); + lua_gettable(ls, idx < 0 ? idx - 1 : idx); + bool nil = lua_isnil(ls, idx); + bool valid = lua_isnumber(ls, idx); + if (!nil && !valid) + luaL_error(ls, "'%s' in table, but not an int.", name); + int ret = (!nil && valid ? lua_tonumber(ls, idx) : defval); + lua_pop(ls, 1); + return (ret); +} + +// Return the character stored in the table (on the stack) with the key name. +// If the key doesn't exist or the value is the wrong type, return defval. +static char _table_char(lua_State *ls, int idx, const char *name, char defval) +{ + lua_pushstring(ls, name); + lua_gettable(ls, idx < 0 ? idx - 1 : idx); + bool nil = lua_isnil(ls, idx); + bool valid = lua_isstring(ls, idx); + if (!nil && !valid) + luaL_error(ls, "'%s' in table, but not a string.", name); + + char ret = defval; + if (!nil && valid) + { + const char *str = lua_tostring(ls, idx); + if (str[0] && !str[1]) + ret = str[0]; + else + luaL_error(ls, "'%s' has more than one character.", name); + } + lua_pop(ls, 1); + return (ret); +} + +// Return the string stored in the table (on the stack) with the key name. +// If the key doesn't exist or the value is the wrong type, return defval. +static const char* _table_str(lua_State *ls, int idx, const char *name, const char *defval) +{ + lua_pushstring(ls, name); + lua_gettable(ls, idx < 0 ? idx - 1 : idx); + bool nil = lua_isnil(ls, idx); + bool valid = lua_isstring(ls, idx); + if (!nil && !valid) + luaL_error(ls, "'%s' in table, but not a string.", name); + const char *ret = (!nil && valid ? lua_tostring(ls, idx) : defval); + lua_pop(ls, 1); + return (ret); +} + +// Return the boolean stored in the table (on the stack) with the key name. +// If the key doesn't exist or the value is the wrong type, return defval. +static bool _table_bool(lua_State *ls, int idx, const char *name, bool defval) +{ + lua_pushstring(ls, name); + lua_gettable(ls, idx < 0 ? idx - 1 : idx); + bool nil = lua_isnil(ls, idx); + bool valid = lua_isboolean(ls, idx); + if (!nil && !valid) + luaL_error(ls, "'%s' in table, but not a bool.", name); + bool ret = (!nil && valid ? lua_toboolean(ls, idx) : defval); + lua_pop(ls, 1); + return (ret); +} + +#define BF_INT(ls, val, def) int val = _table_int(ls, -1, #val, def); +#define BF_CHAR(ls, val, def) char val = _table_char(ls, -1, #val, def); +#define BF_STR(ls, val, def) const char *val = _table_str(ls, -1, #val, def); +#define BF_BOOL(ls, val, def) bool val = _table_bool(ls, -1, #val, def); + +static void bf_octa_room(lua_State *ls, map_lines &lines) +{ + int default_oblique = std::min(lines.width(), lines.height()) / 2 - 1; + BF_INT(ls, oblique, default_oblique); + BF_CHAR(ls, outside, 'x'); + BF_CHAR(ls, inside, '.'); + BF_STR(ls, replace, "."); + + coord_def tl, br; + if (!lines.find_bounds(replace, tl, br)) + return; + + for (rectangle_iterator ri(tl, br); ri; ++ri) + { + const coord_def mc = *ri; + char glyph = lines(mc); + if (replace[0] && !strchr(replace, glyph)) + continue; + + int ob = 0; + ob += std::max(oblique + tl.x - mc.x, 0); + ob += std::max(oblique + mc.x - br.x, 0); + + bool is_inside = (mc.y >= tl.y + ob && mc.y <= br.y - ob); + lines(mc) = is_inside ? inside : outside; + } +} + +static void bf_smear(lua_State *ls, map_lines &lines) +{ + BF_INT(ls, iterations, 1); + BF_CHAR(ls, smear, 'x'); + BF_STR(ls, onto, "."); + BF_BOOL(ls, boxy, false); + + const int max_test_per_iteration = 10; + int sanity = 0; + int max_sanity = iterations * max_test_per_iteration; + + for (int i = 0; i < iterations; i++) + { + bool diagonals, straights; + coord_def mc; + + do + { + do + { + sanity++; + mc.x = random_range(1, lines.width() - 2); + mc.y = random_range(1, lines.height() - 2); + } + while (onto[0] && !strchr(onto, lines(mc))); + + // Prevent too many iterations. + if (sanity > max_sanity) + return; + + // Is there a "smear" feature along the diagonal from mc? + diagonals = lines(coord_def(mc.x+1, mc.y+1)) == smear || + lines(coord_def(mc.x-1, mc.y+1)) == smear || + lines(coord_def(mc.x-1, mc.y-1)) == smear || + lines(coord_def(mc.x+1, mc.y-1)) == smear; + + // Is there a "smear" feature up, down, left, or right from mc? + straights = lines(coord_def(mc.x+1, mc.y)) == smear || + lines(coord_def(mc.x-1, mc.y)) == smear || + lines(coord_def(mc.x, mc.y+1)) == smear || + lines(coord_def(mc.x, mc.y-1)) == smear; + } + while (!straights && (boxy || !diagonals)); + + lines(mc) = smear; + } +} + +static void bf_extend(lua_State *ls, map_lines &lines) +{ + BF_INT(ls, height, 1); + BF_INT(ls, width, 1); + BF_CHAR(ls, fill, 'x'); + + lines.extend(width, height, fill); +} + +typedef void (*bf_func)(lua_State *ls, map_lines &lines); +struct bf_entry +{ + const char* name; + bf_func func; +}; + +// Create a separate list of builder funcs so that we can automatically +// generate a list of closures for them, rather than individually +// and explicitly exposing them to the dgn namespace. +static struct bf_entry bf_map[] = +{ + { "map_octa_room", &bf_octa_room }, + { "map_smear", &bf_smear }, + { "map_extend", &bf_extend } +}; + +static int dgn_call_builder_func(lua_State *ls) +{ + // This function gets called for all the builder functions that + // operate on map_lines. + + MAP(ls, 1, map); + if (!lua_istable(ls, 2) && !lua_isfunction(ls, 2)) + return luaL_argerror(ls, 2, "Expected table"); + + bf_func *func = (bf_func *)lua_topointer(ls, lua_upvalueindex(1)); + if (!func) + return luaL_error(ls, "Expected C function in closure upval"); + + // Put the table on top. + lua_settop(ls, 2); + + // Call the builder func itself. + (*func)(ls, map->map); + + return (0); +} + +void register_builder_funcs(lua_State *ls) +{ + lua_getglobal(ls, "dgn"); + + const size_t num_entries = sizeof(bf_map) / sizeof(bf_entry); + for (size_t i = 0; i < num_entries; i++) + { + // Push a closure with the C function into the dgn table. + lua_pushlightuserdata(ls, &bf_map[i].func); + lua_pushcclosure(ls, &dgn_call_builder_func, 1); + lua_setfield(ls, -2, bf_map[i].name); + } + + lua_pop(ls, 1); +} diff --git a/crawl-ref/source/l_dgnevt.cc b/crawl-ref/source/l_dgnevt.cc index 8247b1fb1d..875c90b467 100644 --- a/crawl-ref/source/l_dgnevt.cc +++ b/crawl-ref/source/l_dgnevt.cc @@ -56,3 +56,7 @@ const struct luaL_reg dgnevent_lib[] = { NULL, NULL } }; +void luaopen_dgnevent(lua_State *ls) +{ + luaopen_setmeta(ls, "dgnevent", dgnevent_lib, DEVENT_METATABLE); +} diff --git a/crawl-ref/source/l_libs.h b/crawl-ref/source/l_libs.h index edbd863d6a..2db0b02816 100644 --- a/crawl-ref/source/l_libs.h +++ b/crawl-ref/source/l_libs.h @@ -13,9 +13,10 @@ extern const struct luaL_reg los_lib[]; extern const struct luaL_reg mapmarker_lib[]; extern const struct luaL_reg you_lib[]; +void luaopen_dgnevent(lua_State *ls); void luaopen_mapmarker(lua_State *ls); void luaopen_ray(lua_State *ls); void register_mapdef_tables(lua_State *ls); +void register_builder_funcs(lua_State *ls); - diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 7f4bbc23ac..fadd7505e1 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -40,6 +40,7 @@ lev-pand.o \ libutil.o \ l_crawl.o \ l_dgn.o \ +l_dgn_bf.o \ l_dgnevt.o \ l_file.o \ l_los.o \ |