Skip to content
Snippets Groups Projects
Commit 0e04d398 authored by dg's avatar dg
Browse files

MiniMap ! default keybind: TAB

move lua lane keeper to a lua file, to avoid 64bits problems


git-svn-id: http://svn.net-core.org/repos/t-engine4@600 51575b47-30f0-44d4-a5cc-537603b46e54
parent 4be0d361
No related branches found
No related tags found
No related merge requests found
......@@ -79,6 +79,13 @@ defineAction{
name = "Look around",
}
defineAction{
default = { "sym:9:false:false:false:false" },
type = "TOGGLE_MINIMAP",
group = "actions",
name = "Toggle minimap",
}
defineAction{
default = { "sym:116:true:false:false:false" },
type = "SHOW_TIME",
......
......@@ -41,6 +41,59 @@ searchOrder = { TERRAIN, TRAP, OBJECT, ACTOR }
color_shown = { 1, 1, 1, 1 }
color_obscure = { 0.6, 0.6, 0.6, 1 }
-- 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 coordonate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks
......@@ -125,19 +178,34 @@ function _M:save()
particles = true,
})
end
function _M:loaded()
self.particles = {}
self.particle = core.display.loadImage("/data/gfx/particle.png"):glTexture()
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.multidisplay)
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),
block_esp = core.fov.newCache(self.w, self.h),
block_sense = core.fov.newCache(self.w, self.h),
}
end
function _M:loaded()
self.particles = {}
self.particle = core.display.loadImage("/data/gfx/particle.png"):glTexture()
self:makeCMap()
local mapseen = function(t, x, y, v)
if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
......@@ -190,7 +258,7 @@ end
--- Recreate the internal map using new dimensions
function _M:recreate()
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.multidisplay)
self:makeCMap()
self.changed = true
self:redisplay()
end
......@@ -220,33 +288,50 @@ function _M:cleanFOV()
self._map:cleanSeen()
end
--- Updates the map on the given spot
-- This updates many things, from the C map object, the FOC caches, the minimap if it exists, ...
function _M:updateMap(x, y)
local g = self(x, y, TERRAIN)
local o = self(x, y, OBJECT)
local a = self(x, y, ACTOR)
local t = self(x, y, TRAP)
if g then g = self.tiles:get(g.display, g.color_r, g.color_g, g.color_b, g.color_br, g.color_bg, g.color_bb, g.image) end
-- Update minimap if any
local mm = MM_FLOOR
if g then
mm = mm + (g:check("block_move") and MM_BLOCK or 0)
mm = mm + (g:check("change_level") and MM_LEVEL_CHANGE or 0)
g = self.tiles:get(g.display, g.color_r, g.color_g, g.color_b, g.color_br, g.color_bg, g.color_bb, g.image)
end
if t then
-- Handles invisibility and telepathy and other such things
if not self.actor_player or t:knownBy(self.actor_player) then
t = self.tiles:get(t.display, t.color_r, t.color_g, t.color_b, t.color_br, t.color_bg, t.color_bb, t.image)
mm = mm + MM_TRAP
else
t = nil
end
end
if o then o = self.tiles:get(o.display, o.color_r, o.color_g, o.color_b, o.color_br, o.color_bg, o.color_bb, o.image) end
if o then
o = self.tiles:get(o.display, o.color_r, o.color_g, o.color_b, o.color_br, o.color_bg, o.color_bb, o.image)
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 = self.tiles:get(a.display, a.color_r, a.color_g, a.color_b, a.color_br, a.color_bg, a.color_bb, a.image)
else
a = nil
end
end
self._map:setGrid(x, y, g, t, o, a)
-- Cache the textures in the C map object
self._map:setGrid(x, y, g, t, o, a, mm)
-- Update FOV caches
if self:checkAllEntities(x, y, "block_sight", self.actor_player) then self._fovcache.block_sight:set(x, y, true)
else self._fovcache.block_sight:set(x, y, false) end
if self:checkAllEntities(x, y, "block_esp", self.actor_player) then self._fovcache.block_esp:set(x, y, true)
......@@ -291,6 +376,12 @@ function _M:remove(x, y, pos)
end
end
--- Displays the minimap
-- @return a surface containing the drawn map
function _M:minimapDisplay(dx, dy, x, y, w, h, transp)
self._map:toScreenMiniMap(dx, dy, x, y, w, h, transp or 0.6)
end
--- Displays the map on a surface
-- @return a surface containing the drawn map
function _M:display()
......
......@@ -178,9 +178,25 @@ function _M:setupDisplayMode()
self.target.target.entity = self.player
self.level.map:moveViewSurround(self.player.x, self.player.y, 8, 8)
end
self:setupMiniMap()
self:saveSettings("tome.gfxmode", ("tome.gfxmode = %d\n"):format(self.gfxmode))
end
function _M:setupMiniMap()
print("[MINIMAP MODE]", self.minimap_mode)
self.minimap_mode = self.minimap_mode or (config.settings.tome and config.settings.tome.minimap_mode) or 1
if self.minimap_mode == 1 then
print("[MINIMAP MODE] disabled")
elseif self.minimap_mode == 2 then
if self.level and self.level.map then self.level.map._map:setupMiniMapGridSize(4) end
print("[MINIMAP MODE] small")
elseif self.minimap_mode == 3 then
if self.level and self.level.map then self.level.map._map:setupMiniMapGridSize(8) end
print("[MINIMAP MODE] full")
end
self:saveSettings("tome.minimap_mode", ("tome.minimap_mode = %d\n"):format(self.minimap_mode))
end
function _M:save()
return class.save(self, self:defaultSavedFields{}, true)
end
......@@ -270,6 +286,8 @@ function _M:changeLevel(lev, zone)
else
self:stopMusic()
end
self:setupMiniMap()
end
function _M:getPlayer()
......@@ -342,6 +360,21 @@ function _M:display()
end
end
]]
if self.minimap_mode == 2 then
self.level.map:minimapDisplay(self.w - 200, 20, util.bound(self.player.x - 25, 0, self.level.map.w - 50), util.bound(self.player.y - 25, 0, self.level.map.h - 50), 50, 50, 0.6)
elseif self.minimap_mode == 3 then
local mx, my = 0, 0
local mw, mh = math.floor((self.w - 200) / 8), math.floor(self.h * .80 / 8)
mx = self.player.x - math.floor(mw / 2)
my = self.player.y - math.floor(mh / 2)
if self.level.map.w < mw then mx = math.floor((self.level.map.w - mw) / 2) end
if self.level.map.h < mh then my = math.floor((self.level.map.h - mh) / 2) end
self.level.map:minimapDisplay(200, 20, mx, my, mw, mh, 0.9)
end
end
engine.GameTurnBased.display(self)
......@@ -596,6 +629,13 @@ function _M:setupCommands()
self:setupDisplayMode()
end,
-- Toggle mini map
TOGGLE_MINIMAP = function()
self.minimap_mode = self.minimap_mode or 1
self.minimap_mode = util.boundWrap(self.minimap_mode + 1, 1, 3)
self:setupMiniMap()
end,
EXIT = function()
local menu menu = require("engine.dialogs.GameMenu").new{
"resume",
......
......@@ -98,6 +98,9 @@ function _M:move(x, y, force)
-- Update wilderness coords
if game.zone.short_name == "wilderness" then
-- Cheat with time
game.turn = game.turn + 1000
self.wild_x, self.wild_y = self.x, self.y
local g = game.level.map(self.x, self.y, Map.TERRAIN)
if g and g.can_encounter and game.level.data.encounters then
......
--
-- KEEPER.LUA
--
-- Keeper state logic
--
-- This code is read in for each "keeper state", which are the hidden, inter-
-- mediate data stores used by Lanes inter-state communication objects.
--
-- Author: Asko Kauppi <akauppi@gmail.com>
--
--[[
===============================================================================
Copyright (C) 2008 Asko Kauppi <akauppi@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
]]--
-- unique key instead of 'nil' in queues
--
assert( nil_sentinel )
-- We only need to have base and table libraries (and io for debugging)
--
local table_remove= assert( table.remove )
local table_concat= assert( table.concat )
local function WR(...)
if io then
io.stderr:write( table_concat({...},'\t').."\n" )
end
end
-----
-- Actual data store
--
-- { [linda_deep_ud]= { key= val [, ...] }
-- ...
-- }
--
local _data= {}
-----
-- Entries queued for use when the existing 'data[ud][key]' entry is consumed.
--
-- { [linda_deep_ud]= { key= { val [, ... } [, ...] }
-- ...
-- }
--
local _incoming= {}
-----
-- Length limits (if any) for queues
--
-- 0: don't queue values at all; ':send()' waits if the slot is not vacant
-- N: allow N values to be queued (slot itself + N-1); wait if full
-- nil: no limits, '_incoming' may grow endlessly
--
local _limits= {}
-----
-- data_tbl, incoming_tbl, limits_tbl = tables( linda_deep_ud )
--
-- Gives appropriate tables for a certain Linda (creates them if needed)
--
local function tables( ud )
-- tables are created either all or nothing
--
if not _data[ud] then
_data[ud]= {}
_incoming[ud]= {}
_limits[ud]= {}
end
return _data[ud], _incoming[ud], _limits[ud]
end
local function DEBUG(title,ud,key)
assert( title and ud and key )
local data,incoming,_= tables(ud)
local s= tostring(data[key])
for _,v in ipairs( incoming[key] or {} ) do
s= s..", "..tostring(v)
end
WR( "*** "..title.." ("..tostring(key).."): ", s )
end
-----
-- bool= send( linda_deep_ud, key, ... )
--
-- Send new data (1..N) to 'key' slot. This send is atomic; all the values
-- end up one after each other (this is why having possibility for sending
-- multiple values in one call is deemed important).
--
-- If the queue has a limit, values are sent only if all of them fit in.
--
-- Returns: 'true' if all the values were placed
-- 'false' if sending would exceed the queue limit (wait & retry)
--
function send( ud, key, ... )
local data,incoming,limits= tables(ud)
local n= select('#',...)
if n==0 then return true end -- nothing to send
-- Initialize queue for all keys that have been used with ':send()'
--
if incoming[key]==nil then
incoming[key]= {}
end
local len= data[key] and 1+#incoming[key] or 0
local m= limits[key]
if m and len+n > m then
return false -- would exceed the limit; try again later
end
for i=1,n do
local val= select(i,...)
-- 'nil' in the data replaced by sentinel
if val==nil then
val= nil_sentinel
end
if len==0 then
data[key]= val
len= 1
else
incoming[key][len]= val
len= len+1
end
end
return true
end
-----
-- [val, key]= receive( linda_deep_ud, key [, ...] )
--
-- Read any of the given keys, consuming the data found. Keys are read in
-- order.
--
function receive( ud, ... )
local data,incoming,_= tables(ud)
for i=1,select('#',...) do
local key= select(i,...)
local val= data[key]
if val~=nil then
if incoming[key] and incoming[key][1]~=nil then
-- pop [1] from 'incoming[key]' into the actual slot
data[key]= table_remove( incoming[key], 1 )
else
data[key]= nil -- empty the slot
end
if val==nil_sentinel then
val= nil
end
return val, key
end
end
--return nil
end
-----
-- = limit( linda_deep_ud, key, uint )
--
function limit( ud, key, n )
local _,_,limits= tables(ud)
limits[key]= n
end
-----
-- void= set( linda_deep_ud, key, [val] )
--
function set( ud, key, val )
local data,incoming,_= tables(ud)
-- Setting a key to 'nil' really clears it; only queing uses sentinels.
--
data[key]= val
incoming[key]= nil
end
-----
-- [val]= get( linda_deep_ud, key )
--
function get( ud, key )
local data,_,_= tables(ud)
local val= data[key]
if val==nil_sentinel then
val= nil
end
return val
end
-----
-- void= clear( linda_deep_ud )
--
-- Clear the data structures used for a Linda (at its destructor)
--
function clear( ud )
_data[ud]= nil
_incoming[ud]= nil
_limits[ud]= nil
end
......@@ -2,7 +2,7 @@
* LANES.C Copyright (c) 2007-08, Asko Kauppi
*
* Multithreading in Lua.
*
*
* History:
* 20-Oct-08 (2.0.2): Added closing of free-running threads, but it does
* not seem to eliminate the occasional segfaults at process
......@@ -124,8 +124,8 @@ THE SOFTWARE.
/*
* Lua code for the keeper states (baked in)
*/
static char keeper_chunk[]=
#include "keeper.lch"
//static char keeper_chunk[]=
//#include "keeper.lch"
struct s_lane;
static bool_t cancel_test( lua_State *L );
......@@ -167,17 +167,17 @@ static bool_t thread_cancel( struct s_lane *s, double secs, bool_t force );
* Push a table stored in registry onto Lua stack.
*
* If there is no existing table, create one if 'create' is TRUE.
*
*
* Returns: TRUE if a table was pushed
* FALSE if no table found, not created, and nothing pushed
*/
static bool_t push_registry_table( lua_State *L, void *key, bool_t create ) {
STACK_GROW(L,3);
lua_pushlightuserdata( L, key );
lua_gettable( L, LUA_REGISTRYINDEX );
if (lua_isnil(L,-1)) {
lua_pop(L,1);
......@@ -187,7 +187,7 @@ static bool_t push_registry_table( lua_State *L, void *key, bool_t create ) {
lua_pushlightuserdata( L, key );
lua_pushvalue(L,-2); // duplicate of the table
lua_settable( L, LUA_REGISTRYINDEX );
// [-1]: table that's also bound in registry
}
return TRUE; // table pushed
......@@ -212,7 +212,7 @@ static int new_require( lua_State *L ) {
STACK_GROW(L,1);
STACK_CHECK(L)
// Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would
// leave us locked, blocking any future 'require' calls from other lanes.
//
......@@ -236,12 +236,12 @@ static int new_require( lua_State *L ) {
/*
* Serialize calls to 'require', if it exists
*/
static
static
void serialize_require( lua_State *L ) {
STACK_GROW(L,1);
STACK_GROW(L,1);
STACK_CHECK(L)
// Check 'require' is there; if not, do nothing
//
lua_getglobal( L, "require" );
......@@ -266,7 +266,7 @@ void serialize_require( lua_State *L ) {
/*
* Pool of keeper states
*
* Access to keeper states is locked (only one OS thread at a time) so the
* Access to keeper states is locked (only one OS thread at a time) so the
* bigger the pool, the less chances of unnecessary waits. Lindas map to the
* keepers randomly, by a hash.
*/
......@@ -292,7 +292,7 @@ static bool_t nil_sentinel;
static const char *init_keepers(void) {
unsigned int i;
for( i=0; i<KEEPER_STATES_N; i++ ) {
// Initialize Keeper states with bare minimum of libs (those required
// by 'keeper.lua')
//
......@@ -306,8 +306,9 @@ static const char *init_keepers(void) {
// Read in the preloaded chunk (and run it)
//
if (luaL_loadbuffer( L, keeper_chunk, sizeof(keeper_chunk), "=lanes_keeper" ))
return "luaL_loadbuffer() failed"; // LUA_ERRMEM
// if (luaL_loadbuffer( L, keeper_chunk, sizeof(keeper_chunk), "=lanes_keeper" ))
// return "luaL_loadbuffer() failed"; // LUA_ERRMEM
luaL_loadfile(L, "/lanes-keeper.lua");
if (lua_pcall( L, 0 /*args*/, 0 /*results*/, 0 /*errfunc*/ )) {
// LUA_ERRRUN / LUA_ERRMEM / LUA_ERRERR
......@@ -323,10 +324,10 @@ static const char *init_keepers(void) {
return NULL; // ok
}
static
static
struct s_Keeper *keeper_acquire( const void *ptr ) {
/*
* Any hashing will do that maps pointers to 0..KEEPER_STATES_N-1
* Any hashing will do that maps pointers to 0..KEEPER_STATES_N-1
* consistently.
*
* Pointers are often aligned by 8 or so - ignore the low order bits
......@@ -338,7 +339,7 @@ struct s_Keeper *keeper_acquire( const void *ptr ) {
return K;
}
static
static
void keeper_release( struct s_Keeper *K ) {
MUTEX_UNLOCK( &K->lock_ );
}
......@@ -353,7 +354,7 @@ void keeper_release( struct s_Keeper *K ) {
* Returns: number of return values (pushed to 'L')
*/
static
int keeper_call( lua_State* K, const char *func_name,
int keeper_call( lua_State* K, const char *func_name,
lua_State *L, struct s_Linda *linda, uint_t starting_index ) {
int args= starting_index ? (lua_gettop(L) - starting_index +1) : 0;
......@@ -426,14 +427,14 @@ LUAG_FUNC( linda_send ) {
STACK_CHECK(KL)
while(TRUE) {
int pushed;
STACK_MID(KL,0)
pushed= keeper_call( K->L, "send", L, linda, key_i );
ASSERT_L( pushed==1 );
ret= lua_toboolean(L,-1);
lua_pop(L,1);
if (ret) {
// Wake up ALL waiting threads
//
......@@ -445,7 +446,7 @@ STACK_MID(KL,0)
} else {
/* limit faced; push until timeout */
cancel= cancel_test( L ); // testing here causes no delays
if (cancel) break;
......@@ -461,7 +462,7 @@ STACK_END(KL,0)
if (cancel)
cancel_error(L);
lua_pushboolean( L, ret );
return 1;
}
......@@ -505,7 +506,7 @@ LUAG_FUNC( linda_receive ) {
break; /* instant timeout */
} else { /* nothing received; wait until timeout */
cancel= cancel_test( L ); // testing here causes no delays
if (cancel) break;
......@@ -611,7 +612,7 @@ LUAG_FUNC( linda_deep ) {
/*
* Identity function of a shared userdata object.
*
*
* lightuserdata= linda_id( "new" [, ...] )
* = linda_id( "delete", lightuserdata )
*
......@@ -626,7 +627,7 @@ LUAG_FUNC( linda_deep ) {
* = linda_id( str, ... )
*
* For any other strings, the ID function must not react at all. This allows
* future extensions of the system.
* future extensions of the system.
*/
LUAG_FUNC( linda_id ) {
const char *which= lua_tostring(L,1);
......@@ -681,19 +682,19 @@ LUAG_FUNC( linda_id ) {
//
// [-2]: linda metatable
// [-1]: metatable's to-be .__index table
lua_pushcfunction( L, LG_linda_send );
lua_setfield( L, -2, "send" );
lua_pushcfunction( L, LG_linda_receive );
lua_setfield( L, -2, "receive" );
lua_pushcfunction( L, LG_linda_limit );
lua_setfield( L, -2, "limit" );
lua_pushcfunction( L, LG_linda_set );
lua_setfield( L, -2, "set" );
lua_pushcfunction( L, LG_linda_get );
lua_setfield( L, -2, "get" );
......@@ -702,10 +703,10 @@ LUAG_FUNC( linda_id ) {
lua_setfield( L, -2, "__index" );
STACK_END(L,1)
return 1;
}
return 0; // unknown request, be quiet
}
......@@ -724,7 +725,7 @@ LUAG_FUNC( linda_id ) {
LUAG_FUNC( set_finalizer )
{
STACK_GROW(L,3);
// Get the current finalizer table (if any)
//
push_registry_table( L, FINALIZER_REG_KEY, TRUE /*do create if none*/ );
......@@ -732,7 +733,7 @@ LUAG_FUNC( set_finalizer )
lua_pushinteger( L, lua_objlen(L,-1)+1 );
lua_pushvalue( L, 1 ); // copy of the function
lua_settable( L, -3 );
lua_pop(L,1);
return 0;
}
......@@ -756,7 +757,7 @@ static int run_finalizers( lua_State *L, int lua_rc )
unsigned error_index, tbl_index;
unsigned n;
int rc= 0;
if (!push_registry_table(L, FINALIZER_REG_KEY, FALSE /*don't create one*/))
return 0; // no finalizers
......@@ -771,7 +772,7 @@ static int run_finalizers( lua_State *L, int lua_rc )
unsigned args= 0;
lua_pushinteger( L,n );
lua_gettable( L, -2 );
// [-1]: function
// [-2]: finalizers table
......@@ -784,7 +785,7 @@ static int run_finalizers( lua_State *L, int lua_rc )
rc= lua_pcall( L, args, 0 /*retvals*/, 0 /*no errfunc*/ );
//
// LUA_ERRRUN / LUA_ERRMEM
if (rc!=0) {
// [-1]: error message
//
......@@ -795,7 +796,7 @@ static int run_finalizers( lua_State *L, int lua_rc )
break;
}
}
lua_remove(L,tbl_index); // take finalizer table out of stack
return rc;
......@@ -820,10 +821,10 @@ struct s_lane {
// S: while S is running, M must keep out of modifying the state
volatile enum e_status status;
//
//
// M: sets to PENDING (before launching)
// S: updates -> RUNNING/WAITING -> DONE/ERROR_ST/CANCELLED
volatile bool_t cancel_request;
//
// M: sets to FALSE, flags TRUE for cancel request
......@@ -836,19 +837,19 @@ struct s_lane {
// S: sets the signal once cancellation is noticed (avoids a kill)
MUTEX_T done_lock_;
//
//
// Lock required by 'done_signal' condition variable, protecting
// lane status changes to DONE/ERROR_ST/CANCELLED.
#endif
volatile enum {
volatile enum {
NORMAL, // normal master side state
KILLED // issued an OS kill
} mstatus;
//
// M: sets to NORMAL, if issued a kill changes to KILLED
// S: not used
struct s_lane * volatile selfdestruct_next;
//
// M: sets to non-NULL if facing lane handle '__gc' cycle but the lane
......@@ -897,7 +898,7 @@ static void selfdestruct_remove( struct s_lane *s ) {
if (s->selfdestruct_next != NULL) {
struct s_lane **ref= (struct s_lane **) &selfdestruct_first;
bool_t found= FALSE;
while( *ref != SELFDESTRUCT_END ) {
if (*ref == s) {
*ref= s->selfdestruct_next;
......@@ -938,7 +939,7 @@ static void selfdestruct_atexit( void ) {
// TBD: Not sure if Windows (multi core) will require the timed approach,
// or single Yield. I don't have machine to test that (so leaving
// for timed approach). -- AKa 25-Oct-2008
#ifdef PLATFORM_LINUX
// It seems enough for Linux to have a single yield here, which allows
// other threads (timer lane) to proceed. Without the yield, there is
......@@ -958,10 +959,10 @@ static void selfdestruct_atexit( void ) {
#endif
{
double t_until= now_secs() + ATEXIT_WAIT_SECS;
while( selfdestruct_first != SELFDESTRUCT_END ) {
YIELD(); // give threads time to act on their cancel
if (now_secs() >= t_until) break;
}
}
......@@ -1077,7 +1078,7 @@ LUAG_FUNC( _single ) {
luaL_error( L, "not implemented!" );
#endif
(void)cores;
return 0;
}
......@@ -1085,10 +1086,10 @@ LUAG_FUNC( _single ) {
/*
* str= lane_error( error_val|str )
*
* Called if there's an error in some lane; add call stack to error message
* Called if there's an error in some lane; add call stack to error message
* just like 'lua.c' normally does.
*
* ".. will be called with the error message and its return value will be the
* ".. will be called with the error message and its return value will be the
* message returned on the stack by lua_pcall."
*
* Note: Rather than modifying the error message itself, it would be better
......@@ -1194,7 +1195,7 @@ static int lane_error( lua_State *L ) {
// Lua 5.1 error handler is limited to one return value; taking stack trace
// via registry
//
if (rc!=0) {
if (rc!=0) {
STACK_GROW(L,1);
lua_pushlightuserdata( L, STACK_TRACE_KEY );
lua_gettable(L, LUA_REGISTRYINDEX);
......@@ -1202,7 +1203,7 @@ static int lane_error( lua_State *L ) {
// For cancellation, a stack trace isn't placed
//
assert( lua_istable(L,2) || (lua_touserdata(L,1)==CANCEL_ERROR) );
// Just leaving the stack trace table on the stack is enough to get
// it through to the master.
}
......@@ -1224,8 +1225,8 @@ static int lane_error( lua_State *L ) {
//
rc2= run_finalizers(L,rc);
if (rc2!=0) {
// Error within a finalizer!
//
// Error within a finalizer!
//
// [-1]: error message
rc= rc2; // we're overruling the earlier script error or normal return
......@@ -1255,9 +1256,9 @@ static int lane_error( lua_State *L ) {
} else {
// leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them
enum e_status st=
(rc==0) ? DONE
: (lua_touserdata(L,1)==CANCEL_ERROR) ? CANCELLED
enum e_status st=
(rc==0) ? DONE
: (lua_touserdata(L,1)==CANCEL_ERROR) ? CANCELLED
: ERROR_ST;
// Posix no PTHREAD_TIMEDJOIN:
......@@ -1280,8 +1281,8 @@ static int lane_error( lua_State *L ) {
//---
// lane_ud= thread_new( function, [libs_str],
// [cancelstep_uint=0],
// lane_ud= thread_new( function, [libs_str],
// [cancelstep_uint=0],
// [prio_int=0],
// [globals_tbl],
// [... args ...] )
......@@ -1303,7 +1304,7 @@ LUAG_FUNC( thread_new )
uint_t args= lua_gettop(L) - FIXED_ARGS;
if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) {
luaL_error( L, "Priority out of range: %d..+%d (%d)",
luaL_error( L, "Priority out of range: %d..+%d (%d)",
THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio );
}
......@@ -1321,7 +1322,7 @@ LUAG_FUNC( thread_new )
//
if (glob!=0) {
STACK_CHECK(L)
if (!lua_istable(L,glob))
if (!lua_istable(L,glob))
luaL_error( L, "Expected table, got %s", luaG_typename(L,glob) );
lua_pushvalue( L, glob );
......@@ -1330,7 +1331,7 @@ STACK_CHECK(L)
// L2 [-1]: table of globals
// "You can change the global environment of a Lua thread using lua_replace"
// (refman-5.0.pdf p. 30)
// (refman-5.0.pdf p. 30)
//
lua_replace( L2, LUA_GLOBALSINDEX );
STACK_END(L,0)
......@@ -1363,7 +1364,7 @@ STACK_MID(L,0)
ASSERT_L( (uint_t)lua_gettop(L2) == 1+args );
ASSERT_L( lua_isfunction(L2,1) );
// 's' is allocated from heap, not Lua, since its life span may surpass
// 's' is allocated from heap, not Lua, since its life span may surpass
// the handle's (if free running thread)
//
ud= lua_newuserdata( L, sizeof(struct s_lane*) );
......@@ -1414,7 +1415,7 @@ STACK_END(L,1)
// Cleanup for a thread userdata. If the thread is still executing, leave it
// alive as a free-running thread (will clean up itself).
//
// * Why NOT cancel/kill a loose thread:
// * Why NOT cancel/kill a loose thread:
//
// At least timer system uses a free-running thread, they should be handy
// and the issue of cancelling/killing threads at gc is not very nice, either
......@@ -1493,7 +1494,7 @@ LUAG_FUNC( thread_cancel )
double secs= 0.0;
uint_t force_i=2;
bool_t force, done= TRUE;
if (lua_isnumber(L,2)) {
secs= lua_tonumber(L,2);
force_i++;
......@@ -1501,7 +1502,7 @@ LUAG_FUNC( thread_cancel )
force_i++;
force= lua_toboolean(L,force_i); // FALSE if nothing there
// We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN)
//
if (s->status < DONE) {
......@@ -1516,7 +1517,7 @@ LUAG_FUNC( thread_cancel )
static bool_t thread_cancel( struct s_lane *s, double secs, bool_t force )
{
bool_t done=
bool_t done=
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN)
THREAD_WAIT( &s->thread, secs );
#else
......@@ -1551,7 +1552,7 @@ LUAG_FUNC( thread_status )
struct s_lane *s= lua_toLane(L,1);
enum e_status st= s->status; // read just once (volatile)
const char *str;
if (s->mstatus == KILLED)
st= CANCELLED;
......@@ -1583,7 +1584,7 @@ LUAG_FUNC( thread_join )
lua_State *L2= s->L;
int ret;
bool_t done=
bool_t done=
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN)
THREAD_WAIT( &s->thread, wait_secs );
#else
......@@ -1597,7 +1598,7 @@ LUAG_FUNC( thread_join )
STACK_GROW( L, 1 );
switch( s->status ) {
case DONE: {
case DONE: {
uint_t n= lua_gettop(L2); // whole L2 stack
luaG_inter_move( L2,L, n );
ret= n;
......@@ -1612,7 +1613,7 @@ LUAG_FUNC( thread_join )
case CANCELLED:
ret= 0;
break;
default:
fprintf( stderr, "Status: %d\n", s->status );
ASSERT_L( FALSE ); ret= 0;
......@@ -1652,7 +1653,7 @@ void push_timer_gateway( lua_State *L ) {
lua_call( L, 1 /*args*/, 1 /*retvals*/ );
ASSERT_L( lua_isuserdata(L,-1) );
// Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer
//
p= * (DEEP_PRELUDE**) lua_touserdata( L, -1 );
......@@ -1661,7 +1662,7 @@ void push_timer_gateway( lua_State *L ) {
// [-1]: proxy for accessing the Linda
} else {
/* Push a proxy based on the deep userdata we stored.
/* Push a proxy based on the deep userdata we stored.
*/
luaG_push_proxy( L, LG_linda_id, p );
}
......@@ -1696,7 +1697,7 @@ LUAG_FUNC( wakeup_conv )
// .yday (day of the year)
// .isdst (daylight saving on/off)
STACK_CHECK(L)
STACK_CHECK(L)
lua_getfield( L, 1, "year" ); year= lua_tointeger(L,-1); lua_pop(L,1);
lua_getfield( L, 1, "month" ); month= lua_tointeger(L,-1); lua_pop(L,1);
lua_getfield( L, 1, "day" ); day= lua_tointeger(L,-1); lua_pop(L,1);
......@@ -1745,7 +1746,7 @@ LUAG_FUNC( wakeup_conv )
lua_setglobal( L, #name )
int
int
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
__declspec(dllexport)
#endif
......@@ -1765,12 +1766,12 @@ __declspec(dllexport)
#if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU)
chudInitialize();
#endif
// Locks for 'tools.c' inc/dec counters
//
MUTEX_INIT( &deep_lock );
MUTEX_INIT( &mtid_lock );
// Serialize calls to 'require' from now on, also in the primary state
//
MUTEX_RECURSIVE_INIT( &require_cs );
......@@ -1787,15 +1788,15 @@ __declspec(dllexport)
// allowed for sudo'ers. SCHED_OTHER (default) has no priorities.
// SCHED_OTHER threads are always lower priority than SCHED_RR.
//
// ^-- those apply to 2.6 kernel. IF **wishful thinking** these
// constraints will change in the future, non-sudo priorities can
// ^-- those apply to 2.6 kernel. IF **wishful thinking** these
// constraints will change in the future, non-sudo priorities can
// be enabled also for Linux.
//
#ifdef PLATFORM_LINUX
sudo= geteuid()==0; // we are root?
// If lower priorities (-2..-1) are wanted, we need to lift the main
// thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below
// thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below
// the launched threads (even -2).
//
#ifdef LINUX_SCHED_RR
......@@ -1806,10 +1807,10 @@ __declspec(dllexport)
#endif
#endif
err= init_keepers();
if (err)
if (err)
luaL_error( L, "Unable to initialize: %s", err );
}
// Linda identity function
//
REG_FUNC( linda_id );
......@@ -1835,7 +1836,7 @@ __declspec(dllexport)
REG_FUNC( now_secs );
REG_FUNC( wakeup_conv );
push_timer_gateway(L);
push_timer_gateway(L);
lua_setglobal( L, "timer_gateway" );
REG_INT2( max_prio, THREAD_PRIO_MAX );
......
......@@ -446,7 +446,6 @@ int main(int argc, char *argv[])
luaopen_mime_core(L);
luaopen_struct(L);
luaopen_profiler(L);
luaopen_lanes(L);
luaopen_lpeg(L);
luaopen_map(L);
luaopen_particles(L);
......@@ -513,6 +512,9 @@ int main(int argc, char *argv[])
/* Sets up OpenGL double buffering */
resizeWindow(WIDTH, HEIGHT);
// Now we can open lua lanes, the physfs paths are set and it can load it's lanes-keeper.lua file
luaopen_lanes(L);
// And run the lua engine scripts
luaL_loadfile(L, "/engine/init.lua");
docall(L, 0, 0);
......
......@@ -28,6 +28,16 @@
#include <SDL.h>
#include <SDL_ttf.h>
// 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);
......@@ -48,6 +58,9 @@ 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->multidisplay = multidisplay;
map->w = w;
map->h = h;
......@@ -64,7 +77,8 @@ static int map_new(lua_State *L)
map->grids_seens = calloc(w, sizeof(bool*));
map->grids_remembers = calloc(w, sizeof(bool*));
map->grids_lites = calloc(w, sizeof(bool*));
printf("size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight);
map->minimap = calloc(w, sizeof(unsigned char*));
printf("C Map size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight);
int i;
for (i = 0; i < w; i++)
......@@ -76,6 +90,7 @@ static int map_new(lua_State *L)
map->grids_seens[i] = calloc(h, sizeof(bool));
map->grids_remembers[i] = calloc(h, sizeof(bool));
map->grids_lites[i] = calloc(h, sizeof(bool));
map->minimap[i] = calloc(h, sizeof(unsigned char));
}
......@@ -109,6 +124,7 @@ static int map_free(lua_State *L)
free(map->grids_seens[i]);
free(map->grids_remembers[i]);
free(map->grids_lites[i]);
free(map->minimap[i]);
}
free(map->grids_terrain);
free(map->grids_actor);
......@@ -117,6 +133,7 @@ static int map_free(lua_State *L)
free(map->grids_seens);
free(map->grids_remembers);
free(map->grids_lites);
free(map->minimap);
lua_pushnumber(L, 1);
return 1;
......@@ -150,6 +167,37 @@ static int map_set_shown(lua_State *L)
return 0;
}
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);
......@@ -159,12 +207,14 @@ static int map_set_grid(lua_State *L)
GLuint *t = lua_isnil(L, 5) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5);
GLuint *o = lua_isnil(L, 6) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 6);
GLuint *a = lua_isnil(L, 7) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 7);
unsigned char mm = luaL_checknumber(L, 8);
if (x < 0 || y < 0 || x >= map->w || y >= map->h) return 0;
map->grids_terrain[x][y] = g ? *g : 0;
map->grids_trap[x][y] = t ? *t : 0;
map->grids_actor[x][y] = a ? *a : 0;
map->grids_object[x][y] = o ? *o : 0;
map->minimap[x][y] = mm;
return 0;
}
......@@ -380,6 +430,157 @@ static int map_to_screen(lua_State *L)
return 0;
}
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;
glColor4f(1, 1, 1, 0.5f);
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])
{
glColor4f(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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
glEnd();
}
}
else
{
glColor4f(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)
{
glBindTexture(GL_TEXTURE_2D, map->mm_level_change);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
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,-99);
glTexCoord2f(1,0); glVertex3f(map->minimap_gridsize +dx, 0 +dy,-99);
glTexCoord2f(1,1); glVertex3f(map->minimap_gridsize +dx, map->minimap_gridsize +dy,-99);
glTexCoord2f(0,1); glVertex3f(0 +dx, map->minimap_gridsize +dy,-99);
glEnd();
}
}
}
}
}
// Restore normal display
glColor4f(1, 1, 1, 1);
return 0;
}
static const struct luaL_reg maplib[] =
{
{"newMap", map_new},
......@@ -401,6 +602,9 @@ static const struct luaL_reg map_reg[] =
{"setLite", map_set_lite},
{"setScroll", map_set_scroll},
{"toScreen", map_to_screen},
{"toScreenMiniMap", minimap_to_screen},
{"setupMiniMap", map_set_minimap},
{"setupMiniMapGridSize", map_set_minimap_gridsize},
{NULL, NULL},
};
......
......@@ -31,6 +31,10 @@ typedef struct {
bool **grids_seens;
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;
int minimap_gridsize;
bool multidisplay;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment