[ create a new paste ] login | about

Link: http://codepad.org/LyB0kE5P    [ raw code | fork ]

C, pasted on Jul 25:
/*

    gcc -Wall -shared -fPIC -o mtmapgenc.so main.c
 */

#include <stdio.h>  /* Just for basic testing (e.g. printf()) */
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#define LUA_NAMESPACE "mtmgc"
#define MODNAME "[caverealms]"

#if LUA_VERSION_NUM > 501
#   define luaL_reg luaL_Reg
#endif

/* Default values for (some) settings */
#define DEFAULT_TCAVE 0.5

struct settings {
    int     ymin;   /* bottom realm limit */
    int     ymax;   /* top realm limit */
    double  tcave;  /* cave threshold */
};

struct mapgen {
    int x0, x1,
        y0, y1,
        z0, z1;
    uint16_t *nvals_cave,
             *nvals_wave,
             *nvals_biome;
    uint16_t *data;
};

struct nodeids {
    size_t n;
    uint16_t *cid;
};

enum {
    C_AIR
};

static int l_gencaverealm(lua_State *L);

/* Private functions */
static int parseargs(lua_State *L, struct settings *cfg, struct mapgen *mapg, struct nodeids *nids);
static int parsearg_settings(lua_State *L, struct settings *cfg, int tidx);
static void parsearg_noisedata(lua_State *L, struct mapgen *mapg, int tidx);
static void parsearg_nodeidtable(lua_State *L, struct nodeids *nids, int tidx);
static void parsearg_mapgeom(lua_State *L, struct mapgen *mapg, int tidx);

const struct luaL_reg lua_funcs[] = {
    { "gencaverealms",      l_gencaverealm },
    { NULL, NULL}
};

int luaopen_cavemapgenc(lua_State *L)
{
    const luaL_reg *f;

    luaL_newmetatable(L, LUA_NAMESPACE);
    lua_pushstring(L, "__index");
    lua_newtable(L);

    /* "install" functions into metatable */
    for (f = lua_funcs; f->func != NULL && f->name != NULL; f++) {
        lua_pushcfunction(L, f->func);
        lua_setfield(L, -2, f->name);
    }

    return 1;
}

/*********************************************************************
 Functions 'exported' to Lua
 *********************************************************************/

/* "Lua Prototype": void f(settingstable, nodeidtable); */
static int l_gencaverealm(lua_State *L)
{
    struct settings     cfg;
    struct mapgen       mapg;
    struct nodeids      nids = {0};

    if (!parseargs(L, &cfg, &mapg, &nids)) {
        lua_pushstring(L, MODNAME" Error parsing settings");
        lua_error(L);
    }

    printf("[%s] %d, %d, %d\n", MODNAME, mapg.x0, mapg.y0, mapg.z0);
    //printf("[%s] %d, %d, %f\n", MODNAME, cfg.ymin, cfg.ymax, cfg.tcave);


    if (nids.cid) free (nids.cid);
    return 0;
}

/*********************************************************************
 Private
 *********************************************************************/

/* (settingstable, nodeidtable) */
static int parseargs(lua_State *L, struct settings *cfg, struct mapgen *mapg, struct nodeids *nids)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    parsearg_settings(L, cfg, 1);

    luaL_checktype(L, 2, LUA_TTABLE);
    parsearg_nodeidtable(L, nids, 2);

    luaL_checktype(L, 3, LUA_TTABLE);
    //parsearg_noisedata(L, mapg, 3);

    luaL_checktype(L, 4, LUA_TTABLE);
    parsearg_mapgeom(L, mapg, 4);

    luaL_checktype(L, 5, LUA_TUSERDATA);
    mapg->data = *(uint16_t **)(lua_touserdata(L, 5));

    return 1;
}

static int parsearg_settings(lua_State *L, struct settings *cfg, int tidx)
{
    lua_getfield(L, tidx, "ymin");
    cfg->ymin = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
    lua_getfield(L, tidx, "ymax");
    cfg->ymax = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
    lua_getfield(L, tidx, "tcave");
    cfg->tcave = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : DEFAULT_TCAVE;

    lua_pop(L, 3);  /* Restore Lua stack */

    if (cfg->ymax == cfg->ymin) {
        lua_pushstring(L, MODNAME" Error: ymin and ymax are equal");
        lua_error(L);
    }

    return 1;
}

static void parsearg_nodeidtable(lua_State *L, struct nodeids *nids, int tidx)
{
    size_t n, i;

    n = luaL_getn(L, tidx);
    nids->n = n;
    nids->cid = malloc(sizeof *nids->cid * n);

    if (!nids->cid) {
        lua_pushstring(L, MODNAME" Error: could not allocate memory");
        lua_error(L);
    }

    for (i = 0; i < n; i++) {
        lua_pushinteger(L, i+1);
        lua_gettable(L, -2);
        if(lua_isnumber(L, -1)) {
            nids->cid[i] = lua_tonumber(L, -1);
        } else {
            lua_pushstring(L, MODNAME" Error: expected number (nodeid)");
            lua_error(L);
        }
        lua_pop(L, 1);
    }
}

static void parsearg_noisedata(lua_State *L, struct mapgen *mapg, int tidx)
{
    lua_getfield(L, tidx, "nvals_cave");
    mapg->nvals_cave = lua_isuserdata(L, -1) ? *(uint16_t **)(lua_touserdata(L, -1)) : NULL;

    lua_getfield(L, tidx, "nvals_wave");
    mapg->nvals_wave = lua_isuserdata(L, -1) ? *(uint16_t **)(lua_touserdata(L, -1)) : NULL;

    lua_getfield(L, tidx, "nvals_biome");
    mapg->nvals_biome = lua_isuserdata(L, -1) ? *(uint16_t **)(lua_touserdata(L, -1)) : NULL;

    if (!(mapg->nvals_cave && mapg->nvals_wave && mapg->nvals_biome)) {
        lua_pushstring(L, MODNAME" Error: noise values not supplied");
        lua_error(L);
    }

    lua_pop(L, 3);


}

static void parsearg_mapgeom(lua_State *L, struct mapgen *mapg, int tidx)
{
    lua_getfield(L, tidx, "x0");
    mapg->x0 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
    lua_getfield(L, tidx, "x1");
    mapg->x1 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;

    lua_getfield(L, tidx, "y0");
    mapg->y0 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
    lua_getfield(L, tidx, "y1");
    mapg->y1 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;

    lua_getfield(L, tidx, "x0");
    mapg->z0 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
    lua_getfield(L, tidx, "x1");
    mapg->z1 = lua_isnumber(L, -1) ? lua_tointeger(L, -1) : 0;
}


Create a new paste based on this one


Comments: