Skip to content
Snippets Groups Projects
Commit 5ce24345 authored by dg's avatar dg
Browse files

more lua less C !

git-svn-id: http://svn.net-core.org/repos/t-engine4@3 51575b47-30f0-44d4-a5cc-537603b46e54
parent 75875a6b
No related branches found
No related tags found
No related merge requests found
require "engine.class"
local Entity = require "engine.Entity"
local Map = require "engine.Map"
module(..., package.seeall, class.inherit(Entity))
function _M:move(map, x, y)
if self.x and self.y then
map:remove(self.x, self.y, Map.ACTOR)
end
self.x, self.y = x, y
map(x, y, Map.ACTOR, self)
end
......@@ -2,6 +2,9 @@ module(..., package.seeall, class.make)
local next_uid = 1
-- Setup the uids repository as a weak value table, when the entities are no more used anywhere else they disappear from there too
setmetatable(__uids, {__mode="v"})
function _M:init(t)
t = t or {}
self.uid = next_uid
......
require "engine.class"
local Entity = require "engine.Entity"
module(..., package.seeall, class.make)
TERRAIN = 1
OBJECT = 10
ACTOR = 20
function _M:init(w, h)
self.w, self.h = w, h
self.map = {}
self.seens = {}
self.remembers = {}
for i = 0, w * h - 1 do self.map[i] = {} end
getmetatable(self).__call = _M.call
self.map = core.new_map(w, h)
setmetatable(self.seens, {__call = function(t, x, y, v) if v ~= nil then t[x + y * w] = v end return t[x + y * w] end})
setmetatable(self.remembers, {__call = function(t, x, y, v) if v ~= nil then t[x + y * w] = v end return t[x + y * w] end})
self.fov = engine.fov.new(_M.opaque, _M.apply, self)
end
function _M:setCurrent()
self.map:setCurrent()
engine.display.set_current_map(self)
end
function _M:call(x, y, pos, entity)
if entity then
self.map(x, y, pos, entity.uid)
table.insert(self.map[x + y * self.w], pos, entity)
else
return __uids[self.map(x, y, pos)]
if self.map[x + y * self.w] then
return self.map[x + y * self.w][pos]
end
end
end
function _M:remove(x, y, pos)
if self.map[x + y * self.w] then
self.map[x + y * self.w][pos] = nil
end
end
function _M:display()
self.fov(player.x, player.y, 20)
self.seens(player.x, player.y, true)
player:move(self, player.x+1, player.y)
for i = 0, self.w - 1 do for j = 0, self.h - 1 do
local e = self(i, j, TERRAIN)
local z = i + j * self.w
if e then
-- print("grid", i, j, z, self.seens[z])
if self.seens[z] then
engine.display.char(e.display, i, j, e.color_r, e.color_g, e.color_b)
elseif self.remembers[z] then
engine.display.char(e.display, i, j, e.color_r/3, e.color_g/3, e.color_b/3)
end
end
self.seens[z] = nil
end end
end
function _M:close()
self.fov:close()
self.fov = nil
end
function _M:opaque(x, y)
if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end
local e = self(x, y, TERRAIN)
if e and e.block_sight then return true end
end
function _M:apply(x, y)
if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
self.seens[x + y * self.w] = true
self.remembers[x + y * self.w] = true
end
......@@ -13,11 +13,29 @@ function make(c)
return c
end
function _M:clone(deep)
function inherit(base)
return function(c)
c.new = function(...)
local obj = {}
setmetatable(c, {__index=base})
setmetatable(obj, {__index=c})
if obj.init then obj:init(...) end
return obj
end
return c
end
end
function _M:clone(t, deep)
local n = {}
for k, e in pairs(self) do
n[k] = e
end
if t then
for k, e in pairs(t) do
n[k] = e
end
end
setmetatable(n, getmetatable(self))
if n.cloned then n:cloned(self) end
return n
......
require "engine.class"
require "engine.Map"
require "engine.Entity"
local Map = require "engine.Map"
local Entity = require "engine.Entity"
local Actor = require "engine.Actor"
map = engine.Map.new(20, 20)
map = Map.new(20, 20)
local floor = engine.Entity.new{color_r=50, color_g=50, color_b=50}
local e1 = engine.Entity.new{color_r=255, block_sight=true}
local e2 = engine.Entity.new{color_g=255, block_sight=true}
local e3 = engine.Entity.new{color_b=255}
local e4 = e3:clone()
e4.color_r=255
local floor = Entity.new{display='#', color_r=100, color_g=100, color_b=100}
local e1 = Entity.new{display='#', color_r=255, block_sight=true}
local e2 = Entity.new{display='#', color_g=255, block_sight=true}
local e3 = Entity.new{display='#', color_b=255, block_sight=true}
local e4 = e3:clone{color_r=255}
for i = 0, 19 do for j = 0, 19 do
map(i, j, 1, floor)
end end
map(8, 6, 1, e4)
map(8, 7, 1, e2)
map(8, 8, 1, e3)
map(9, 6, 1, e1)
map(9, 7, 1, e2)
map(9, 8, 1, e3)
map(10, 6, 1, e1)
map(10, 7, 1, e2)
map(10, 8, 1, e3)
map(8, 6, Map.TERRAIN, e4)
map(8, 7, Map.TERRAIN, e2)
map(8, 8, Map.TERRAIN, e3)
map(9, 6, Map.TERRAIN, e1)
map(9, 7, Map.TERRAIN, e2)
map(9, 8, Map.TERRAIN, e3)
map(10, 6, Map.TERRAIN, e1)
map(10, 7, Map.TERRAIN, e2)
map(10, 8, Map.TERRAIN, e3)
print(map(8, 8, 1))
player = Actor.new{display='#', color_r=125, color_g=125, color_b=0}
player:move(map, 2, 3)
map:setCurrent()
print("map is ", map)
--dofile("/game/modules/tome/")
#include "fov/fov.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "auxiliar.h"
#include "types.h"
#include "script.h"
#include "display.h"
#include "map.h"
struct lua_fov
{
fov_settings_type fov_settings;
int apply_ref;
int opaque_ref;
int map_ref;
};
#define REG_CORELUA "core"
static void map_seen(void *m, int x, int y, int dx, int dy, void *src)
{
struct lua_fov *fov = (struct lua_fov *)m;
extern map current_map;
lua_rawgeti(L, LUA_REGISTRYINDEX, fov->apply_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, fov->map_ref);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_call(L, 3, 0);
}
typedef struct lua_map lua_map;
struct lua_map
static bool map_opaque(void *m, int x, int y)
{
map m;
};
struct lua_fov *fov = (struct lua_fov *)m;
static int lua_new_map(lua_State *L)
lua_rawgeti(L, LUA_REGISTRYINDEX, fov->opaque_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, fov->map_ref);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_call(L, 3, 1);
bool res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int lua_new_fov(lua_State *L)
{
int w = luaL_checknumber(L, 1);
int h = luaL_checknumber(L, 2);
lua_map *m = (lua_map*)lua_newuserdata(L, sizeof(struct lua_map));
auxiliar_setclass(L, "map{core}", -1);
m->m = new_map(w, h);
/* printf("1\n");
luaL_checktype(L, LUA_TFUNCTION, 1);
printf("2\n");
luaL_checktype(L, LUA_TFUNCTION, 2);
printf("3\n");
luaL_checktype(L, LUA_TTABLE, 3);
printf("4\n");*/
int map_ref = luaL_ref(L, LUA_REGISTRYINDEX);
int apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
int opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
struct lua_fov *fov = (struct lua_fov*)lua_newuserdata(L, sizeof(struct lua_fov));
auxiliar_setclass(L, "fov{core}", -1);
fov->apply_ref = apply_ref;
fov->opaque_ref = opaque_ref;
fov->map_ref = map_ref;
fov_settings_init(&(fov->fov_settings));
fov_settings_set_opacity_test_function(&(fov->fov_settings), map_opaque);
fov_settings_set_apply_lighting_function(&(fov->fov_settings), map_seen);
return 1;
}
static int lua_free_map(lua_State *L)
static int lua_free_fov(lua_State *L)
{
lua_map *m = (lua_map*)auxiliar_checkclass(L, "map{core}", 1);
free_map(m->m);
if (current_map == m->m) current_map = NULL;
struct lua_fov *fov = (struct lua_fov*)auxiliar_checkclass(L, "fov{core}", 1);
fov_settings_free(&(fov->fov_settings));
luaL_unref(L, LUA_REGISTRYINDEX, fov->apply_ref);
luaL_unref(L, LUA_REGISTRYINDEX, fov->opaque_ref);
luaL_unref(L, LUA_REGISTRYINDEX, fov->map_ref);
lua_pushnumber(L, 1);
return 1;
}
static int lua_set_current_map(lua_State *L)
static int lua_fov(lua_State *L)
{
lua_map *m = (lua_map*)auxiliar_checkclass(L, "map{core}", 1);
current_map = m->m;
struct lua_fov *fov = (struct lua_fov*)auxiliar_checkclass(L, "fov{core}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int radius = luaL_checknumber(L, 4);
fov_circle(&(fov->fov_settings), fov, NULL, x, y, radius);
return 0;
}
static int lua_grid(lua_State *L)
static const struct luaL_reg fovlib[] =
{
lua_map *m = (lua_map*)auxiliar_checkclass(L, "map{core}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int pos = lua_tonumber(L, 4);
long uid = luaL_optlong(L, 5, -1);
if (uid == -1)
{
uid = map_get_grid(m->m, x, y, pos);
if (!uid)
lua_pushnil(L);
else
lua_pushnumber(L, uid);
return 1;
}
else
{
map_insert_grid(m->m, x, y, pos, uid);
return 0;
}
}
{"new", lua_new_fov},
{NULL, NULL},
};
static const struct luaL_reg corelib[] =
static const struct luaL_reg fov_reg[] =
{
{"new_map", lua_new_map},
{"setCurrent", lua_set_current_map},
{"__gc", lua_free_fov},
{"close", lua_free_fov},
{"__call", lua_fov},
{NULL, NULL},
};
static const struct luaL_reg map_reg[] =
extern int current_map;
static int lua_set_current_map(lua_State *L)
{
if (lua_isnil(L, 1))
current_map = LUA_NOREF;
else
current_map = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
static int lua_display_char(lua_State *L)
{
const char *c = luaL_checkstring(L, 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int r = luaL_checknumber(L, 4);
int g = luaL_checknumber(L, 5);
int b = luaL_checknumber(L, 6);
display_put_char(c[0], x, y, r, g, b);
return 0;
}
static const struct luaL_reg displaylib[] =
{
{"__gc", lua_free_map},
{"__call", lua_grid},
{"setCurrent", lua_set_current_map},
{"char", lua_display_char},
{"set_current_map", lua_set_current_map},
{NULL, NULL},
};
int luaopen_core(lua_State *L)
{
auxiliar_newclass(L, "map{core}", map_reg);
luaL_openlib(L, "core", corelib, 0);
auxiliar_newclass(L, "fov{core}", fov_reg);
luaL_openlib(L, "engine.fov", fovlib, 0);
luaL_openlib(L, "engine.display", displaylib, 0);
return 1;
}
......@@ -16,27 +16,40 @@
#include "types.h"
#include "script.h"
#include "map.h"
#include "physfs.h"
#define FOVRADIUS 100
lua_State *L = NULL;
fov_settings_type fov_settings;
map current_map = NULL;
int current_map = LUA_NOREF;
int px = 1, py = 1;
void display_utime()
{
struct timeval tv;
struct timezone tz;
struct tm *tm;
gettimeofday(&tv, &tz);
tm=localtime(&tv.tv_sec);
printf(" %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}
/**
* Redraw the screen. Called in a loop to create the output.
*/
void redraw(void) {
display_clear();
if (current_map)
// display_utime();
if (current_map != LUA_NOREF)
{
fov_circle(&fov_settings, current_map, NULL, px, py, 20);
map_display(current_map);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_map);
lua_pushstring(L, "display");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_map);
lua_call(L, 1, 0);
}
// display_utime();
display_put_char('@', px, py, 0x00, 0xFF, 0x00);
display_refresh();
......@@ -47,7 +60,6 @@ void redraw(void) {
*/
void normal_exit(void) {
display_exit();
fov_settings_free(&fov_settings);
exit(0);
}
......@@ -91,75 +103,9 @@ void keypressed(int key, int shift) {
redraw();
}
void map_seen(void *m, int x, int y, int dx, int dy, void *src)
{
if ((x < 0) || (y < 0) || (x >= ((map)m)->w) || (y >= ((map)m)->h)) return;
((map)m)->seens[x + y * ((map)m)->w] = TRUE;
((map)m)->remembers[x + y * ((map)m)->w] = TRUE;
}
bool map_opaque(void *mm, int x, int y)
{
int i = 1;
map m = (map)mm;
bool block = FALSE;
if (!m) return FALSE;
if ((x < 0) || (y < 0) || (x >= m->w) || (y >= m->h)) return FALSE;
grid g = m->grids[x + y * m->w];
while (g)
{
lua_getglobal(L, "__uids");
lua_pushnumber(L, g->uid);
lua_gettable(L, -2);
lua_pushstring(L, "block_sight");
lua_gettable(L, -2);
if (lua_isnil(L, 4))
{
// printf("block %d:%d => nil\n");
}
else if (lua_isboolean(L, 4))
{
// printf("block %d:%d [%d] => %d\n", x, y, i, lua_toboolean(L, 4));
block = TRUE;
}
else
{
// printf("block %d:%d [%d] => ??? %s\n", x, y, i, lua_tostring(L, 4));
}
// printf("lua top %d\n", lua_gettop(L));
lua_pop(L, 3);
if (block) return TRUE;
g = g->next;
i++;
}
return FALSE;
}
extern int luaopen_core(lua_State *L);
static int traceback (lua_State *L) {
#if 0
if (!lua_isstring(L, 1)) /* 'message' not a string? */
return 1; /* keep it intact */
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
return 1;
#endif
printf("Lua Error: %s\n", lua_tostring(L, 1));
}
......@@ -186,10 +132,6 @@ int main (int argc, char *argv[])
TTF_Init();
fov_settings_init(&fov_settings);
fov_settings_set_opacity_test_function(&fov_settings, map_opaque);
fov_settings_set_apply_lighting_function(&fov_settings, map_seen);
L = lua_open(); /* create state */
luaL_openlibs(L); /* open libraries */
luaopen_core(L);
......
#include <stdlib.h>
#include "display.h"
#include "script.h"
#include "map.h"
void init_map(map m, int w, int h)
{
int i, j;
m->grids = calloc(w * h, sizeof(grid*));
m->seens = calloc(w * h, sizeof(bool));
m->remembers = calloc(w * h, sizeof(bool));
m->w = w;
m->h = h;
for (i = 0; i < w; i++)
for (j = 0; j < h; j++)
{
m->grids[i + j * w] = NULL;
m->seens[i + j * w] = FALSE;
m->remembers[i + j * w] = FALSE;
}
}
map new_map(int w, int h)
{
map m = malloc(sizeof(map));
init_map(m, w, h);
return m;
}
void free_map(map m)
{
int i, j;
for (i = 0; i < m->w; i++)
for (j = 0; j < m->h; j++)
{
grid g = m->grids[i + j * m->w];
while (g)
{
grid next = g->next;
free(g);
g = next;
}
}
free(m->grids);
free(m->seens);
free(m);
}
void map_delete_grid_all(map m, int x, int y)
{
grid g = m->grids[x + y * m->w];
while (g)
{
grid next = g->next;
free(g);
g = next;
}
}
void map_insert_grid(map m, int x, int y, int pos, long uid)
{
grid g;
if (!m) return;
if ((x < 0) || (y < 0) || (x >= m->w) || (y >= m->h)) return;
g = m->grids[x + y * m->w];
while (g)
{
if (g->uid == uid) break;
g = g->next;
}
/* Not present, add it */
if (!g)
{
int i = 1;
g = m->grids[x + y * m->w];
grid prev = NULL;
while (g && i < pos)
{
i++;
prev = g;
g = g->next;
}
if (i == 1)
{
grid next = m->grids[x + y * m->w];
g = m->grids[x + y * m->w] = calloc(1, sizeof(struct grid_type));
g->uid = uid;
g->next = next;
}
else
{
grid next = g;
g = calloc(1, sizeof(struct grid_type));
g->uid = uid;
g->next = next;
prev->next = g;
}
}
}
long map_get_grid(map m, int x, int y, int pos)
{
int i = 1;
if (!m) return;
if ((x < 0) || (y < 0) || (x >= m->w) || (y >= m->h)) return;
grid g = m->grids[x + y * m->w];
while (g && i++ < pos) g = g->next;
if (g) return g->uid;
else return 0;
}
void map_display(map m)
{
int i, j;
for (i = 0; i < m->w; i++)
for (j = 0; j < m->h; j++)
{
if (m->grids[i + j * m->w])
{
unsigned char r, g, b;
char *c;
lua_getglobal(L, "__uids");
lua_pushnumber(L, m->grids[i + j * m->w]->uid);
lua_gettable(L, -2);
lua_pushstring(L, "color_r");
lua_gettable(L, -2);
r = lua_tonumber(L, 4);
lua_pop(L, 1);
lua_pushstring(L, "color_g");
lua_gettable(L, -2);
g = lua_tonumber(L, 4);
lua_pop(L, 1);
lua_pushstring(L, "color_b");
lua_gettable(L, -2);
b = lua_tonumber(L, 4);
lua_pop(L, 1);
lua_pushstring(L, "display");
lua_gettable(L, -2);
c = lua_tostring(L, 4);
lua_pop(L, 1);
lua_pop(L, 2);
if (m->seens[i + j * m->w])
display_put_char(c, i, j, r, g, b);
else if (m->remembers[i + j * m->w])
display_put_char(c, i, j, r/3, g/3, b/3);
}
m->seens[i + j * m->w] = FALSE;
}
}
#ifndef MAP_H
#define MAP_H
#include "types.h"
typedef struct grid_type* grid;
struct grid_type
{
long uid;
grid next;
};
typedef struct map_type* map;
struct map_type
{
int w, h;
grid* grids;
bool* seens;
bool* remembers;
};
// Handle maps
void init_map(map m, int w, int h);
map new_map(int w, int h);
void free_map(map m);
void map_insert_grid(map m, int x, int y, int pos, long uid);
long map_get_grid(map m, int x, int y, int pos);
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment