226 lines
5.1 KiB
C
226 lines
5.1 KiB
C
/*
|
|
This file is part of Warzone 2100.
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
Warzone 2100 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 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/**
|
|
* @file advvis.c
|
|
*
|
|
* Makes smooth transitions for terrain visibility.
|
|
*/
|
|
|
|
#include "lib/framework/frame.h"
|
|
#include "lib/gamelib/gtime.h"
|
|
|
|
#include "advvis.h"
|
|
#include "display3d.h"
|
|
#include "hci.h"
|
|
#include "map.h"
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
#define FADE_IN_TIME (GAME_TICKS_PER_SEC/10)
|
|
#define START_DIVIDE (8)
|
|
|
|
static UDWORD avConsidered;
|
|
static UDWORD avCalculated;
|
|
static UDWORD avIgnored;
|
|
static BOOL bRevealActive = false;
|
|
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
void avSetStatus(BOOL var)
|
|
{
|
|
debug(LOG_FOG, "avSetStatus: Setting fog of war %s", var ? "ON" : "OFF");
|
|
bRevealActive = var;
|
|
}
|
|
|
|
void avInformOfChange(SDWORD x, SDWORD y)
|
|
{
|
|
MAPTILE *psTile;
|
|
SDWORD lowerX,upperX,lowerY,upperY;
|
|
|
|
psTile= mapTile(x,y);
|
|
if(psTile->level < 0)
|
|
{
|
|
lowerX = player.p.x/TILE_UNITS;
|
|
upperX = lowerX + visibleTiles.x;
|
|
lowerY = player.p.z/TILE_UNITS;
|
|
upperY = lowerY + visibleTiles.y;
|
|
if(lowerX<0) lowerX = 0;
|
|
if(lowerY<0) lowerY = 0;
|
|
if(x>lowerX && x<upperX && y>lowerY && y<upperY)
|
|
{
|
|
/* tile is on grid - so initiate fade up */
|
|
psTile->level = 0;
|
|
}
|
|
else
|
|
{
|
|
/* tile is off the grid, so force to maximum and finish */
|
|
psTile->level = psTile->illumination;
|
|
psTile->bMaxed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Already know about this one - so exit */
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
static void processAVTile(UDWORD x, UDWORD y)
|
|
{
|
|
MAPTILE *psTile;
|
|
float newLevel;
|
|
|
|
psTile = mapTile(x, y);
|
|
if (psTile->level < 0 || psTile->bMaxed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
newLevel = psTile->level + timeAdjustedIncrement(FADE_IN_TIME, true);
|
|
if (newLevel >= psTile->illumination)
|
|
{
|
|
psTile->level = psTile->illumination;
|
|
psTile->bMaxed = true;
|
|
}
|
|
else
|
|
{
|
|
psTile->level = newLevel;
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
void avUpdateTiles( void )
|
|
{
|
|
SDWORD startX,startY,endX,endY;
|
|
UDWORD i,j;
|
|
|
|
/* Clear stats */
|
|
avConsidered = 0;
|
|
avCalculated = 0;
|
|
avIgnored = 0;
|
|
|
|
/* Only process the ones on the grid. Find top left */
|
|
if(player.p.x>=0)
|
|
{
|
|
startX = player.p.x/TILE_UNITS;
|
|
}
|
|
else
|
|
{
|
|
startX = 0;
|
|
}
|
|
if(player.p.z >= 0)
|
|
{
|
|
startY = player.p.z/TILE_UNITS;
|
|
}
|
|
else
|
|
{
|
|
startY = 0;
|
|
}
|
|
|
|
/* Find bottom right */
|
|
endX = startX + visibleTiles.x;
|
|
endY = startY + visibleTiles.y;
|
|
|
|
/* Clip, as we may be off map */
|
|
if(startX<0) startX = 0;
|
|
if(startY<0) startY = 0;
|
|
if(endX>(SDWORD)(mapWidth-1)) endX = (SDWORD)(mapWidth-1);
|
|
if(endY>(SDWORD)(mapHeight-1)) endY =(SDWORD)(mapHeight-1);
|
|
|
|
/* Go through the grid */
|
|
for(i=startY; i<(UDWORD)endY; i++)
|
|
{
|
|
for(j=startX; j<(UDWORD)endX; j++)
|
|
{
|
|
processAVTile(j,i);
|
|
}
|
|
}
|
|
|
|
avConsidered = (visibleTiles.x * visibleTiles.y);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
UDWORD avGetObjLightLevel(BASE_OBJECT *psObj,UDWORD origLevel)
|
|
{
|
|
float div = (float)psObj->visible[selectedPlayer] / 255.f;
|
|
|
|
unsigned int lowest = origLevel / START_DIVIDE;
|
|
unsigned int newLevel = div * origLevel;
|
|
|
|
if(newLevel < lowest)
|
|
{
|
|
newLevel = lowest;
|
|
}
|
|
|
|
return newLevel;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
void avGetStats(UDWORD *considered, UDWORD *ignored, UDWORD *calculated)
|
|
{
|
|
*considered = avConsidered;
|
|
*ignored = avIgnored;
|
|
*calculated = avCalculated;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
BOOL getRevealStatus( void )
|
|
{
|
|
return(bRevealActive);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
void setRevealStatus( BOOL val )
|
|
{
|
|
debug(LOG_FOG, "avSetRevealStatus: Setting reveal to %s", val ? "ON" : "OFF");
|
|
bRevealActive = val;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
void preProcessVisibility( void )
|
|
{
|
|
UDWORD i,j;
|
|
MAPTILE *psTile;
|
|
|
|
for(i=0; i<mapWidth;i++)
|
|
{
|
|
for(j=0; j<mapHeight; j++)
|
|
{
|
|
psTile = mapTile(i,j);
|
|
if(TEST_TILE_VISIBLE(selectedPlayer,psTile))
|
|
{
|
|
psTile->bMaxed = true;
|
|
psTile->level = psTile->illumination;
|
|
}
|
|
else
|
|
{
|
|
psTile->level = -1;
|
|
psTile->bMaxed = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
// ------------------------------------------------------------------------------------
|