1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include "AppHdr.h"
#include "clua.h"
#include "l_libs.h"
#include "options.h"
////////////////////////////////////////////////////////////////
// Option handling
typedef int (*ohandler)(lua_State *ls, const char *name, void *data, bool get);
struct option_handler
{
const char *option;
void *data;
ohandler handler;
};
static int option_hboolean(lua_State *ls, const char *name, void *data,
bool get)
{
if (get)
{
lua_pushboolean(ls, *static_cast<bool*>( data ));
return (1);
}
else
{
if (lua_isboolean(ls, 3))
*static_cast<bool*>( data ) = lua_toboolean(ls, 3);
return (0);
}
}
static option_handler handlers[] =
{
// Boolean options come first
{ "easy_open", &Options.easy_open, option_hboolean },
{ "colour_map", &Options.colour_map, option_hboolean },
{ "clean_map", &Options.clean_map, option_hboolean },
{ "show_uncursed", &Options.show_uncursed, option_hboolean },
{ "easy_open", &Options.easy_open, option_hboolean },
{ "easy_armour", &Options.easy_unequip, option_hboolean },
{ "easy_unequip", &Options.easy_unequip, option_hboolean },
{ "easy_butcher", &Options.easy_butcher, option_hboolean },
{ "always_confirm_butcher", &Options.always_confirm_butcher, option_hboolean },
{ "default_target", &Options.default_target, option_hboolean },
{ "autopickup_no_burden", &Options.autopickup_no_burden, option_hboolean },
{ "note_skill_max", &Options.note_skill_max, option_hboolean },
{ "clear_messages", &Options.clear_messages, option_hboolean },
{ "no_dark_brand", &Options.no_dark_brand, option_hboolean },
{ "auto_list", &Options.auto_list, option_hboolean },
{ "pickup_thrown", &Options.pickup_thrown, option_hboolean },
{ "pickup_dropped", &Options.pickup_dropped, option_hboolean },
{ "show_waypoints", &Options.show_waypoints, option_hboolean },
{ "item_colour", &Options.item_colour, option_hboolean },
{ "easy_exit_menu", &Options.easy_exit_menu, option_hboolean },
{ "dos_use_background_intensity", &Options.dos_use_background_intensity,
option_hboolean },
{ "menu_colour_prefix_class", &Options.menu_colour_prefix_class,
option_hboolean }
};
static const option_handler *get_handler(const char *optname)
{
if (optname)
{
for (int i = 0, count = sizeof(handlers) / sizeof(*handlers);
i < count; ++i)
{
if (!strcmp(handlers[i].option, optname))
return &handlers[i];
}
}
return (NULL);
}
static int option_get(lua_State *ls)
{
const char *opt = luaL_checkstring(ls, 2);
if (!opt)
return (0);
// Is this a Lua named option?
game_options::opt_map::iterator i = Options.named_options.find(opt);
if (i != Options.named_options.end())
{
const std::string &ov = i->second;
lua_pushstring(ls, ov.c_str());
return (1);
}
const option_handler *oh = get_handler(opt);
if (oh)
return (oh->handler(ls, opt, oh->data, true));
return (0);
}
static int option_set(lua_State *ls)
{
const char *opt = luaL_checkstring(ls, 2);
if (!opt)
return (0);
const option_handler *oh = get_handler(opt);
if (oh)
oh->handler(ls, opt, oh->data, false);
return (0);
}
#define OPT_METATABLE "clua_metatable_optaccess"
void cluaopen_options(lua_State *ls)
{
int top = lua_gettop(ls);
luaL_newmetatable(ls, OPT_METATABLE);
lua_pushstring(ls, "__index");
lua_pushcfunction(ls, option_get);
lua_settable(ls, -3);
luaL_getmetatable(ls, OPT_METATABLE);
lua_pushstring(ls, "__newindex");
lua_pushcfunction(ls, option_set);
lua_settable(ls, -3);
lua_settop(ls, top);
// Create dummy userdata to front for our metatable
int *dummy = static_cast<int *>( lua_newuserdata(ls, sizeof(int)) );
// Mystic number
*dummy = 42;
luaL_getmetatable(ls, OPT_METATABLE);
lua_setmetatable(ls, -2);
lua_setglobal(ls, "options");
}
|