/*-------------------------------------------------------------------------*\ * Creates a master tcp object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { t_socket sock; const char *err = NULL; int fd = luaL_optnumber(L, 1, -1); if (fd < 1) err = inet_trycreate(&sock, SOCK_STREAM); else sock = fd; /* try to allocate a system socket */ if (!err) { /* allocate tcp object */ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); if (fd >= 1) auxiliar_setclass(L, "tcp{client}", -1); else auxiliar_setclass(L, "tcp{master}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); tcp->sock = sock; io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
/*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_timeout tm = &udp->tm; const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); const char *port = connecting? luaL_checkstring(L, 3): "0"; struct addrinfo connecthints; const char *err; memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_DGRAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = udp->family; if (connecting) { err = inet_tryconnect(&udp->sock, &udp->family, address, port, tm, &connecthints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } auxiliar_setclass(L, "udp{connected}", 1); } else { /* we ignore possible errors because Mac OS X always * returns EAFNOSUPPORT */ inet_trydisconnect(&udp->sock, udp->family, tm); auxiliar_setclass(L, "udp{unconnected}", 1); } /* change class to connected or unconnected depending on address */ lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Creates a master tcp object \*-------------------------------------------------------------------------*/ static int tcp_create(lua_State *L, int family) { t_socket sock; const char *err = inet_trycreate(&sock, family, SOCK_STREAM); /* try to allocate a system socket */ if (!err) { /* allocate tcp object */ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); memset(tcp, 0, sizeof(t_tcp)); /* set its type as master object */ auxiliar_setclass(L, "tcp{master}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); if (family == PF_INET6) { int yes = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)); } tcp->sock = sock; io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); tcp->family = family; return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
// Runs into main thread static int particles_new(lua_State *L) { const char *name_def = luaL_checkstring(L, 1); const char *args = luaL_checkstring(L, 2); // float zoom = luaL_checknumber(L, 3); int density = luaL_checknumber(L, 4); GLuint *texture = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5); shader_type *s = NULL; if (lua_isuserdata(L, 6)) s = (shader_type*)lua_touserdata(L, 6); bool fboalter = lua_toboolean(L, 7); particles_type *ps = (particles_type*)lua_newuserdata(L, sizeof(particles_type)); auxiliar_setclass(L, "core{particles}", -1); ps->lock = SDL_CreateMutex(); ps->name_def = strdup(name_def); ps->args = strdup(args); ps->density = density; ps->alive = TRUE; ps->i_want_to_die = FALSE; ps->l = NULL; ps->texcoords = NULL; ps->vertices = NULL; ps->colors = NULL; ps->particles = NULL; ps->init = FALSE; ps->texture = *texture; ps->shader = s; ps->fboalter = fboalter; ps->sub = NULL; thread_add(ps); return 1; }
/*-------------------------------------------------------------------------*\ * Creates a serial object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { const char* path = luaL_checkstring(L, 1); /* allocate unix object */ p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); /* open serial device */ t_socket sock = open(path, O_NOCTTY|O_RDWR, 00700); /*printf("open %s on %d\n", path, sock);*/ if (sock < 0) { lua_pushnil(L); lua_pushstring(L, socket_strerror(errno)); lua_pushnumber(L, errno); return 3; } /* set its type as client object */ auxiliar_setclass(L, "serial{client}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); un->sock = sock; io_init(&un->io, (p_send) socket_write, (p_recv) socket_read, (p_error) socket_ioerror, &un->sock); timeout_init(&un->tm, -1, -1); buffer_init(&un->buf, &un->io, &un->tm); return 1; }
/*-------------------------------------------------------------------------*\ * Creates a master udp object \*-------------------------------------------------------------------------*/ static int udp_create(lua_State *L, int family) { t_socket sock; const char *err = inet_trycreate(&sock, family, SOCK_DGRAM); /* try to allocate a system socket */ if (!err) { /* allocate udp object */ p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); auxiliar_setclass(L, "udp{unconnected}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); if (family == PF_INET6) { int yes = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)); } udp->sock = sock; timeout_init(&udp->tm, -1, -1); udp->family = family; return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
/*-------------------------------------------------------------------------*\ * Creates a master tcp object \*-------------------------------------------------------------------------*/ static int tcp_create(lua_State *L, int family) { p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); memset(tcp, 0, sizeof(t_tcp)); /* set its type as master object */ auxiliar_setclass(L, "tcp{master}", -1); /* if family is AF_UNSPEC, we leave the socket invalid and * store AF_UNSPEC into family. This will allow it to later be * replaced with an AF_INET6 or AF_INET socket upon first use. */ tcp->sock = SOCKET_INVALID; tcp->family = family; io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); if (family != AF_UNSPEC) { const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0); if (err != NULL) { lua_pushnil(L); lua_pushstring(L, err); return 2; } socket_setnonblocking(&tcp->sock); } return 1; }
/*-------------------------------------------------------------------------*\ * Creates a master tcp object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { short family; const char *af_opts[] = {"AF_INET", "AF_INET6"}; const char *def_af = "AF_INET"; const char *err; t_socket sock; switch(luaL_checkoption(L, 1, def_af, af_opts)) { case 0 : family = PF_INET ; break; case 1 : family = PF_INET6 ; break; default: family = PF_INET ; break; } /* try to allocate a system socket */ err = inet_trycreate(&sock, SOCK_STREAM, family); if (!err) { /* allocate tcp object */ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); /* set its type as master object */ auxiliar_setclass(L, "tcp{master}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); tcp->sock = sock; io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
/*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { const char *af_opts[] = {"AF_INET", "AF_INET6", "AF_UNSPEC"}; const char *def_af = "AF_UNSPEC"; p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); short family; const char *err; p_timeout tm = timeout_markstart(&tcp->tm); switch(luaL_checkoption(L, 4, def_af, af_opts)) { case 0 : family = AF_INET ; break; case 1 : family = AF_INET6 ; break; case 2 : family = AF_UNSPEC ; break; default: family = AF_UNSPEC ; break; } err = inet_tryconnect(&tcp->sock, address, port, tm, family); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* turn master object into a client object */ lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Waits for and returns a client object attempting connection to the * server object \*-------------------------------------------------------------------------*/ static int meth_accept(lua_State *L) { p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); p_timeout tm = timeout_markstart(&server->tm); t_socket sock; const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm); /* if successful, push client socket */ if (err == NULL) { p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); auxiliar_setclass(L, "tcp{client}", -1); /* initialize structure fields */ memset(clnt, 0, sizeof(t_tcp)); socket_setnonblocking(&sock); clnt->sock = sock; io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &clnt->sock); timeout_init(&clnt->tm, -1, -1); buffer_init(&clnt->buf, &clnt->io, &clnt->tm); clnt->family = server->family; return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
static int newcond(lua_State *L) { pthread_cond_t *cond = (pthread_cond_t *) lua_newuserdata(L, pthread_cond_sizeof()); auxiliar_setclass(L, "cond", -1); if (pthread_cond_init(cond, NULL) != 0) luaL_error(L, "unable to create cond"); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_timeout tm = &udp->tm; const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); unsigned short port = connecting ? (unsigned short) luaL_checknumber(L, 3) : (unsigned short) luaL_optnumber(L, 3, 0); const char *err = inet_tryconnect(&udp->sock, address, port, tm); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* change class to connected or unconnected depending on address */ if (connecting) auxiliar_setclass(L, "udp{connected}", 1); else auxiliar_setclass(L, "udp{unconnected}", 1); lua_pushnumber(L, 1); return 1; }
static int shader_new(lua_State *L) { if (!shaders_active) return 0; const char *code = luaL_checkstring(L, 1); bool vertex = lua_toboolean(L, 2); GLuint *s = (GLuint*)lua_newuserdata(L, sizeof(GLuint)); auxiliar_setclass(L, "gl{shader}", -1); *s = loadShader(code, vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); return 1; }
static int program_new(lua_State *L) { if (!shaders_active) return 0; shader_type *p = (shader_type*)lua_newuserdata(L, sizeof(shader_type)); auxiliar_setclass(L, "gl{program}", -1); p->shader = glCreateProgramObjectARB(); p->reset_uniforms = NULL; p->clone = FALSE; printf("New GL Shader program %d\n", p->shader); return 1; }
/*-------------------------------------------------------------------------*\ * Puts the sockt in listen mode \*-------------------------------------------------------------------------*/ static int meth_listen(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); int backlog = (int) luaL_optnumber(L, 2, 32); int err = socket_listen(&tcp->sock, backlog); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, socket_strerror(err)); return 2; } /* turn master object into a server object */ auxiliar_setclass(L, "tcp{server}", 1); lua_pushnumber(L, 1); return 1; }
static int meth_connect(lua_State *L) { p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); const char *path = luaL_checkstring(L, 2); const char *err = unix_tryconnect(un, path); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* turn master object into a client object */ auxiliar_setclass(L, "unix{client}", 1); lua_pushnumber(L, 1); return 1; }
static int global_connect(lua_State *L) { const char *remoteaddr = luaL_checkstring(L, 1); const char *remoteserv = luaL_checkstring(L, 2); const char *localaddr = luaL_optstring(L, 3, NULL); const char *localserv = luaL_optstring(L, 4, "0"); int family = inet_optfamily(L, 5, "unspec"); p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); struct addrinfo bindhints, connecthints; const char *err = NULL; /* initialize tcp structure */ memset(tcp, 0, sizeof(t_tcp)); io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); tcp->sock = SOCKET_INVALID; tcp->family = AF_UNSPEC; /* allow user to pick local address and port */ memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_STREAM; bindhints.ai_family = family; bindhints.ai_flags = AI_PASSIVE; if (localaddr) { err = inet_trybind(&tcp->sock, &tcp->family, localaddr, localserv, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } } /* try to connect to remote address and port */ memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_STREAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = tcp->family; err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, &tcp->tm, &connecthints); if (err) { socket_destroy(&tcp->sock); lua_pushnil(L); lua_pushstring(L, err); return 2; } auxiliar_setclass(L, "tcp{client}", -1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); p_timeout tm = timeout_markstart(&tcp->tm); const char *err = inet_tryconnect(&tcp->sock, address, port, tm); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* turn master object into a client object */ lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Creates a master udp object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { t_socket sock; const char *err = inet_trycreate(&sock, SOCK_DGRAM); /* try to allocate a system socket */ if (!err) { /* allocate tcp object */ p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); auxiliar_setclass(L, "udp{unconnected}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); udp->sock = sock; timeout_init(&udp->tm, -1, -1); return 1; } else { lua_pushnil(L); lua_pushstring(L, err); return 2; } }
/*-------------------------------------------------------------------------*\ * Creates a master udp object \*-------------------------------------------------------------------------*/ static int udp_create(lua_State *L, int family) { /* allocate udp object */ p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); auxiliar_setclass(L, "udp{unconnected}", -1); /* if family is AF_UNSPEC, we leave the socket invalid and * store AF_UNSPEC into family. This will allow it to later be * replaced with an AF_INET6 or AF_INET socket upon first use. */ udp->sock = SOCKET_INVALID; timeout_init(&udp->tm, -1, -1); udp->family = family; if (family != AF_UNSPEC) { const char *err = inet_trycreate(&udp->sock, family, SOCK_DGRAM, 0); if (err != NULL) { lua_pushnil(L); lua_pushstring(L, err); return 2; } socket_setnonblocking(&udp->sock); } return 1; }
static int program_clone(lua_State *L) { shader_type *p = (shader_type*)lua_touserdata(L, 1); shader_type *np = (shader_type*)lua_newuserdata(L, sizeof(shader_type)); // 2 auxiliar_setclass(L, "gl{program}", -1); np->clone = TRUE; np->shader = p->shader; np->p_tick = p->p_tick; np->p_color = p->p_color; np->p_mapcoord = p->p_mapcoord; np->p_texsize = p->p_texsize; np->p_texcoord = p->p_texcoord; np->reset_uniforms = NULL; lua_getmetatable(L, 1); // 3 lua_newtable(L); // 4 // Iterate old table and copy to new table lua_pushnil(L); while (lua_next(L, 3) != 0) { lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_rawset(L, 4); lua_pop(L, 1); } // Capture a reference to the parent so it is not GC'ed before us lua_pushstring(L, "_parent_clone"); lua_pushvalue(L, 1); lua_rawset(L, 4); lua_setmetatable(L, 2); lua_pop(L, 1); printf("Cloned shader %d\n", p->shader); return 1; }
/******************************************************************** ** Main thread * Takes a table, serialiaze it to memory and register it in the save thread ********************************************************************/ static int serial_new(lua_State *L) { const char *zfname = lua_tostring(L, 1); luaL_checktype(L, 2, LUA_TFUNCTION); luaL_checktype(L, 3, LUA_TFUNCTION); if (!lua_isnil(L, 4) && !lua_istable(L, 4)) { lua_pushstring(L, "argument 4 is not nil or table"); lua_error(L); } if (!lua_isnil(L, 5) && !lua_istable(L, 5)) { lua_pushstring(L, "argument 5 is not nil or table"); lua_error(L); } if (!lua_isnil(L, 6) && !lua_istable(L, 6)) { lua_pushstring(L, "argument 6 is not nil or table"); lua_error(L); } int d2_ref = luaL_ref(L, LUA_REGISTRYINDEX); int d_ref = luaL_ref(L, LUA_REGISTRYINDEX); int a_ref = luaL_ref(L, LUA_REGISTRYINDEX); int fadd_ref = luaL_ref(L, LUA_REGISTRYINDEX); int fname_ref = luaL_ref(L, LUA_REGISTRYINDEX); serial_type *s = (serial_type*)lua_newuserdata(L, sizeof(serial_type)); auxiliar_setclass(L, "core{serial}", -1); zipFile *zf = NULL; if (!last_zipname || strcmp(last_zipname, zfname)) { zf = zipOpen(zfname, APPEND_STATUS_CREATE); last_zf = zf; if (last_zipname) free(last_zipname); last_zipname = strdup(zfname); } else { zf = last_zf; } s->zf = zf; s->zfname = zfname; s->fname = fname_ref; s->fadd = fadd_ref; s->allow = a_ref; s->disallow = d_ref; s->disallow2 = d2_ref; return 1; }
/*-------------------------------------------------------------------------*\ * Waits for and returns a client object attempting connection to the * server object \*-------------------------------------------------------------------------*/ static int meth_accept(lua_State *L) { p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1); p_timeout tm = timeout_markstart(&server->tm); t_socket sock; int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); /* if successful, push client socket */ if (err == IO_DONE) { p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); auxiliar_setclass(L, "unix{client}", -1); /* initialize structure fields */ socket_setnonblocking(&sock); clnt->sock = sock; io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv, (p_error) socket_ioerror, &clnt->sock); timeout_init(&clnt->tm, -1, -1); buffer_init(&clnt->buf, &clnt->io, &clnt->tm); return 1; } else { lua_pushnil(L); lua_pushstring(L, socket_strerror(err)); return 2; } }
/*-------------------------------------------------------------------------*\ * Creates a master unix object \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { t_socket sock; int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); /* try to allocate a system socket */ if (err == IO_DONE) { /* allocate unix object */ p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); /* set its type as master object */ auxiliar_setclass(L, "unix{master}", -1); /* initialize remaining structure fields */ socket_setnonblocking(&sock); un->sock = sock; io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &un->sock); timeout_init(&un->tm, -1, -1); buffer_init(&un->buf, &un->io, &un->tm); return 1; } else { lua_pushnil(L); lua_pushstring(L, socket_strerror(err)); return 2; } }
/*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); const char *port = luaL_checkstring(L, 3); struct addrinfo connecthints; const char *err; memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_STREAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = tcp->family; timeout_markstart(&tcp->tm); err = inet_tryconnect(&tcp->sock, address, port, &tcp->tm, &connecthints); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
static int newmutex(lua_State *L) { srm_t *srm = (srm_t *) lua_newuserdata(L, sizeof(srm_t)); if (srm_init(srm) != 0) luaL_error(L, "unable to create mutex"); auxiliar_setclass(L, "mutex", -1); return 1; }
static int gas_new(lua_State *L) { int w = luaL_checknumber(L, 1); int h = luaL_checknumber(L, 2); // int density = luaL_checknumber(L, 3); GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5); int t_ref = luaL_ref(L, LUA_REGISTRYINDEX); int p_ref = luaL_ref(L, LUA_REGISTRYINDEX); gaszone_type *gz = (gaszone_type*)lua_newuserdata(L, sizeof(gaszone_type)); auxiliar_setclass(L, "core{gas}", -1); gz->last_tick = -1; gz->w = w; gz->h = h; gz->n = (w*2 > h*2) ? w*2 : h*2; gz->size = (gz->n + 2) * (gz->n + 2); gz->visc = 1E-4f; gz->diff = 1E-5f; gz->force = 20.0f; gz->source = 3000.0f; gz->stepDelay = 0.0f; gz->texture = *t; gz->texture_ref = t_ref; gz->u = calloc(gz->size, sizeof(float)); gz->v = calloc(gz->size, sizeof(float)); gz->dens = calloc(gz->size, sizeof(float)); gz->u_prev = calloc(gz->size, sizeof(float)); gz->v_prev = calloc(gz->size, sizeof(float)); gz->dens_prev = calloc(gz->size, sizeof(float)); int i; for (i=0; i < gz->size; i++) { gz->u[i] = 0.0f; gz->u_prev[i] = 0.0f; gz->v[i] = 0.0f; gz->v_prev[i] = 0.0f; gz->dens[i] = 0.0f; gz->dens_prev[i] = 0.0f; } printf("Making gas emitter with size %dx%d\n", w, h); // Grab all parameters lua_rawgeti(L, LUA_REGISTRYINDEX, p_ref); lua_pushstring(L, "generator"); lua_gettable(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 1); gz->generator_ref = LUA_NOREF; } else gz->generator_ref = luaL_ref(L, LUA_REGISTRYINDEX); if (gz->generator_ref == LUA_NOREF) { lua_pushstring(L, "Gas cloud created without a lua generator!"); lua_error(L); } lua_pop(L, 1); luaL_unref(L, LUA_REGISTRYINDEX, p_ref); return 1; }