diff --git a/game/engines/default/engine/Actor.lua b/game/engines/default/engine/Actor.lua index ed10ec2057b5ab6cae15e89ea88575c0a0cb2cb0..fdb6751bcca8641860d52ec4b759721075e92084 100644 --- a/game/engines/default/engine/Actor.lua +++ b/game/engines/default/engine/Actor.lua @@ -60,6 +60,17 @@ end function _M:setTarget(target) end +--- Setup minimap color for this entity +-- You may overload this method to customize your minimap +function _M:setupMinimapInfo(mo, map) + if map.actor_player and not map.actor_player:canSee(self) then return end + local r = map.actor_player and map.actor_player:reactionToward(self) or -100 + if r < 0 then mo:minimap(240, 0, 0) + elseif r > 0 then mo:minimap(0, 240, 0) + else mo:minimap(0, 0, 240) + end +end + --- Adds a particles emitter following the actor function _M:addParticles(ps) self.__particles[ps] = true diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua index cf959cef24fb59aa99726c4fbaa8b17a612fcc36..dee17fd7df41d8384612e593aa1cee9f8e960fec 100644 --- a/game/engines/default/engine/Entity.lua +++ b/game/engines/default/engine/Entity.lua @@ -156,6 +156,11 @@ function _M:changeUid(newuid) __uids[self.uid] = self end +--- Setup minimap color for this entity +-- You may overload this method to customize your minimap +function _M:setupMinimapInfo(mo, map) +end + --- Create the "map object" representing this entity -- Do not touch unless you *KNOW* what you are doing.<br/> -- You do *NOT* need this, this is used by the engine.Map class automatically.<br/> diff --git a/game/engines/default/engine/Grid.lua b/game/engines/default/engine/Grid.lua index a9478cc7a9e151e7d661960fd5ee6bbaa41012a5..bc36bb7a069c908b716062e5185963c9eb17dea8 100644 --- a/game/engines/default/engine/Grid.lua +++ b/game/engines/default/engine/Grid.lua @@ -34,3 +34,11 @@ function _M:init(t, no_default) self.name = t.name Entity.init(self, t, no_default) end + +--- Setup minimap color for this entity +-- You may overload this method to customize your minimap +function _M:setupMinimapInfo(mo, map) + if self:check("block_move") then mo:minimap(240, 240, 240) + else mo:minimap(0, 0, 0) + end +end diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua index 90cf0aed37ef8bdd6c9699a335251d31e387c372..636661b87546af673fb42632a681ce167f816f07 100644 --- a/game/engines/default/engine/Map.lua +++ b/game/engines/default/engine/Map.lua @@ -61,59 +61,6 @@ color_shown = { 1, 1, 1, 1 } color_obscure = { 0.6, 0.6, 0.6, 1 } smooth_scroll = 0 --- The minimap data -MM_FLOOR = 1 -MM_BLOCK = 2 -MM_OBJECT = 4 -MM_TRAP = 8 -MM_FRIEND = 16 -MM_NEUTRAL = 32 -MM_HOSTILE = 64 -MM_LEVEL_CHANGE = 128 - -local s_floor = core.display.newSurface(4, 4) -s_floor:erase(0, 0, 0, 255) -local s_floor_gl = s_floor:glTexture() - -local s_block = core.display.newSurface(4, 4) -s_block:erase(240, 240, 240, 255) -local s_block_gl = s_block:glTexture() - -local s_level_change = core.display.newSurface(4, 4) -s_level_change:erase(240, 0, 240, 255) -local s_level_change_gl = s_level_change:glTexture() - -local s_hostile = core.display.newSurface(4, 4) -s_hostile:erase(240, 0, 0, 255) -local s_hostile_gl = s_hostile:glTexture() - -local s_friend = core.display.newSurface(4, 4) -s_friend:erase(0, 240, 0, 255) -local s_friend_gl = s_friend:glTexture() - -local s_neutral = core.display.newSurface(4, 4) -s_neutral:erase(0, 0, 240, 255) -local s_neutral_gl = s_neutral:glTexture() - -local s_object = core.display.newSurface(4, 4) -s_object:erase(0, 0, 240, 255) -local s_object_gl = s_object:glTexture() - -local s_trap = core.display.newSurface(4, 4) -s_trap:erase(240, 240, 0, 255) -local s_trap_gl = s_trap:glTexture() - -mm_blocks = { - [MM_FLOOR] = s_floor_gl, - [MM_BLOCK] = s_block_gl, - [MM_LEVEL_CHANGE] = s_level_change_gl, - [MM_HOSTILE] = s_hostile_gl, - [MM_FRIEND] = s_friend_gl, - [MM_NEUTRAL] = s_neutral_gl, - [MM_OBJECT] = s_object_gl, - [MM_TRAP] = s_trap_gl, -} - --- Sets the viewport size -- Static -- @param x screen coordinate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks @@ -238,16 +185,6 @@ function _M:makeCMap() self._map = core.map.newMap(self.w, self.h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight, self.tile_w, self.tile_h, self.zdepth) self._map:setObscure(unpack(self.color_obscure)) self._map:setShown(unpack(self.color_shown)) - self._map:setupMiniMap( - mm_blocks[MM_FLOOR], - mm_blocks[MM_BLOCK], - mm_blocks[MM_OBJECT], - mm_blocks[MM_TRAP], - mm_blocks[MM_FRIEND], - mm_blocks[MM_NEUTRAL], - mm_blocks[MM_HOSTILE], - mm_blocks[MM_LEVEL_CHANGE] - ) self._fovcache = { block_sight = core.fov.newCache(self.w, self.h), @@ -385,7 +322,6 @@ end -- This updates many things, from the C map object, the FOV caches, the minimap if it exists, ... function _M:updateMap(x, y) -- Update minimap if any - local mm = MM_FLOOR local mos = {} if not self.updateMapDisplay then @@ -402,40 +338,39 @@ function _M:updateMap(x, y) self._fovcache.path_caches[ps]:set(x, y, g:check("block_move", x, y, ps, false, true)) end - mm = mm + (g:check("block_move") and MM_BLOCK or 0) - mm = mm + (g:check("change_level") and MM_LEVEL_CHANGE or 0) g:getMapObjects(self.tiles, mos, 1) + g:setupMinimapInfo(g._mo, self) end if t then -- Handles trap being known if not self.actor_player or t:knownBy(self.actor_player) then t:getMapObjects(self.tiles, mos, 4) - mm = mm + MM_TRAP + t:setupMinimapInfo(t._mo, self) else t = nil end end if o then o:getMapObjects(self.tiles, mos, 7) + o:setupMinimapInfo(o._mo, self) if self.object_stack_count then local mo = o:getMapStackMO(self, x, y) if mo then mos[9] = mo end end - mm = mm + MM_OBJECT end if a then -- Handles invisibility and telepathy and other such things if not self.actor_player or self.actor_player:canSee(a) then - local r = self.actor_player:reactionToward(a) - mm = mm + (r > 0 and MM_FRIEND or (r == 0 and MM_NEUTRAL or MM_HOSTILE)) a:getMapObjects(self.tiles, mos, 10) + a:setupMinimapInfo(a._mo, self) end end if p then p:getMapObjects(self.tiles, mos, 13) + p:setupMinimapInfo(p._mo, self) end else - mm = self:updateMapDisplay(x, y, mos) + self:updateMapDisplay(x, y, mos) end -- Update entities checker for this spot @@ -453,7 +388,7 @@ function _M:updateMap(x, y) self._check_entities_store[ce] = self._check_entities[x + y * self.w] -- Cache the map objects in the C map - self._map:setGrid(x, y, mm, mos) + self._map:setGrid(x, y, mos) -- Update FOV caches if self:checkAllEntities(x, y, "block_sight", self.actor_player) then self._fovcache.block_sight:set(x, y, true) diff --git a/game/engines/default/engine/Object.lua b/game/engines/default/engine/Object.lua index 6e76b21a035989d9c7d0aed71d312e0d6dbbb2b2..4f5db794c488cdaab5fd7d975471f5150754eb34 100644 --- a/game/engines/default/engine/Object.lua +++ b/game/engines/default/engine/Object.lua @@ -66,6 +66,12 @@ function _M:canAct() return false end +--- Setup minimap color for this entity +-- You may overload this method to customize your minimap +function _M:setupMinimapInfo(mo, map) + mo:minimap(0, 0, 240) +end + --- Do something when its your turn -- For objects this mostly is to recharge them -- By default, does nothing at all diff --git a/game/engines/default/engine/Trap.lua b/game/engines/default/engine/Trap.lua index 962904d4045d9b63c9b9f7c53abd81deaba0dda5..60e5083659880787689fd05d8e6d9e1a15b3f970 100644 --- a/game/engines/default/engine/Trap.lua +++ b/game/engines/default/engine/Trap.lua @@ -52,6 +52,12 @@ function _M:loaded() setmetatable(self.known_by, {__mode="k"}) end +--- Setup minimap color for this entity +-- You may overload this method to customize your minimap +function _M:setupMinimapInfo(mo, map) + mo:minimap(240, 240, 0) +end + --- Do we have enough energy function _M:enoughEnergy(val) val = val or game.energy_to_act diff --git a/game/modules/tome/data/talents/spells/ice.lua b/game/modules/tome/data/talents/spells/ice.lua index e3733469196d6c119247a9227c4c193fa9c1f016..4264b4a178f810223414b7a9cc1fdc86c66c3347 100644 --- a/game/modules/tome/data/talents/spells/ice.lua +++ b/game/modules/tome/data/talents/spells/ice.lua @@ -60,6 +60,7 @@ newTalent{ points = 5, mana = 25, cooldown = 10, + requires_target = true, tactical = { ATTACKAREA = 2, DISABLE = 1 }, range = function(self, t) return 1 + self:getTalentLevelRaw(t) end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 180) end, @@ -87,6 +88,7 @@ newTalent{ cooldown = 15, tactical = { ATTACKAREA = 2 }, range = 10, + requires_target = true, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 180) end, getTargetCount = function(self, t) return math.ceil(self:getTalentLevel(t) + 2) end, action = function(self, t) diff --git a/game/modules/tome/data/talents/spells/storm.lua b/game/modules/tome/data/talents/spells/storm.lua index af2dd9c0e840fa8eb479fa4d63469b16cf6c1a4a..1050746c3bffa11c440fde4d94b206227b93f2e8 100644 --- a/game/modules/tome/data/talents/spells/storm.lua +++ b/game/modules/tome/data/talents/spells/storm.lua @@ -26,6 +26,7 @@ newTalent{ cooldown = 8, tactical = { ATTACKAREA = 2, DISABLE =1 }, direct_hit = true, + requires_target = true, range = function(self, t) return math.floor(2 + self:getTalentLevel(t) * 0.7) end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 28, 170) end, action = function(self, t) @@ -63,6 +64,7 @@ newTalent{ cooldown = 3, tactical = { ATTACK = 2 }, range = 10, + requires_target = true, reflectable = true, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 25, 200) end, action = function(self, t) diff --git a/game/modules/tome/data/talents/spells/wildfire.lua b/game/modules/tome/data/talents/spells/wildfire.lua index 1b95ac8c0419895a5aa2f06ccd189d09dd8b76ee..50c4c01c6b5cbac8f9368a1989c326ede9ee21f5 100644 --- a/game/modules/tome/data/talents/spells/wildfire.lua +++ b/game/modules/tome/data/talents/spells/wildfire.lua @@ -26,6 +26,7 @@ newTalent{ cooldown = 5, tactical = { ATTACKAREA = 2, DISABLE = 2, ESCAPE = 2 }, direct_hit = true, + requires_target = true, range = function(self, t) return 1 + self:getTalentLevelRaw(t) end, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 28, 180) end, action = function(self, t) @@ -51,6 +52,7 @@ newTalent{ cooldown = 16, tactical = { ATTACKAREA = 2 }, range = 10, + requires_target = true, getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 240) end, getTargetCount = function(self, t) return math.ceil(self:getTalentLevel(t) + 2) end, action = function(self, t) diff --git a/src/core_lua.c b/src/core_lua.c index bc0480a37ee48648dcf7ab2298da2bf04ae38248..02873e60cac01ba01d82ce230459c2190b8ca1af 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -532,16 +532,21 @@ static int gl_draw_quad(lua_State *L) else tglBindTexture(GL_TEXTURE_2D, 0); - tglColor4f(r, g, b, a); - GLfloat texcoords[2*4] = { 0, 0, 0, 1, 1, 1, 1, 0, }; - + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + GLfloat vertices[2*4] = { x, y, x, y + h, @@ -549,9 +554,8 @@ static int gl_draw_quad(lua_State *L) x + w, y, }; glVertexPointer(2, GL_FLOAT, 0, vertices); - glDrawArrays(GL_QUADS, 0, 4); - tglColor4f(1, 1, 1, 1); + glDrawArrays(GL_QUADS, 0, 4); return 0; } @@ -738,7 +742,23 @@ static int sdl_surface_toscreen(lua_State *L) float g = luaL_checknumber(L, 5); float b = luaL_checknumber(L, 6); float a = luaL_checknumber(L, 7); - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); + } + else + { + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; + glColorPointer(4, GL_FLOAT, 0, colors); } GLuint t; @@ -751,8 +771,6 @@ static int sdl_surface_toscreen(lua_State *L) glDeleteTextures(1, &t); - if (lua_isnumber(L, 4)) tglColor4f(1, 1, 1, 1); - return 0; } @@ -768,7 +786,23 @@ static int sdl_surface_toscreen_with_texture(lua_State *L) float g = luaL_checknumber(L, 6); float b = luaL_checknumber(L, 7); float a = luaL_checknumber(L, 8); - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); + } + else + { + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; + glColorPointer(4, GL_FLOAT, 0, colors); } tglBindTexture(GL_TEXTURE_2D, *t); @@ -776,8 +810,6 @@ static int sdl_surface_toscreen_with_texture(lua_State *L) copy_surface_to_texture(*s); draw_textured_quad(x,y,(*s)->w,(*s)->h); - if (lua_isnumber(L, 5)) tglColor4f(1, 1, 1, 1); - return 0; } @@ -862,7 +894,23 @@ static int sdl_texture_toscreen(lua_State *L) float g = luaL_checknumber(L, 7); float b = luaL_checknumber(L, 8); float a = luaL_checknumber(L, 9); - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); + } + else + { + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; + glColorPointer(4, GL_FLOAT, 0, colors); } tglBindTexture(GL_TEXTURE_2D, *t); @@ -883,8 +931,6 @@ static int sdl_texture_toscreen(lua_State *L) }; glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); - - if (lua_isnumber(L, 6)) tglColor4f(1, 1, 1, 1); return 0; } @@ -903,7 +949,23 @@ static int sdl_texture_toscreen_full(lua_State *L) float g = luaL_checknumber(L, 10); float b = luaL_checknumber(L, 11); float a = luaL_checknumber(L, 12); - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); + } + else + { + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; + glColorPointer(4, GL_FLOAT, 0, colors); } tglBindTexture(GL_TEXTURE_2D, *t); @@ -926,8 +988,6 @@ static int sdl_texture_toscreen_full(lua_State *L) }; glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); - - if (lua_isnumber(L, 8)) tglColor4f(1, 1, 1, 1); return 0; } @@ -990,6 +1050,7 @@ static int sdl_texture_outline(lua_State *L) float g = luaL_checknumber(L, 7); float b = luaL_checknumber(L, 8); float a = luaL_checknumber(L, 9); + int i; // Setup our FBO // WARNING: this is a static, only one FBO is ever made, and never deleted, for some reasons @@ -1029,34 +1090,39 @@ static int sdl_texture_outline(lua_State *L) glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); + /* Render to buffer: shadow */ + glBindTexture(GL_TEXTURE_2D, *t); + GLfloat texcoords[2*4] = { 0, 0, 1, 0, 1, 1, 0, 1, }; - - glBindTexture(GL_TEXTURE_2D, *t); - glTexCoordPointer(2, GL_FLOAT, 0, texcoords); GLfloat vertices[2*4] = { x, y, w+x, y, w+x, h+y, x, h+y, }; - - /* Render to buffer: shadow */ - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glDrawArrays(GL_QUADS, 0, 4); /* Render to buffer: original */ - tglColor4f(1, 1, 1, 1); + for (i = 0; i < 4*4; i++) colors[i] = 1; vertices[0] = 0; vertices[1] = 0; vertices[2] = w; vertices[3] = 0; vertices[4] = w; vertices[5] = h; vertices[6] = 0; vertices[7] = h; - glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); // Unbind texture from FBO and then unbind FBO @@ -1265,7 +1331,23 @@ static int gl_fbo_toscreen(lua_State *L) g = luaL_checknumber(L, 8); b = luaL_checknumber(L, 9); a = luaL_checknumber(L, 10); - tglColor4f(r, g, b, a); + GLfloat colors[4*4] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a, + }; + glColorPointer(4, GL_FLOAT, 0, colors); + } + else + { + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; + glColorPointer(4, GL_FLOAT, 0, colors); } if (lua_isuserdata(L, 6)) { @@ -1295,7 +1377,6 @@ static int gl_fbo_toscreen(lua_State *L) glDrawArrays(GL_QUADS, 0, 4); if (lua_isuserdata(L, 6)) glUseProgramObjectARB(0); - if (lua_isnumber(L, 7)) tglColor4f(1, 1, 1, 1); glEnable(GL_BLEND); return 0; } diff --git a/src/main.c b/src/main.c index 2727f187fbb13448842e1c9ead8063b9fa6d453f..37582045311574fd5b7ab5192024e78771329b0d 100644 --- a/src/main.c +++ b/src/main.c @@ -299,14 +299,20 @@ void call_draw(int nb_keyframes) 1, 1, 0, 1, }; + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glColorPointer(4, GL_FLOAT, 0, colors); int x = mousex + mouse_cursor_ox; int y = mousey + mouse_cursor_oy; int down = SDL_GetMouseState(NULL, NULL); tglBindTexture(GL_TEXTURE_2D, down ? mouse_cursor_down_tex : mouse_cursor_tex); - tglColor4f(1, 1, 1, 1); GLfloat vertices[2*4] = { x, y, @@ -485,9 +491,6 @@ void setupDisplayTimer(int fps) /* general OpenGL initialization function */ int initGL() { - /* Enable smooth shading */ -// glShadeModel( GL_SMOOTH ); - /* Set the background black */ tglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); @@ -496,19 +499,13 @@ int initGL() /* The Type Of Depth Test To Do */ glDepthFunc(GL_LEQUAL); -// glDepthFunc(GL_LESS); - - /* Really Nice Perspective Calculations */ - // glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); -// glDisable(GL_DEPTH_TEST); - tglColor4f(1.0f,1.0f,1.0f,1.0f); -// glAlphaFunc(GL_GREATER,0.1f); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); return( TRUE ); } @@ -547,9 +544,6 @@ int resizeWindow(int width, int height) /* Reset The View */ glLoadIdentity( ); -// glEnable(GL_ALPHA_TEST); -// tglColor4f(1.0f,1.0f,1.0f,1.0f); - return( TRUE ); } diff --git a/src/map.c b/src/map.c index 6dbc5252cc8bff54ae49b454f41812578f31d74d..ebf299092c4f28f1390d17ca25fa5dd83aace157 100644 --- a/src/map.c +++ b/src/map.c @@ -51,6 +51,10 @@ static int map_object_new(lua_State *L) obj->move_max = 0; + obj->mm_r = -1; + obj->mm_g = -1; + obj->mm_b = -1; + obj->valid = TRUE; obj->dx = luaL_checknumber(L, 6); obj->dy = luaL_checknumber(L, 7); @@ -133,6 +137,18 @@ static int map_object_tint(lua_State *L) return 0; } +static int map_object_minimap(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->mm_r = r / 255; + obj->mm_g = g / 255; + obj->mm_b = b / 255; + return 0; +} + static int map_object_print(lua_State *L) { map_object *obj = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1); @@ -248,20 +264,23 @@ static int map_objects_toscreen(lua_State *L) int w = luaL_checknumber(L, 3); int h = luaL_checknumber(L, 4); - GLfloat vertices[3*4] = { - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - }; + GLfloat vertices[3*4]; GLfloat texcoords[2*4] = { 0, 0, 1, 0, 1, 1, 0, 1, }; + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glColorPointer(4, GL_FLOAT, 0, colors); + glVertexPointer(3, GL_FLOAT, 0, vertices); /*************************************************** * Render @@ -271,8 +290,6 @@ static int map_objects_toscreen(lua_State *L) { map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", moid); - tglColor4f(1, 1, 1, 1); - 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--) @@ -287,7 +304,6 @@ static int map_objects_toscreen(lua_State *L) vertices[3] = w + dx; vertices[4] = dy; vertices[5] = dz; vertices[6] = w + dx; vertices[7] = h + dy; vertices[8] = dz; vertices[9] = dx; vertices[10] = h + dy; vertices[11] = dz; - glVertexPointer(3, GL_FLOAT, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); if (m->shader) glUseProgramObjectARB(0); @@ -344,20 +360,23 @@ static int map_objects_display(lua_State *L) CHECKGL(glClear(GL_COLOR_BUFFER_BIT)); CHECKGL(glLoadIdentity()); - GLfloat vertices[3*4] = { - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - }; + GLfloat vertices[3*4]; GLfloat texcoords[2*4] = { 0, 0, 1, 0, 1, 1, 0, 1, }; + GLfloat colors[4*4] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }; glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glColorPointer(4, GL_FLOAT, 0, colors); + glVertexPointer(3, GL_FLOAT, 0, vertices); /*************************************************** * Render to buffer @@ -367,8 +386,6 @@ static int map_objects_display(lua_State *L) { map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", moid); - tglColor4f(1, 1, 1, 1); - 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--) @@ -383,7 +400,6 @@ static int map_objects_display(lua_State *L) vertices[3] = w + dx; vertices[4] = dy; vertices[5] = dz; vertices[6] = w + dx; vertices[7] = h + dy; vertices[8] = dz; vertices[9] = dx; vertices[10] = h + dy; vertices[11] = dz; - glVertexPointer(3, GL_FLOAT, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); if (m->shader) glUseProgramObjectARB(0); @@ -419,15 +435,7 @@ static int map_objects_display(lua_State *L) } -// 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 +#define QUADS_PER_BATCH 500 static int map_new(lua_State *L) { @@ -449,9 +457,12 @@ static int map_new(lua_State *L) 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->vertices = calloc(2*4*QUADS_PER_BATCH, sizeof(GLfloat)); // 2 coords, 4 vertices per particles + map->colors = calloc(4*4*QUADS_PER_BATCH, sizeof(GLfloat)); // 4 color data, 4 vertices per particles + map->texcoords = calloc(2*4*QUADS_PER_BATCH, sizeof(GLfloat)); + map->w = w; map->h = h; map->zdepth = zdepth; @@ -475,7 +486,7 @@ static int map_new(lua_State *L) map->my = my; map->mwidth = mwidth; map->mheight = mheight; - map->grids= calloc(w, sizeof(map_object***)); + map->grids = calloc(w, sizeof(map_object***)); map->grids_seens = calloc(w, sizeof(float*)); map->grids_remembers = calloc(w, sizeof(bool*)); map->grids_lites = calloc(w, sizeof(bool*)); @@ -516,6 +527,10 @@ static int map_free(lua_State *L) free(map->grids_lites); free(map->minimap); + free(map->colors); + free(map->texcoords); + free(map->vertices); + luaL_unref(L, LUA_REGISTRYINDEX, map->mo_list_ref); lua_pushnumber(L, 1); @@ -572,36 +587,12 @@ static int map_set_minimap_gridsize(lua_State *L) 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); if (x < 0 || y < 0 || x >= map->w || y >= map->h) return 0; - unsigned char mm = lua_tonumber(L, 4); // Get the mo list lua_rawgeti(L, LUA_REGISTRYINDEX, map->mo_list_ref); @@ -615,18 +606,18 @@ static int map_set_grid(lua_State *L) { lua_pushnumber(L, (long long)map->grids[x][y][i]); lua_pushnil(L); - lua_settable(L, 6); // Access the list of all mos for the map + lua_settable(L, 5); // 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 + lua_gettable(L, 4); // 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 + lua_settable(L, 5); // Access the list of all mos for the map // Remove the mo and get the next lua_pop(L, 1); @@ -634,8 +625,6 @@ static int map_set_grid(lua_State *L) // Pop the mo list lua_pop(L, 1); - - map->minimap[x][y] = mm; return 0; } @@ -740,19 +729,38 @@ static int map_set_scroll(lua_State *L) return 0; } -#define DO_QUAD(dx, dy, zoom) {\ - vertices[0] = (dx); vertices[1] = (dy); \ - vertices[3] = map->tile_w * (zoom) + (dx); vertices[4] = (dy); \ - vertices[6] = map->tile_w * (zoom) + (dx); vertices[7] = map->tile_h * (zoom) + (dy); \ - vertices[9] = (dx); vertices[10] = map->tile_h * (zoom) + (dy); \ - glVertexPointer(3, GL_FLOAT, 0, vertices); \ - glDrawArrays(GL_QUADS, 0, 4); \ - } +#define DO_QUAD(dx, dy, zoom, r, g, b, a) {\ + vertices[(*vert_idx)] = (dx); vertices[(*vert_idx)+1] = (dy); \ + vertices[(*vert_idx)+2] = map->tile_w * (zoom) + (dx); vertices[(*vert_idx)+3] = (dy); \ + vertices[(*vert_idx)+4] = map->tile_w * (zoom) + (dx); vertices[(*vert_idx)+5] = map->tile_h * (zoom) + (dy); \ + vertices[(*vert_idx)+6] = (dx); vertices[(*vert_idx)+7] = map->tile_h * (zoom) + (dy); \ + \ + texcoords[(*vert_idx)] = 0; texcoords[(*vert_idx)+1] = 0; \ + texcoords[(*vert_idx)+2] = map->tex_tile_w; texcoords[(*vert_idx)+3] = 0; \ + texcoords[(*vert_idx)+4] = map->tex_tile_w; texcoords[(*vert_idx)+5] = map->tex_tile_h; \ + texcoords[(*vert_idx)+6] = 0; texcoords[(*vert_idx)+7] = map->tex_tile_h; \ + \ + colors[(*col_idx)] = r; colors[(*col_idx)+1] = g; colors[(*col_idx)+2] = b; colors[(*col_idx)+3] = (a); \ + colors[(*col_idx)+4] = r; colors[(*col_idx)+5] = g; colors[(*col_idx)+6] = b; colors[(*col_idx)+7] = (a); \ + colors[(*col_idx)+8] = r; colors[(*col_idx)+9] = g; colors[(*col_idx)+10] = b; colors[(*col_idx)+11] = (a); \ + colors[(*col_idx)+12] = r; colors[(*col_idx)+13] = g; colors[(*col_idx)+14] = b; colors[(*col_idx)+15] = (a); \ + \ + (*vert_idx) += 8; \ + (*col_idx) += 16; \ + if ((*vert_idx) >= 8*QUADS_PER_BATCH) {\ + glDrawArrays(GL_QUADS, 0, (*vert_idx) / 2); \ + (*vert_idx) = 0; \ + (*col_idx) = 0; \ + } \ +} -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) +inline void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, 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(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes) { float r, g, b; + GLfloat *vertices = map->vertices; + GLfloat *colors = map->colors; + GLfloat *texcoords = map->texcoords; /******************************************************** ** Select the color to use @@ -783,27 +791,33 @@ void display_map_quad(map_type *map, int dx, int dy, float dz, map_object *m, in } } + /* Reset vertices&all buffers, we are changing texture/shader */ + if ((*cur_tex != m->textures[0]) || m->shader || (m->nb_textures > 1)) + { + /* Draw remaining ones */ + if (vert_idx) glDrawArrays(GL_QUADS, 0, (*vert_idx) / 2); + /* Reset */ + (*vert_idx) = 0; + (*col_idx) = 0; + } + if (*cur_tex != m->textures[0]) + { + glBindTexture(GL_TEXTURE_2D, m->textures[0]); + *cur_tex = m->textures[0]; + } + /******************************************************** ** Setup all textures we need ********************************************************/ 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--) + for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z > 0; z--) { if (multitexture_active && shaders_active) tglActiveTexture(GL_TEXTURE0+z); tglBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]); } - - /******************************************************** - ** Make up the arrays to push - ********************************************************/ - GLfloat vertices[3*4] = { - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 0, 0, 0, - }; + if (m->nb_textures && multitexture_active && shaders_active) tglActiveTexture(GL_TEXTURE0); // Switch back to default texture unit /******************************************************** ** Compute/display movement and motion blur @@ -832,8 +846,7 @@ void display_map_quad(map_type *map, int dx, int dy, float dz, map_object *m, in { 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, m->scale); + DO_QUAD(dx + m->dx * map->tile_w + animdx, dy + m->dy * map->tile_h + animdy, m->scale, r, g, b, a * 2 / (3 + z)); } } } @@ -847,12 +860,20 @@ void display_map_quad(map_type *map, int dx, int dy, float dz, map_object *m, in /******************************************************** ** Display the entity ********************************************************/ - tglColor4f(r, g, b, a); - DO_QUAD(dx + m->dx * map->tile_w + animdx, dy + m->dy * map->tile_h + animdy, m->scale); + DO_QUAD(dx + m->dx * map->tile_w + animdx, dy + m->dy * map->tile_h + animdy, m->scale, r, g, b, a); /******************************************************** ** Cleanup ********************************************************/ + if (m->shader || m->nb_textures) + { + /* Draw remaining ones */ + if (vert_idx) glDrawArrays(GL_QUADS, 0, (*vert_idx) / 2); + /* Reset */ + (*vert_idx) = 0; + (*col_idx) = 0; + *cur_tex = 0; + } if (m->shader) glUseProgramObjectARB(0); m->display_last = DL_TRUE; } @@ -866,17 +887,19 @@ static int map_to_screen(lua_State *L) int y = luaL_checknumber(L, 3); int nb_keyframes = luaL_checknumber(L, 4); int i = 0, j = 0, z = 0; + int vert_idx = 0; + int col_idx = 0; + GLuint cur_tex = 0; /* Enables Depth Testing */ glEnable(GL_DEPTH_TEST); - GLfloat texcoords[2*4] = { - 0, 0, - map->tex_tile_w, 0, - map->tex_tile_w, map->tex_tile_h, - 0, map->tex_tile_h, - }; + GLfloat *vertices = map->vertices; + GLfloat *colors = map->colors; + GLfloat *texcoords = map->texcoords; glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glColorPointer(4, GL_FLOAT, 0, colors); // Smooth scrolling float animdx = 0, animdy = 0; @@ -923,17 +946,20 @@ static int map_to_screen(lua_State *L) { 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(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->shown_a, map->grids_seens[i][j], nb_keyframes); } else { - display_map_quad(map, dx, dy, z, mo, i, j, map->obscure_a, 0, nb_keyframes); + display_map_quad(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->obscure_a, 0, nb_keyframes); } } } } } + /* Display any leftovers */ + if (vert_idx) glDrawArrays(GL_QUADS, 0, vert_idx / 2); + // "Decay" displayed status for all mos lua_rawgeti(L, LUA_REGISTRYINDEX, map->mo_list_ref); lua_pushnil(L); @@ -945,24 +971,12 @@ static int map_to_screen(lua_State *L) lua_pop(L, 1); // Remove value, keep key for next iteration } - // Restore normal display - tglColor4f(1, 1, 1, 1); - /* Disables Depth Testing, we do not need it for the rest of the display */ glDisable(GL_DEPTH_TEST); return 0; } -#define DO_MINIQUAD(dx, dy) {\ - vertices[0] = (dx); vertices[1] = (dy); \ - vertices[3] = map->minimap_gridsize + (dx); vertices[4] = (dy); \ - vertices[6] = map->minimap_gridsize + (dx); vertices[7] = map->minimap_gridsize + (dy); \ - vertices[9] = (dx); vertices[10] = map->minimap_gridsize + (dy); \ - glVertexPointer(3, GL_FLOAT, 0, vertices); \ - glDrawArrays(GL_QUADS, 0, 4); \ - } - static int minimap_to_screen(lua_State *L) { map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); @@ -973,102 +987,76 @@ static int minimap_to_screen(lua_State *L) int mdw = luaL_checknumber(L, 6); int mdh = luaL_checknumber(L, 7); float transp = luaL_checknumber(L, 8); - int i = 0, j = 0; - GLfloat vertices[3*4] = { - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - 0, 0, -96, - }; - - GLfloat texcoords[2*4] = { - 0, 0, - map->tex_tile_w, 0, - map->tex_tile_w, map->tex_tile_h, - 0, map->tex_tile_h, - }; + int z = 0, i = 0, j = 0; + int vert_idx = 0; + int col_idx = 0; + GLfloat r, g, b, a; + + GLfloat *vertices = map->vertices; + GLfloat *colors = map->colors; + GLfloat *texcoords = map->texcoords; glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glColorPointer(4, GL_FLOAT, 0, colors); + + tglBindTexture(GL_TEXTURE_2D, 0); - for (i = mdx; i < mdx + mdw; i++) + // Always display some more of the map to make sure we always see it all + for (z = 0; z < map->zdepth; z++) { - for (j = mdy; j < mdy + mdh; j++) + for (i = mdx; i < mdx + mdw; i++) { - if ((i < 0) || (j < 0) || (i >= map->w) || (j >= map->h)) continue; + 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; + int dx = x + (i - mdx) * map->minimap_gridsize; + int dy = y + (j - mdy) * map->minimap_gridsize; + map_object *mo = map->grids[i][j][z]; + if (!mo || mo->mm_r < 0) continue; - 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) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_level_change); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_HOSTILE) && map->mm_hostile) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_hostile); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_NEUTRAL) && map->mm_neutral) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_neutral); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_FRIEND) && map->mm_friend) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_friend); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_TRAP) && map->mm_trap) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_trap); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_OBJECT) && map->mm_object) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_object); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_BLOCK) && map->mm_block) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_block); - DO_MINIQUAD(dx, dy); - } - else if ((map->minimap[i][j] & MM_FLOOR) && map->mm_floor) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_floor); - DO_MINIQUAD(dx, dy); - } - } - else + if ((mo->on_seen && map->grids_seens[i][j]) || (mo->on_remember && map->grids_remembers[i][j]) || mo->on_unknown) { - tglColor4f(map->obscure_r, map->obscure_g, map->obscure_b, map->obscure_a * transp); - if ((map->minimap[i][j] & MM_LEVEL_CHANGE) && map->mm_level_change) + if (map->grids_seens[i][j]) { - tglBindTexture(GL_TEXTURE_2D, map->mm_level_change); - DO_MINIQUAD(dx, dy); + r = mo->mm_r; g = mo->mm_g; b = mo->mm_b; a = transp; + colors[col_idx] = r; colors[col_idx+1] = g; colors[col_idx+2] = b; colors[col_idx+3] = (a); + colors[col_idx+4] = r; colors[col_idx+5] = g; colors[col_idx+6] = b; colors[col_idx+7] = (a); + colors[col_idx+8] = r; colors[col_idx+9] = g; colors[col_idx+10] = b; colors[col_idx+11] = (a); + colors[col_idx+12] = r; colors[col_idx+13] = g; colors[col_idx+14] = b; colors[col_idx+15] = (a); } - else if ((map->minimap[i][j] & MM_BLOCK) && map->mm_block) + else { - tglBindTexture(GL_TEXTURE_2D, map->mm_block); - DO_MINIQUAD(dx, dy); + r = mo->mm_r * 0.6; g = mo->mm_g * 0.6; b = mo->mm_b * 0.6; a = transp * 0.6; + colors[col_idx] = r; colors[col_idx+1] = g; colors[col_idx+2] = b; colors[col_idx+3] = (a); + colors[col_idx+4] = r; colors[col_idx+5] = g; colors[col_idx+6] = b; colors[col_idx+7] = (a); + colors[col_idx+8] = r; colors[col_idx+9] = g; colors[col_idx+10] = b; colors[col_idx+11] = (a); + colors[col_idx+12] = r; colors[col_idx+13] = g; colors[col_idx+14] = b; colors[col_idx+15] = (a); } - else if ((map->minimap[i][j] & MM_FLOOR) && map->mm_floor) - { - tglBindTexture(GL_TEXTURE_2D, map->mm_floor); - DO_MINIQUAD(dx, dy); + + vertices[vert_idx] = (dx); vertices[vert_idx+1] = (dy); + vertices[vert_idx+2] = map->minimap_gridsize + (dx); vertices[vert_idx+3] = (dy); + vertices[vert_idx+4] = map->minimap_gridsize + (dx); vertices[vert_idx+5] = map->minimap_gridsize + (dy); + vertices[vert_idx+6] = (dx); vertices[vert_idx+7] = map->minimap_gridsize + (dy); + + texcoords[vert_idx] = 0; texcoords[vert_idx+1] = 0; + texcoords[vert_idx+2] = map->tex_tile_w; texcoords[vert_idx+3] = 0; + texcoords[vert_idx+4] = map->tex_tile_w; texcoords[vert_idx+5] = map->tex_tile_h; + texcoords[vert_idx+6] = 0; texcoords[vert_idx+7] = map->tex_tile_h; + + vert_idx += 8; + col_idx += 16; + if (vert_idx >= 8*QUADS_PER_BATCH) { + glDrawArrays(GL_QUADS, 0, vert_idx / 2); + vert_idx = 0; + col_idx = 0; } } } } } + if (vert_idx) glDrawArrays(GL_QUADS, 0, vert_idx / 2); - // Restore normal display - tglColor4f(1, 1, 1, 1); return 0; } @@ -1098,7 +1086,6 @@ static const struct luaL_reg map_reg[] = {"setScroll", map_set_scroll}, {"toScreen", map_to_screen}, {"toScreenMiniMap", minimap_to_screen}, - {"setupMiniMap", map_set_minimap}, {"setupMiniMapGridSize", map_set_minimap_gridsize}, {NULL, NULL}, }; @@ -1113,6 +1100,7 @@ static const struct luaL_reg map_object_reg[] = {"invalidate", map_object_invalid}, {"isValid", map_object_is_valid}, {"onSeen", map_object_on_seen}, + {"minimap", map_object_minimap}, {"resetMoveAnim", map_object_reset_move_anim}, {"setMoveAnim", map_object_set_move_anim}, {"getMoveAnim", map_object_get_move_anim}, diff --git a/src/map.h b/src/map.h index aaf07c2dc772f447466f2e394c59f1abfc9ebc7d..32a340a377ef95bcf34023c094ad6ea264c9d62b 100644 --- a/src/map.h +++ b/src/map.h @@ -34,6 +34,9 @@ typedef struct { float tint_r; float tint_g; float tint_b; + float mm_r; + float mm_g; + float mm_b; bool on_seen; bool on_remember; bool on_unknown; @@ -50,7 +53,10 @@ typedef struct { bool **grids_remembers; bool **grids_lites; unsigned char **minimap; - GLuint mm_floor, mm_block, mm_object, mm_trap, mm_friend, mm_neutral, mm_hostile, mm_level_change; + + GLfloat *vertices; + GLfloat *colors; + GLfloat *texcoords; int mo_list_ref; diff --git a/src/particles.c b/src/particles.c index 9e0c1a371334ff1fc55a962f5fdb789c4d9aa2a2..efd56eed6b026c2837e87fa69b849a4922ad445c 100644 --- a/src/particles.c +++ b/src/particles.c @@ -32,6 +32,7 @@ #define rng(x, y) (x + rand_div(1 + y - x)) #define PARTICLE_ETERNAL 999999 +#define PARTICLES_PER_ARRAY 1000 static void getinitfield(lua_State *L, const char *key, int *min, int *max) { @@ -82,6 +83,11 @@ static int particles_new(lua_State *L) ps->texture_ref = t_ref; ps->no_stop = no_stop; + int batch = (nb < PARTICLES_PER_ARRAY) ? nb : PARTICLES_PER_ARRAY; + ps->vertices = calloc(2*4*batch, sizeof(GLfloat)); // 2 coords, 4 vertices per particles + ps->colors = calloc(4*4*batch, sizeof(GLfloat)); // 4 color data, 4 vertices per particles + ps->texcoords = calloc(2*4*batch, sizeof(GLshort)); + ps->particles = calloc(nb, sizeof(particle_type)); // printf("Making particle emitter with %d particles\n", ps->nb); @@ -143,6 +149,9 @@ static int particles_free(lua_State *L) { particles_type *ps = (particles_type*)auxiliar_checkclass(L, "core{particles}", 1); + free(ps->texcoords); + free(ps->vertices); + free(ps->colors); free(ps->particles); luaL_unref(L, LUA_REGISTRYINDEX, ps->texture_ref); if (ps->generator_ref) luaL_unref(L, LUA_REGISTRYINDEX, ps->generator_ref); @@ -264,7 +273,6 @@ static int particles_emit(lua_State *L) return 0; } - static int particles_to_screen(lua_State *L) { particles_type *ps = (particles_type*)auxiliar_checkclass(L, "core{particles}", 1); @@ -276,21 +284,15 @@ static int particles_to_screen(lua_State *L) int w = 0; int i, j; bool alive = FALSE; - GLfloat vertices[3*4] = { - 0, 0, -97, - 0, 0, -97, - 0, 0, -97, - 0, 0, -97, - }; - GLshort texcoords[2*4] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1, - }; + int vert_idx = 0, col_idx = 0; + GLfloat *vertices = ps->vertices; + GLfloat *colors = ps->colors; + GLshort *texcoords = ps->texcoords; glBindTexture(GL_TEXTURE_2D, ps->texture); glTexCoordPointer(2, GL_SHORT, 0, texcoords); + glColorPointer(4, GL_FLOAT, 0, colors); + glVertexPointer(2, GL_FLOAT, 0, vertices); for (w = 0; w < ps->nb; w++) { @@ -307,52 +309,69 @@ static int particles_to_screen(lua_State *L) i = x + p->x * zoom - p->size / 2; j = y + p->y * zoom - p->size / 2; - vertices[0] = i; vertices[1] = j; - vertices[3] = p->size + i; vertices[4] = j; - vertices[6] = p->size + i; vertices[7] = p->size + j; - vertices[9] = i; vertices[10] = p->size + j; + vertices[vert_idx] = i; vertices[vert_idx+1] = j; + vertices[vert_idx+2] = p->size + i; vertices[vert_idx+3] = j; + vertices[vert_idx+4] = p->size + i; vertices[vert_idx+5] = p->size + j; + vertices[vert_idx+6] = i; vertices[vert_idx+7] = p->size + j; } else { if ((p->ox <= p->x) && (p->oy <= p->y)) { - vertices[0] = 0 + x + p->ox * zoom; vertices[1] = 0 + y + p->oy * zoom; - vertices[3] = p->size + x + p->x * zoom; vertices[4] = 0 + y + p->y * zoom; - vertices[6] = p->size + x + p->x * zoom; vertices[7] = p->size + y + p->y * zoom; - vertices[9] = 0 + x + p->x * zoom; vertices[10] = p->size + y + p->y * zoom; + vertices[vert_idx+0] = 0 + x + p->ox * zoom; vertices[vert_idx+1] = 0 + y + p->oy * zoom; + vertices[vert_idx+2] = p->size + x + p->x * zoom; vertices[vert_idx+3] = 0 + y + p->y * zoom; + vertices[vert_idx+4] = p->size + x + p->x * zoom; vertices[vert_idx+5] = p->size + y + p->y * zoom; + vertices[vert_idx+6] = 0 + x + p->x * zoom; vertices[vert_idx+7] = p->size + y + p->y * zoom; } else if ((p->ox <= p->x) && (p->oy > p->y)) { - vertices[0] = 0 + x + p->x * zoom; vertices[1] = 0 + y + p->y * zoom; - vertices[3] = p->size + x + p->x * zoom; vertices[4] = 0 + y + p->y * zoom; - vertices[6] = p->size + x + p->x * zoom; vertices[7] = p->size + y + p->y * zoom; - vertices[9] = 0 + x + p->ox * zoom; vertices[10] = p->size + y + p->oy * zoom; + vertices[vert_idx+0] = 0 + x + p->x * zoom; vertices[vert_idx+1] = 0 + y + p->y * zoom; + vertices[vert_idx+2] = p->size + x + p->x * zoom; vertices[vert_idx+3] = 0 + y + p->y * zoom; + vertices[vert_idx+4] = p->size + x + p->x * zoom; vertices[vert_idx+5] = p->size + y + p->y * zoom; + vertices[vert_idx+6] = 0 + x + p->ox * zoom; vertices[vert_idx+7] = p->size + y + p->oy * zoom; } else if ((p->ox > p->x) && (p->oy <= p->y)) { - vertices[0] = 0 + x + p->x * zoom; vertices[1] = 0 + y + p->y * zoom; - vertices[3] = p->size + x + p->ox * zoom; vertices[4] = 0 + y + p->oy * zoom; - vertices[6] = p->size + x + p->x * zoom; vertices[7] = p->size + y + p->y * zoom; - vertices[9] = 0 + x + p->x * zoom; vertices[10] = p->size + y + p->y * zoom; + vertices[vert_idx+0] = 0 + x + p->x * zoom; vertices[vert_idx+1] = 0 + y + p->y * zoom; + vertices[vert_idx+2] = p->size + x + p->ox * zoom; vertices[vert_idx+3] = 0 + y + p->oy * zoom; + vertices[vert_idx+4] = p->size + x + p->x * zoom; vertices[vert_idx+5] = p->size + y + p->y * zoom; + vertices[vert_idx+6] = 0 + x + p->x * zoom; vertices[vert_idx+7] = p->size + y + p->y * zoom; } else if ((p->ox > p->x) && (p->oy > p->y)) { - vertices[0] = 0 + x + p->x * zoom; vertices[1] = 0 + y + p->y * zoom; - vertices[3] = p->size + x + p->x * zoom; vertices[4] = 0 + y + p->y * zoom; - vertices[6] = p->size + x + p->ox * zoom; vertices[7] = p->size + y + p->oy * zoom; - vertices[9] = 0 + x + p->x * zoom; vertices[10] = p->size + y + p->y * zoom; + vertices[vert_idx+0] = 0 + x + p->x * zoom; vertices[vert_idx+1] = 0 + y + p->y * zoom; + vertices[vert_idx+2] = p->size + x + p->x * zoom; vertices[vert_idx+3] = 0 + y + p->y * zoom; + vertices[vert_idx+4] = p->size + x + p->ox * zoom; vertices[vert_idx+5] = p->size + y + p->oy * zoom; + vertices[vert_idx+6] = 0 + x + p->x * zoom; vertices[vert_idx+7] = p->size + y + p->y * zoom; } } - tglColor4f(p->r, p->g, p->b, p->a); - glVertexPointer(3, GL_FLOAT, 0, vertices); - glDrawArrays(GL_QUADS, 0, 4); + /* Setup texture coords */ + texcoords[vert_idx] = 0; texcoords[vert_idx+1] = 0; + texcoords[vert_idx+2] = 1; texcoords[vert_idx+3] = 0; + texcoords[vert_idx+4] = 1; texcoords[vert_idx+5] = 1; + texcoords[vert_idx+6] = 0; texcoords[vert_idx+7] = 1; + + /* Setup color */ + colors[col_idx] = p->r; colors[col_idx+1] = p->g; colors[col_idx+2] = p->b; colors[col_idx+3] = p->a; + colors[col_idx+4] = p->r; colors[col_idx+5] = p->g; colors[col_idx+6] = p->b; colors[col_idx+7] = p->a; + colors[col_idx+8] = p->r; colors[col_idx+9] = p->g; colors[col_idx+10] = p->b; colors[col_idx+11] = p->a; + colors[col_idx+12] = p->r; colors[col_idx+13] = p->g; colors[col_idx+14] = p->b; colors[col_idx+15] = p->a; + + /* Draw if over PARTICLES_PER_ARRAY particles */ + vert_idx += 8; + col_idx += 16; + if (vert_idx >= 2*4*PARTICLES_PER_ARRAY) { + // Draw them all in one fell swoop + glDrawArrays(GL_QUADS, 0, vert_idx / 2); + vert_idx = 0; + col_idx = 0; + } } } } - - // Restore normal display - tglColor4f(1, 1, 1, 1); + // Draw them all in one fell swoop + if (vert_idx) glDrawArrays(GL_QUADS, 0, vert_idx / 2); lua_pushboolean(L, alive || ps->no_stop); return 1; @@ -409,9 +428,6 @@ static int particles_update(lua_State *L) } } - // Restore normal display - tglColor4f(1, 1, 1, 1); - lua_pushboolean(L, alive || ps->no_stop); return 1; } diff --git a/src/particles.h b/src/particles.h index 595364f7131ec402fdb95a0be5c3a43ff922fd05..0b354f6308f7fe364323ee5e738691ba7699cbfa 100644 --- a/src/particles.h +++ b/src/particles.h @@ -42,6 +42,10 @@ typedef struct { int density; bool no_stop; + GLfloat *vertices; + GLfloat *colors; + GLshort *texcoords; + int base; int angle_min, anglev_min, anglea_min;