Newer
Older
/*
TE4 - T-Engine 4
Copyright (C) 2009, 2010 Nicolas Casalini
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Nicolas Casalini "DarkGod"
darkgod@te4.org
*/
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "auxiliar.h"
#include "types.h"
#include "map.h"
#include "useshader.h"
#define DO_QUAD(dx, dy, dz, zoom) {\
glBegin(GL_QUADS); \
glTexCoord2f(0,0); glVertex3f((dx), (dy), (dz)); \
glTexCoord2f(map->tex_tile_w,0); glVertex3f(map->tile_w * (zoom) + (dx), (dy), (dz)); \
glTexCoord2f(map->tex_tile_w,map->tex_tile_h); glVertex3f(map->tile_w * (zoom) + (dx), map->tile_h * (zoom) + (dy), (dz)); \
glTexCoord2f(0,map->tex_tile_h); glVertex3f((dx), map->tile_h * (zoom) + (dy), (dz)); \
static int map_object_new(lua_State *L)
{
long uid = luaL_checknumber(L, 1);
int nb_textures = luaL_checknumber(L, 2);
int i;
map_object *obj = (map_object*)lua_newuserdata(L, sizeof(map_object));
auxiliar_setclass(L, "core{mapobj}", -1);
obj->textures = calloc(nb_textures, sizeof(GLuint));
obj->textures_ref = calloc(nb_textures, sizeof(int));
obj->on_seen = lua_toboolean(L, 3);
obj->on_remember = lua_toboolean(L, 4);
obj->on_unknown = lua_toboolean(L, 5);
obj->move_max = 0;
obj->dx = luaL_checknumber(L, 6);
obj->dy = luaL_checknumber(L, 7);
obj->scale = luaL_checknumber(L, 8);
obj->shader = 0;
obj->tint_r = obj->tint_g = obj->tint_b = 1;
for (i = 0; i < nb_textures; i++)
{
obj->textures[i] = 0;
obj->textures_is3d[i] = FALSE;
obj->textures_ref[i] = LUA_NOREF;
return 1;
}
static int map_object_free(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
int i;
for (i = 0; i < obj->nb_textures; i++)
if (obj->textures_ref[i] != LUA_NOREF)
luaL_unref(L, LUA_REGISTRYINDEX, obj->textures_ref[i]);
free(obj->textures_ref);
lua_pushnumber(L, 1);
return 1;
}
static int map_object_on_seen(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
if (lua_isboolean(L, 2))
{
obj->on_seen = lua_toboolean(L, 2);
}
lua_pushboolean(L, obj->on_seen);
return 1;
}
static int map_object_texture(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
int i = luaL_checknumber(L, 2);
GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 3);
if (i < 0 || i >= obj->nb_textures) return 0;
if (obj->textures_ref[i] != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, obj->textures_ref[i]);
lua_pushvalue(L, 3); // Get the texture
obj->textures_ref[i] = luaL_ref(L, LUA_REGISTRYINDEX); // Ref the texture
// printf("C Map Object setting texture %d = %d (ref %x)\n", i, *t, obj->textures_ref[i]);
return 0;
}
static int map_object_shader(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
GLuint *s = (GLuint*)auxiliar_checkclass(L, "gl{program}", 2);
obj->shader = *s;
return 0;
}
static int map_object_tint(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
float r = luaL_checknumber(L, 2);
float g = luaL_checknumber(L, 3);
float b = luaL_checknumber(L, 4);
obj->tint_r = r;
obj->tint_g = g;
obj->tint_b = b;
return 0;
}
static int map_object_print(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
printf("Map object texture 0: %d\n", obj->textures[0]);
return 0;
}
static int map_object_invalid(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
obj->valid = FALSE;
return 0;
}
static int map_object_reset_move_anim(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
obj->move_max = 0;
}
static int map_object_set_move_anim(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
// If at rest use satrting point
if (!obj->move_max)
{
obj->oldx = luaL_checknumber(L, 2);
obj->oldy = luaL_checknumber(L, 3);
}
// If already moving, compute starting point
else
{
float nx = luaL_checknumber(L, 4);
float ny = luaL_checknumber(L, 5);
float adx = nx - obj->oldx;
float ady = ny - obj->oldy;
obj->oldx = adx * obj->move_step / (float)obj->move_max + obj->oldx;
obj->oldy = ady * obj->move_step / (float)obj->move_max + obj->oldy;
}
obj->move_step = 0;
obj->move_max = luaL_checknumber(L, 6);
obj->move_blur = lua_tonumber(L, 7); // defaults to 0
return 0;
}
static int map_object_get_move_anim(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 2);
int i = luaL_checknumber(L, 3);
int j = luaL_checknumber(L, 4);
float mapdx = 0, mapdy = 0;
if (map->move_max)
{
float adx = (float)map->mx - map->oldmx;
float ady = (float)map->my - map->oldmy;
mapdx = -(adx * map->move_step / (float)map->move_max - adx);
mapdy = -(ady * map->move_step / (float)map->move_max - ady);
if (!obj->move_max || obj->display_last == DL_NONE)
}
else
{
float adx = (float)i - obj->oldx;
float ady = (float)j - obj->oldy;
lua_pushnumber(L, mapdx + (adx * obj->move_step / (float)obj->move_max - adx));
lua_pushnumber(L, mapdy + (ady * obj->move_step / (float)obj->move_max - ady));
}
return 2;
}
static int map_object_is_valid(lua_State *L)
{
map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
lua_pushboolean(L, obj->valid);
return 1;
}
static bool _CheckGL_Error(const char* GLcall, const char* file, const int line)
GLenum errCode;
if((errCode = glGetError())!=GL_NO_ERROR)
{
printf("OPENGL ERROR #%i: (%s) in file %s on line %i\n",errCode,gluErrorString(errCode), file, line);
printf("OPENGL Call: %s\n",GLcall);
return FALSE;
}
return TRUE;
}
//#define _DEBUG
#ifdef _DEBUG
#define CHECKGL( GLcall ) \
GLcall; \
if(!_CheckGL_Error( #GLcall, __FILE__, __LINE__)) \
exit(-1);
#else
#define CHECKGL( GLcall) \
GLcall;
#endif
static int map_objects_toscreen(lua_State *L)
{
if (!fbo_active) return 0;
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
/***************************************************
* Render
***************************************************/
int moid = 5;
while (lua_isuserdata(L, moid))
{
map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", moid);
int z;
if (m->shader) useShader(m->shader, 1, 1, 1, 1, 1, 1, 1, 1);
for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z >= 0; z--)
{
if (multitexture_active && shaders_active) tglActiveTexture(GL_TEXTURE0+z);
glBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]);
}
int dx = x, dy = y;
int dz = moid;
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f((dx), (dy), (dz));
glTexCoord2f(1,0); glVertex3f(w + (dx), (dy), (dz));
glTexCoord2f(1,1); glVertex3f(w + (dx), h + (dy), (dz));
glTexCoord2f(0,1); glVertex3f((dx), h + (dy), (dz));
glEnd();
if (m->shader) glUseProgramObjectARB(0);
moid++;
}
/***************************************************
***************************************************/
return 0;
}
static int map_objects_display(lua_State *L)
{
if (!fbo_active) return 0;
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
int w = luaL_checknumber(L, 1);
int h = luaL_checknumber(L, 2);
// Setup our FBO
// WARNING: this is a static, only one FBO is ever made, and never deleted, for some reasons
// deleting it makes the game crash when doing a chain lightning spell under luajit1 ... (yeah I know .. weird)
static GLuint fbo = 0;
if (!fbo) CHECKGL(glGenFramebuffersEXT(1, &fbo));
CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
// Now setup a texture to render to
GLuint img;
CHECKGL(glGenTextures(1, &img));
CHECKGL(glBindTexture(GL_TEXTURE_2D, img));
CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0));
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT) return 0;
// Set the viewport and save the old one
CHECKGL(glPushAttrib(GL_VIEWPORT_BIT));
CHECKGL(glViewport(0, 0, w, h));
glMatrixMode(GL_PROJECTION);
CHECKGL(glPushMatrix());
glLoadIdentity();
glOrtho(0, w, 0, h, -101, 101);
glMatrixMode( GL_MODELVIEW );
/* Reset The View */
glLoadIdentity( );
CHECKGL(glClear(GL_COLOR_BUFFER_BIT));
CHECKGL(glLoadIdentity());
/***************************************************
* Render to buffer
***************************************************/
int moid = 3;
while (lua_isuserdata(L, moid))
map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", moid);
int z;
if (m->shader) useShader(m->shader, 1, 1, 1, 1, 1, 1, 1, 1);
for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z >= 0; z--)
{
if (multitexture_active && shaders_active) tglActiveTexture(GL_TEXTURE0+z);
glBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]);
}
int dx = 0, dy = 0;
int dz = moid;
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f((dx), (dy), (dz));
glTexCoord2f(1,0); glVertex3f(w + (dx), (dy), (dz));
glTexCoord2f(1,1); glVertex3f(w + (dx), h + (dy), (dz));
glTexCoord2f(0,1); glVertex3f((dx), h + (dy), (dz));
glEnd();
if (m->shader) glUseProgramObjectARB(0);
moid++;
/***************************************************
***************************************************/
// Unbind texture from FBO and then unbind FBO
CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
// Restore viewport
CHECKGL(glPopAttrib());
// Cleanup
// No, dot not it's a static, see upwards
// CHECKGL(glDeleteFramebuffersEXT(1, &fbo));
glMatrixMode(GL_PROJECTION);
CHECKGL(glPopMatrix());
glMatrixMode( GL_MODELVIEW );
// Now register the texture to lua
GLuint *t = (GLuint*)lua_newuserdata(L, sizeof(GLuint));
auxiliar_setclass(L, "gl{texture}", -1);
*t = img;
return 1;
// Minimap defines
#define MM_FLOOR 1
#define MM_BLOCK 2
#define MM_OBJECT 4
#define MM_TRAP 8
#define MM_FRIEND 16
#define MM_NEUTRAL 32
#define MM_HOSTILE 64
#define MM_LEVEL_CHANGE 128
static int map_new(lua_State *L)
{
int w = luaL_checknumber(L, 1);
int h = luaL_checknumber(L, 2);
int mx = luaL_checknumber(L, 3);
int my = luaL_checknumber(L, 4);
int mwidth = luaL_checknumber(L, 5);
int mheight = luaL_checknumber(L, 6);
int tile_w = luaL_checknumber(L, 7);
int tile_h = luaL_checknumber(L, 8);
int zdepth = luaL_checknumber(L, 9);
map_type *map = (map_type*)lua_newuserdata(L, sizeof(map_type));
auxiliar_setclass(L, "core{map}", -1);
map->obscure_r = map->obscure_g = map->obscure_b = 0.6f;
map->obscure_a = 1;
map->shown_r = map->shown_g = map->shown_b = 1;
map->shown_a = 1;
map->mm_floor = map->mm_block = map->mm_object = map->mm_trap = map->mm_friend = map->mm_neutral = map->mm_hostile = map->mm_level_change = 0;
map->minimap_gridsize = 4;
map->zdepth = zdepth;
// Make up the map objects list, thus we can iterate them later
lua_newtable(L);
map->mo_list_ref = luaL_ref(L, LUA_REGISTRYINDEX); // Ref the table
// In case we can't support NPOT textures round up to nearest POT
int realw=1;
int realh=1;
while (realw < tile_w) realw *= 2;
while (realh < tile_h) realh *= 2;
map->tex_tile_w = (GLfloat)tile_w / realw;
map->tex_tile_h = (GLfloat)tile_h / realh;
map->mx = mx;
map->my = my;
map->mwidth = mwidth;
map->mheight = mheight;
map->grids= calloc(w, sizeof(map_object***));
map->grids_remembers = calloc(w, sizeof(bool*));
map->grids_lites = calloc(w, sizeof(bool*));
map->minimap = calloc(w, sizeof(unsigned char*));
printf("C Map size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight);
int i, j;
map->grids[i] = calloc(h, sizeof(map_object**));
for (j = 0; j < h; j++) map->grids[i][j] = calloc(zdepth, sizeof(map_object*));
map->grids_remembers[i] = calloc(h, sizeof(bool));
map->grids_lites[i] = calloc(h, sizeof(bool));
}
return 1;
}
static int map_free(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int i, j;
for (j = 0; j < map->h; j++) free(map->grids[i][j]);
free(map->grids[i]);
free(map->grids_seens[i]);
free(map->grids_remembers[i]);
free(map->grids_lites[i]);
free(map->grids);
free(map->grids_seens);
free(map->grids_remembers);
free(map->grids_lites);
luaL_unref(L, LUA_REGISTRYINDEX, map->mo_list_ref);
static int map_set_zoom(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int tile_w = luaL_checknumber(L, 2);
int tile_h = luaL_checknumber(L, 3);
int mwidth = luaL_checknumber(L, 4);
int mheight = luaL_checknumber(L, 5);
map->tile_w = tile_w;
map->tile_h = tile_h;
map->mwidth = mwidth;
map->mheight = mheight;
return 0;
}
static int map_set_obscure(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
float r = luaL_checknumber(L, 2);
float g = luaL_checknumber(L, 3);
float b = luaL_checknumber(L, 4);
float a = luaL_checknumber(L, 5);
map->obscure_r = r;
map->obscure_g = g;
map->obscure_b = b;
map->obscure_a = a;
return 0;
}
static int map_set_shown(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
float r = luaL_checknumber(L, 2);
float g = luaL_checknumber(L, 3);
float b = luaL_checknumber(L, 4);
float a = luaL_checknumber(L, 5);
map->shown_r = r;
map->shown_g = g;
map->shown_b = b;
map->shown_a = a;
return 0;
}
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
static int map_set_minimap_gridsize(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
float s = luaL_checknumber(L, 2);
map->minimap_gridsize = s;
return 0;
}
static int map_set_minimap(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
GLuint *floor = lua_isnil(L, 2) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 2);
GLuint *block = lua_isnil(L, 3) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 3);
GLuint *object = lua_isnil(L, 4) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 4);
GLuint *trap = lua_isnil(L, 5) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5);
GLuint *frien = lua_isnil(L, 6) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 6);
GLuint *neutral =lua_isnil(L, 7) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 7);
GLuint *hostile =lua_isnil(L, 8) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 8);
GLuint *lev =lua_isnil(L, 9) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 9);
map->mm_floor = *floor;
map->mm_block = *block;
map->mm_object = *object;
map->mm_trap = *trap;
map->mm_friend = *frien;
map->mm_neutral = *neutral;
map->mm_hostile = *hostile;
map->mm_level_change = *lev;
return 0;
}
static int map_set_grid(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
unsigned char mm = lua_tonumber(L, 4);
// Get the mo list
lua_rawgeti(L, LUA_REGISTRYINDEX, map->mo_list_ref);
int i;
for (i = 0; i < map->zdepth; i++)
{
// Remove the old object if any from the mo list
// We use the pointer value directly as an index
if (map->grids[x][y][i])
{
lua_pushnil(L);
lua_settable(L, 6); // Access the list of all mos for the map
}
lua_pushnumber(L, i + 1);
lua_gettable(L, 5); // Access the table of mos for this spot
map->grids[x][y][i] = lua_isnoneornil(L, -1) ? NULL : (map_object*)auxiliar_checkclass(L, "core{mapobj}", -1);
// Set the object in the mo list
// We use the pointer value directly as an index
lua_pushnumber(L, (long)map->grids[x][y][i]);
lua_pushvalue(L, -2);
lua_settable(L, 6); // Access the list of all mos for the map
// Remove the mo and get the next
lua_pop(L, 1);
}
// Pop the mo list
lua_pop(L, 1);
}
static int map_set_seen(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
map->grids_seens[x][y] = v;
return 0;
}
static int map_set_remember(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
bool v = lua_toboolean(L, 4);
map->grids_remembers[x][y] = v;
return 0;
}
static int map_set_lite(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
bool v = lua_toboolean(L, 4);
map->grids_lites[x][y] = v;
return 0;
}
static int map_clean_seen(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int i, j;
for (i = 0; i < map->w; i++)
for (j = 0; j < map->h; j++)
return 0;
}
static int map_clean_remember(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int i, j;
for (i = 0; i < map->w; i++)
for (j = 0; j < map->h; j++)
map->grids_remembers[i][j] = FALSE;
return 0;
}
static int map_clean_lite(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int i, j;
for (i = 0; i < map->w; i++)
for (j = 0; j < map->h; j++)
map->grids_lites[i][j] = FALSE;
return 0;
}
static int map_set_scroll(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int smooth = luaL_checknumber(L, 4);
if (smooth)
{
// Not moving, use starting point
if (!map->move_max)
{
map->oldmx = map->mx;
map->oldmy = map->my;
}
// Already moving, compute starting point
else
{
float adx = map->mx - map->oldmx;
float ady = map->my - map->oldmy;
map->oldmx = -adx * map->move_step / (float)map->move_max + map->mx;
map->oldmy = -ady * map->move_step / (float)map->move_max + map->my;
}
inline void display_map_quad(map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes) ALWAYS_INLINE;
void display_map_quad(map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes)
if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1)
{
r = (map->shown_r + m->tint_r)/2; g = (map->shown_g + m->tint_g)/2; b = (map->shown_b + m->tint_b)/2;
}
{
r = map->shown_r; g = map->shown_g; b = map->shown_b;
}
else
{
if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1)
{
r = (map->obscure_r + m->tint_r)/2; g = (map->obscure_g + m->tint_g)/2; b = (map->obscure_b + m->tint_b)/2;
}
{
r = map->obscure_r; g = map->obscure_g; b = map->obscure_b;
}
// Setup for display
a = (a > 1) ? 1 : ((a < 0) ? 0 : a);
int z;
if (m->shader) useShader(m->shader, i, j, map->tile_w, map->tile_h, r, g, b, a);
for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z >= 0; z--)
{
if (multitexture_active && shaders_active) tglActiveTexture(GL_TEXTURE0+z);
glBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]);
}
// Handle move anim
float animdx = 0, animdy = 0;
if (m->display_last == DL_NONE) m->move_max = 0;
if (m->move_max)
{
m->move_step += nb_keyframes;
if (m->move_step >= m->move_max) m->move_max = 0; // Reset once in place
if (m->display_last == DL_NONE) m->display_last = DL_TRUE;
if (m->move_max)
{
float adx = (float)i - m->oldx;
float ady = (float)j - m->oldy;
// Motion bluuuurr!
if (m->move_blur)
{
int step;
for (z = 1; z <= m->move_blur; z++)
{
step = m->move_step - z;
if (step >= 0)
{
animdx = map->tile_w * (adx * step / (float)m->move_max - adx);
animdy = map->tile_h * (ady * step / (float)m->move_max - ady);
tglColor4f(r, g, b, a * 2 / (3 + z));
DO_QUAD(dx + m->dx * map->tile_w + animdx, dy + m->dy * map->tile_h + animdy, 0, m->scale);
}
}
}
// Final step
animdx = map->tile_w * (adx * m->move_step / (float)m->move_max - adx);
animdy = map->tile_h * (ady * m->move_step / (float)m->move_max - ady);
}
}
// Final display
tglColor4f(r, g, b, a);
DO_QUAD(dx + m->dx * map->tile_w + animdx, dy + m->dy * map->tile_h + animdy, 0, m->scale);
// Unbind any shaders
if (m->shader) glUseProgramObjectARB(0);
m->display_last = DL_TRUE;
static int map_to_screen(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int nb_keyframes = luaL_checknumber(L, 4);
int i = 0, j = 0, z = 0;
/* Enables Depth Testing */
glEnable(GL_DEPTH_TEST);
int mx = map->mx;
int my = map->my;
if (map->move_max)
{
map->move_step += nb_keyframes;
if (map->move_step >= map->move_max)
{
map->move_max = 0; // Reset once in place
map->oldmx = map->mx;
map->oldmy = map->my;
}
if (map->move_max)
{
float adx = (float)map->mx - map->oldmx;
float ady = (float)map->my - map->oldmy;
animdx = map->tile_w * (adx * map->move_step / (float)map->move_max - adx);
animdy = map->tile_h * (ady * map->move_step / (float)map->move_max - ady);
mx = map->mx + (int)(adx * map->move_step / (float)map->move_max - adx);
my = map->my + (int)(ady * map->move_step / (float)map->move_max - ady);
}
}
x -= animdx;
y -= animdy;
// Always display some more of the map to make sure we always see it all
for (z = 0; z < map->zdepth; z++)
for (j = my - 1; j < my + map->mheight + 2; j++)
for (i = mx - 1; i < mx + map->mwidth + 2; i++)
{
if ((i < 0) || (j < 0) || (i >= map->w) || (j >= map->h)) continue;
int dx = x + (i - map->mx) * map->tile_w;
int dy = y + (j - map->my) * map->tile_h;
map_object *mo = map->grids[i][j][z];
if (!mo) continue;
if ((mo->on_seen && map->grids_seens[i][j]) || (mo->on_remember && map->grids_remembers[i][j]) || mo->on_unknown)
if (map->grids_seens[i][j])
display_map_quad(map, dx, dy, z, mo, i, j, map->shown_a, map->grids_seens[i][j], nb_keyframes);
display_map_quad(map, dx, dy, z, mo, i, j, map->obscure_a, 0, nb_keyframes);
// "Decay" displayed status for all mos
lua_rawgeti(L, LUA_REGISTRYINDEX, map->mo_list_ref);
lua_pushnil(L);
while (lua_next(L, -2) != 0)
{
map_object *mo = (map_object*)auxiliar_checkclass(L, "core{mapobj}", -1);
if (mo->display_last == DL_TRUE) mo->display_last = DL_TRUE_LAST;
else if (mo->display_last == DL_TRUE_LAST) mo->display_last = DL_NONE;
lua_pop(L, 1); // Remove value, keep key for next iteration
}
/* Disables Depth Testing, we do not need it for the rest of the display */
glDisable(GL_DEPTH_TEST);
static int minimap_to_screen(lua_State *L)
{
map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int mdx = luaL_checknumber(L, 4);
int mdy = luaL_checknumber(L, 5);
int mdw = luaL_checknumber(L, 6);
int mdh = luaL_checknumber(L, 7);
float transp = luaL_checknumber(L, 8);
int i = 0, j = 0;
for (i = mdx; i < mdx + mdw; i++)
{
for (j = mdy; j < mdy + mdh; j++)
{
if ((i < 0) || (j < 0) || (i >= map->w) || (j >= map->h)) continue;
int dx = x + (i - mdx) * map->minimap_gridsize;
int dy = y + (j - mdy) * map->minimap_gridsize;
if (map->grids_seens[i][j] || map->grids_remembers[i][j])
{
if (map->grids_seens[i][j])
{
tglColor4f(map->shown_r, map->shown_g, map->shown_b, map->shown_a * transp);
if ((map->minimap[i][j] & MM_LEVEL_CHANGE) && map->mm_level_change)
{
glBindTexture(GL_TEXTURE_2D, map->mm_level_change);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_HOSTILE) && map->mm_hostile)
{
glBindTexture(GL_TEXTURE_2D, map->mm_hostile);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_NEUTRAL) && map->mm_neutral)
{
glBindTexture(GL_TEXTURE_2D, map->mm_neutral);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_FRIEND) && map->mm_friend)
{
glBindTexture(GL_TEXTURE_2D, map->mm_friend);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_TRAP) && map->mm_trap)
{
glBindTexture(GL_TEXTURE_2D, map->mm_trap);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_OBJECT) && map->mm_object)
{
glBindTexture(GL_TEXTURE_2D, map->mm_object);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_BLOCK) && map->mm_block)
{
glBindTexture(GL_TEXTURE_2D, map->mm_block);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-96);
glEnd();
}
else if ((map->minimap[i][j] & MM_FLOOR) && map->mm_floor)
{
glBindTexture(GL_TEXTURE_2D, map->mm_floor);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-96);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-96);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-96);