Okay, this is quite a bit of code, well commented. (But I skipped on the error checking part, for clarity.) I also made a stack dump function, so you can visualize the stack is the code progresses. It looks like a lot (it is), but without the comments it's actually not too bad.
It's hard to see the actual output with the stack dumping in the way, so disable it to see that the code works and such, but then use it to understand how the stack manipulations work.
This code assumes your file format is the same as the example you gave in your OP. It checks the size of the table, so you can add as many definitions as you want. like I said, I didn't add error checking so if the format is wrong or whatever, you're on your own
Also, this program just prints the screen definitions to console, you can of course store them in a structure/class and store them in a `std::vector`, etc.
Code:
#include <lua\lua.hpp>
#include <iostream>
// uncomment this to do stack dumps
//#define DO_STACK_DUMP
// optional stack dump mischief
#ifdef DO_STACK_DUMP
void stack_dump(lua_State *stack); // forward declare
#define STACK_DUMP stack_dump(config); (void)0
#else
#define STACK_DUMP (void)0
#endif
int main(void)
{
// open state
lua_State *config;
config = lua_open();
// load file
luaL_loadfile( config, "config.lua");
lua_pcall(config, 0, 0, 0);
// push the table onto the stack
lua_getglobal(config, "ScreenDefs");
STACK_DUMP;
// get number of elements in the table
unsigned tableSize = lua_objlen(config, -1);
// now get each definition
for (unsigned i = 1; i <= tableSize; ++i)
{
// push which field we want to grab.
// in lua, you can have indices of any
// type. these are integer indices.
lua_pushinteger(config, i);
STACK_DUMP;
// now get data from the table
// lua will use the value from the top
// to get data from the table 2 spots from the top
lua_gettable(config, -2);
STACK_DUMP;
// get table replaces the index of the table by its value.
// the top of the stack is now the value of ScreenDefs[i],
// and the integer we pushed has been replaced by it.
// this is another table, except unnamed. it has the fields
// `width`, `height`, and `fullscreen`.
// now perform the same operations to get those values.
// push the name of the field we want to grab:
lua_pushstring(config, "width");
STACK_DUMP;
// get the data from the table
// -2 this time refers to the new table.
// (ScreenDef's is now at position -3)
lua_gettable(config, -2);
STACK_DUMP;
// the top is now the value of "width" in the table
int width = lua_tointeger(config, -1);
std::cout << "Width: " << width << " ";
// remove it, so we can get the height
lua_pop(config, 1);
STACK_DUMP;
// get the height
lua_pushstring(config, "height");
STACK_DUMP;
// get the data associated with it
lua_gettable(config, -2);
STACK_DUMP;
// the top is now the value of "height" in the table
int height = lua_tointeger(config, -1);
std::cout << "Height: " << height << " ";
// remove it, so we can get fullscreen
lua_pop(config, 1);
STACK_DUMP;
// get fullscreen
lua_pushstring(config, "fullscreen");
STACK_DUMP;
// get the data associated with it
lua_gettable(config, -2);
STACK_DUMP;
// the top is now the value of "fullscreen" in the table
bool fullscreen = lua_toboolean(config, -1) != 0;
std::cout << "Fullscreen: " << fullscreen << " ";
// pop away the value
lua_pop(config, 1);
STACK_DUMP;
// pop the unnamed table away, leaving only
// the ScreenDef table, ready for the next iteration
lua_pop(config, 1);
STACK_DUMP;
// (note, the last two pops could be combined into just:
// `lua_pop(config, 2)`.
std::cout << std::endl;
}
// pop the global table away,
// finishing up the stack
lua_pop(config, 1);
STACK_DUMP;
// clean up
lua_close(config);
return 0;
}
void stack_dump(lua_State *stack)
{
int stackSize = lua_gettop(stack);
std::cout << "Stack Dump: " << std::endl;
for (int i = stackSize; i > 0; --i)
{
int absoluteIndex = i;
int relativeIndex = stackSize - i + 1;
std::cout << "Index[" << absoluteIndex << " / -" << relativeIndex << "] = ";
int type = lua_type(stack, i);
switch (type)
{
case LUA_TSTRING:
std::cout << lua_tostring(stack, i);
break;
case LUA_TBOOLEAN:
std::cout << lua_toboolean(stack, i);
break;
case LUA_TNUMBER:
std::cout << lua_tonumber(stack, i);
break;
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
std::cout << lua_touserdata(stack, i);
break;
default:
std::cout << lua_typename(stack, type);
}
std::cout << std::endl;
}
std::cout << std::endl;
}