Logo Search packages:      
Sourcecode: warzone2100 version File versions

radar.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
*/
#include <string.h>

#include "lib/framework/frame.h"
#include "lib/ivis_common/piedef.h"
#include "lib/ivis_common/rendmode.h"
// FIXME Direct iVis implementation include!
#include "lib/ivis_opengl/piematrix.h"
#include "lib/ivis_common/piepalette.h"
#include "lib/ivis_common/piestate.h"
#include "lib/ivis_common/piefunc.h"
#include "lib/gamelib/gtime.h"
#include "advvis.h"
#include "objects.h"
#include "display3d.h"
#include "map.h"
#include "component.h"
#include "radar.h"
#include "mapdisplay.h"
#include "hci.h"
#include "geometry.h"
#include "intimage.h"
#include "loop.h"
#include "warcam.h"
#include "display.h"
#include "mission.h"
#include "multiplay.h"
#include "intdisplay.h"
#include "texture.h"

#define HIT_NOTIFICATION      (GAME_TICKS_PER_SEC*2)

#define RADAR_DRAW_VIEW_BOX         // If defined then draw a box to show the viewing area.
#define RADAR_TRIANGLE_SIZE         8
#define RADAR_TRIANGLE_HEIGHT RADAR_TRIANGLE_SIZE
#define RADAR_TRIANGLE_WIDTH  (RADAR_TRIANGLE_SIZE/2)

#define RADAR_FRAME_SKIP 10

static PIELIGHT   colRadarAlly, colRadarMe, colRadarEnemy;

BOOL bEnemyAllyRadarColor = false;     //enemy/ally radar color

//current mini-map mode
RADAR_DRAW_MODE   radarDrawMode = RADAR_MODE_DEFAULT;

static PIELIGHT         tileColours[MAX_TILES];
static UDWORD           *radarBuffer = NULL;

PIELIGHT clanColours[MAX_PLAYERS]=
{     // see frontend2.png for team color order.
      // [r,g,b,a]
      {{0,255,0,255}},        // green  Player 0
      {{255,210,40,255}},           // orange Player 1
      {{255,255,255,255}},    // grey   Player 2
      {{0,0,0,255}},                // black  Player 3
      {{255,0,0,255}},        // red    Player 4
      {{20,20,255,255}},            // blue   Player 5
      {{255,0,255,255}},            // pink   Player 6
      {{0,255,255,255}},            // cyan   Player 7
};

static PIELIGHT flashColours[MAX_PLAYERS]=
{     //right now the flash color is all bright red
      {{254,37,37,200}},      // Player 0
      {{254,37,37,200}},      // Player 1
      {{254,37,37,200}},      // Player 2
      {{254,37,37,200}},      // Player 3
      {{254,37,37,200}},      // Player 4  (notice, brighter red)
      {{254,37,37,200}},      // Player 5
      {{254,37,37,200}},      // Player 6
      {{254,37,37,200}}       // Player 7
};

static SDWORD RadarScrollX;
static SDWORD RadarScrollY;
static SDWORD RadarWidth;
static SDWORD RadarHeight;
static SDWORD RadVisWidth;
static SDWORD RadVisHeight;
static SDWORD RadarOffsetX;
static SDWORD RadarOffsetY;
static UWORD RadarZoom;
static SDWORD RadarMapOriginX;
static SDWORD RadarMapOriginY;
static SDWORD RadarMapWidth;
static SDWORD RadarMapHeight;

static void CalcRadarPixelSize(UWORD *SizeH,UWORD *SizeV);
static void CalcRadarScroll(UWORD boxSizeH,UWORD boxSizeV);
static void ClearRadar(UDWORD *screen);
static void DrawRadarTiles(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV);
static void DrawRadarObjects(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV);
static void DrawRadarExtras(UWORD boxSizeH, UWORD boxSizeV);


void radarInitVars(void)
{
      RadarScrollX = 0;
      RadarScrollY = 0;
      RadarWidth = RADWIDTH;
      RadarHeight = RADHEIGHT;
      RadarOffsetX = 0;
      RadarOffsetY = 0;
      RadarZoom = 0;
}

//called for when a new mission is started
void resetRadarRedraw(void)
{
      // nothing here now
}

BOOL InitRadar(void)
{
      radarBuffer = malloc(RADWIDTH * RADHEIGHT * sizeof(UDWORD));
      if (radarBuffer == NULL)
      {
            debug(LOG_ERROR, "Out of memory!");
            abort();
            return false;
      }
      memset(radarBuffer, 0, RADWIDTH * RADHEIGHT * sizeof(UDWORD));

      // Ally/enemy/me colors
      colRadarAlly = WZCOL_YELLOW;
      colRadarEnemy = WZCOL_RED;
      colRadarMe = WZCOL_WHITE;

      pie_InitRadar();

      return true;
}


BOOL ShutdownRadar(void)
{
      pie_ShutdownRadar();

      free(radarBuffer);
      radarBuffer = NULL;

      return true;
}


void SetRadarZoom(UWORD ZoomLevel)
{
      ASSERT( ZoomLevel <= MAX_RADARZOOM,"SetRadarZoom: Max radar zoom exceeded" );

      if (ZoomLevel != RadarZoom)
      {
            RadarZoom = ZoomLevel;
      }
}

UDWORD GetRadarZoom(void)
{
      return RadarZoom;
}


// Given a position within the radar, return a world coordinate.
//
void CalcRadarPosition(UDWORD mX,UDWORD mY,UDWORD *PosX,UDWORD *PosY)
{
      UWORD boxSizeH,boxSizeV;
      SDWORD      sPosX, sPosY;
      SDWORD Xoffset,Yoffset;

      CalcRadarPixelSize(&boxSizeH,&boxSizeV);
      CalcRadarScroll(boxSizeH,boxSizeV);

      // Calculate where on the radar we clicked
      Xoffset=mX-RADTLX-RadarOffsetX;
      // we need to check for negative values (previously this meant that sPosX/Y were becoming huge)
      if (Xoffset<0) Xoffset=0;

      Yoffset=mY-RADTLY-RadarOffsetY;
      if (Yoffset<0) Yoffset=0;

      sPosX = ((Xoffset)/boxSizeH)+RadarScrollX+RadarMapOriginX;
      sPosY = ((Yoffset)/boxSizeV)+RadarScrollY+RadarMapOriginY;

      if (sPosX < scrollMinX)
      {
            sPosX = scrollMinX;
      }
      else if (sPosX > scrollMaxX)
      {
            sPosX = scrollMaxX;
      }
      if (sPosY < scrollMinY)
      {
            sPosY = scrollMinY;
      }
      else if (sPosY > scrollMaxY)
      {
            sPosY = scrollMaxY;
      }
      *PosX = sPosX;
      *PosY = sPosY;
}


// Calculate the radar pixel sizes.
//
static void CalcRadarPixelSize(UWORD *SizeH,UWORD *SizeV)
{
      UWORD Size = (UWORD)(1<<RadarZoom);

      *SizeH = Size;
      *SizeV = Size;
}


// Calculate the radar scroll positions from the current player position.
//
static void CalcRadarScroll(UWORD boxSizeH,UWORD boxSizeV)
{
      SDWORD viewX,viewY;
      SDWORD BorderX;
      SDWORD BorderY;

      RadarMapOriginX = scrollMinX;
      RadarMapOriginY = scrollMinY;
      RadarMapWidth = scrollMaxX- scrollMinX;
      RadarMapHeight = scrollMaxY - scrollMinY;

      RadVisWidth = RadarWidth;
      RadVisHeight = RadarHeight;

      if(RadarMapWidth < RadVisWidth/boxSizeH) {
            RadVisWidth = RadarMapWidth*boxSizeH;
            RadarOffsetX = (RadarWidth-RadVisWidth)/2;
      } else {
            RadarOffsetX = 0;
      }

      if(RadarMapHeight < RadVisHeight/boxSizeV) {
            RadVisHeight = RadarMapHeight*boxSizeV;
            RadarOffsetY = (RadarHeight-RadVisHeight)/2;
      } else {
            RadarOffsetY = 0;
      }

      BorderX = (RadVisWidth - visibleTiles.x*boxSizeH) / 2;
      BorderY = (RadVisHeight - visibleTiles.y*boxSizeV) / 2;
      BorderX /= boxSizeH;
      BorderY /= boxSizeV;

      if(BorderX > 16) {
            BorderX = 16;
      } else if(BorderX < 0) {
            BorderX = 0;
      }

      if(BorderY > 16) {
            BorderY = 16;
      } else if(BorderY < 0) {
            BorderY = 0;
      }

      viewX = ((player.p.x/TILE_UNITS)-RadarScrollX-RadarMapOriginX);
      viewY = ((player.p.z/TILE_UNITS)-RadarScrollY-RadarMapOriginY);

      if(viewX < BorderX) {
            RadarScrollX += viewX-BorderX;
      }

      viewX += visibleTiles.x;
      if(viewX > (RadVisWidth/boxSizeH)-BorderX) {
            RadarScrollX += viewX-(RadVisWidth/boxSizeH)+BorderX;
      }

      if(viewY < BorderY) {
            RadarScrollY += viewY-BorderY;
      }

      viewY += visibleTiles.y;
      if(viewY > (RadVisHeight/boxSizeV)-BorderY) {
            RadarScrollY += viewY-(RadVisHeight/boxSizeV)+BorderY;
      }

      if(RadarScrollX < 0) {
            RadarScrollX = 0;
      } else if(RadarScrollX > RadarMapWidth-(RadVisWidth/boxSizeH)) {
            RadarScrollX = RadarMapWidth-(RadVisWidth/boxSizeH);
      }

      if(RadarScrollY < 0) {
            RadarScrollY = 0;
      } else if(RadarScrollY > RadarMapHeight-(RadVisHeight/boxSizeV)) {
            RadarScrollY = RadarMapHeight-(RadVisHeight/boxSizeV);
      }
}


void drawRadar(void)
{
      UWORD boxSizeH,boxSizeV;
      static int frameSkip = 0;

      ASSERT(radarBuffer, "No radar buffer allocated");
      if (!radarBuffer)
      {
            return;
      }

      CalcRadarPixelSize(&boxSizeH,&boxSizeV);
      CalcRadarScroll(boxSizeH,boxSizeV);

      if(frameSkip<=0)
      {
            if (RadVisWidth != RadarWidth || RadVisHeight != RadarHeight)
            {
                  ClearRadar(radarBuffer);
            }
            DrawRadarTiles(radarBuffer, RADWIDTH, boxSizeH, boxSizeV);
            DrawRadarObjects(radarBuffer, RADWIDTH, boxSizeH, boxSizeV);
            pie_DownLoadRadar(radarBuffer, RADWIDTH, RADHEIGHT);
            frameSkip=RADAR_FRAME_SKIP;
      }
      frameSkip--;

      pie_ClipBegin(RADTLX, RADTLY, RADTLX + RADWIDTH, RADTLY + RADHEIGHT);
      iV_TransBoxFill( RADTLX,RADTLY, RADTLX + RADWIDTH, RADTLY + RADHEIGHT);
      pie_RenderRadar(RADTLX, RADTLY, RADWIDTH, RADHEIGHT);
      DrawRadarExtras(boxSizeH,boxSizeV);
      drawRadarBlips(boxSizeH, boxSizeV, RadarOffsetX, RadarOffsetY);
      pie_ClipEnd();
}


// Clear the radar buffer.
//
static void ClearRadar(UDWORD *screen)
{
      SDWORD i, j;
      UDWORD *pScr = screen;

      for (i = 0; i < RadarWidth; i++)
      {
            for (j = 0; j < RadarHeight; j++)
            {
                  *pScr++ = WZCOL_RADAR_BACKGROUND.rgba;
            }
      }
}

static PIELIGHT appliedRadarColour(RADAR_DRAW_MODE radarDrawMode, MAPTILE *WTile)
{
      PIELIGHT WScr = WZCOL_BLACK;  // squelch warning

      switch(radarDrawMode)
      {
            case RADAR_MODE_TERRAIN:
            {
                  // draw radar terrain on/off feature
                  PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];

                  col.byte.r = sqrtf(col.byte.r * WTile->illumination);
                  col.byte.b = sqrtf(col.byte.b * WTile->illumination);
                  col.byte.g = sqrtf(col.byte.g * WTile->illumination);
                  WScr = col;
            }
            break;
            case RADAR_MODE_COMBINED:
            {
                  // draw radar terrain on/off feature
                  PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];

                  col.byte.r = sqrtf(col.byte.r * (WTile->illumination + WTile->height) / 2);
                  col.byte.b = sqrtf(col.byte.b * (WTile->illumination + WTile->height) / 2);
                  col.byte.g = sqrtf(col.byte.g * (WTile->illumination + WTile->height) / 2);
                  WScr = col;
            }
            break;
            case RADAR_MODE_HEIGHT_MAP:
            {
                  // draw radar terrain on/off feature
                  PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];

                  col.byte.r = (col.byte.r * 3 + WTile->height) / 4;
                  col.byte.b = (col.byte.b * 3 + WTile->height) / 4;
                  col.byte.g = (col.byte.g * 3 + WTile->height) / 4;
                  WScr = col;
            }
            break;
            case RADAR_MODE_NO_TERRAIN:
            {
                  WScr = WZCOL_RADAR_BACKGROUND;
            }
            break;
            case NUM_RADAR_MODES:
            {
                  assert(false);
            }
            break;
      }
      return WScr;
}

// Draw the map tiles on the radar.
//
static void DrawRadarTiles(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV)
{
      MAPTILE     *psTile;
      UWORD SizeH = boxSizeH;
      UWORD SizeV = boxSizeV;
      SDWORD      VisWidth = RadVisWidth;
      SDWORD      VisHeight = RadVisHeight;
      SDWORD      i, j, EndY = VisHeight;
      SDWORD      OffsetX = RadarOffsetX;
      SDWORD      OffsetY = RadarOffsetY;
      UDWORD      *Scr = screen + OffsetX + OffsetY * Modulus;

      ASSERT( (SizeV!=0) && (SizeV!=0) ,"Zero pixel size" );

      /* Get pointer to very first tile */
      psTile = psMapTiles + RadarScrollX + RadarScrollY*mapWidth;
      psTile += RadarMapOriginX + RadarMapOriginY*mapWidth;

      if(SizeH==1)
      {
            for (i=0; i<EndY; i+=SizeH)
            {
                  MAPTILE *WTile = psTile;
                  UDWORD *WScr = Scr;

                  for (j=0; j<VisWidth; j+=SizeV)
                  {
                        if (!getRevealStatus() || TEST_TILE_VISIBLE(selectedPlayer, WTile) || godMode)
                        {
                              *WScr = appliedRadarColour(radarDrawMode, WTile).rgba;
                        } else {
                              *WScr = WZCOL_RADAR_BACKGROUND.rgba;
                        }
                        /* Next pixel, next tile */
                        WScr++;
                        WTile++;
                  }
                  Scr += Modulus;
                  psTile += mapWidth;
            }
      }
      else
      {
            for (i=0; i<EndY; i+=SizeV)
            {
                  MAPTILE *WTile = psTile;

                  for (j=0; j<VisWidth; j+=SizeH)
                  {
                        /* Only draw if discovered or in GOD mode */
                        if (!getRevealStatus() || TEST_TILE_VISIBLE(selectedPlayer, WTile) || godMode)
                        {
                              PIELIGHT col = tileColours[TileNumber_tile(WTile->texture)];
                              UDWORD Val, c, d;
                              UDWORD *Ptr = Scr + j + i * Modulus;

                              col.byte.r = sqrtf(col.byte.r * WTile->illumination);
                              col.byte.b = sqrtf(col.byte.b * WTile->illumination);
                              col.byte.g = sqrtf(col.byte.g * WTile->illumination);
                              Val = col.rgba;

                              for(c=0; c<SizeV; c++)
                              {
                                    UDWORD *WPtr = Ptr;

                                    for(d=0; d<SizeH; d++)
                                    {
                                          *WPtr = appliedRadarColour(radarDrawMode, WTile).rgba;
                                          WPtr++;
                                    }
                                    Ptr += Modulus;
                              }
                        }
                        else
                        {
                              UDWORD c, d;
                              UDWORD *Ptr = Scr + j + i * Modulus;

                              for(c=0; c<SizeV; c++)
                              {
                                    UDWORD *WPtr = Ptr;

                                    for(d=0; d<SizeH; d++)
                                    {
                                          *WPtr = WZCOL_RADAR_BACKGROUND.rgba;
                                          WPtr++;
                                    }
                                    Ptr += Modulus;
                              }
                        }
                        WTile++;
                  }
                  psTile += mapWidth;
            }
      }
}


// Draw the droids and structure positions on the radar.
//
static void DrawRadarObjects(UDWORD *screen,UDWORD Modulus,UWORD boxSizeH,UWORD boxSizeV)
{
      SDWORD                        c,d;
      UBYTE                   clan;
      SDWORD                        x = 0, y = 0;
      DROID                   *psDroid;
      STRUCTURE               *psStruct;
      PROXIMITY_DISPLAY *psProxDisp;
      VIEW_PROXIMITY          *psViewProx;
      UDWORD                        *Ptr,*WPtr;
      SDWORD                        SizeH,SizeV;
      SDWORD                        bw,bh;
      SDWORD                        SSizeH,SSizeV;
      SDWORD                        VisWidth;
      SDWORD                        VisHeight;
      SDWORD                        OffsetX;
      SDWORD                        OffsetY;
      PIELIGHT                playerCol, col;
      PIELIGHT                flashCol;

      SizeH = boxSizeH;
      SizeV = boxSizeV;
      VisWidth = RadVisWidth;
      VisHeight = RadVisHeight;
      OffsetX = RadarOffsetX;
      OffsetY = RadarOffsetY;

      /* Show droids on map - go through all players */
      for(clan = 0; clan < MAX_PLAYERS; clan++)
      {
            //see if have to draw enemy/ally color
            if (bEnemyAllyRadarColor)
            {
                  if (clan == selectedPlayer)
                  {
                        playerCol = colRadarMe;
                  }
                  else
                  {
                        playerCol = (aiCheckAlliances(selectedPlayer, clan) ? colRadarAlly : colRadarEnemy);
                  }
            }
            else
            {
                  //original 8-color mode
                  playerCol = clanColours[getPlayerColour(clan)];
            }

            flashCol = flashColours[getPlayerColour(clan)];

            /* Go through all droids */
            for(psDroid = apsDroidLists[clan]; psDroid != NULL;
                  psDroid = psDroid->psNext)
            {
                  if (psDroid->visible[selectedPlayer]
                      || godMode
                      || (bMultiPlayer && game.alliance == ALLIANCES_TEAMS
                          && aiCheckAlliances(selectedPlayer,psDroid->player)))
                  {
                        x=(psDroid->pos.x/TILE_UNITS)-RadarScrollX;
                        y=(psDroid->pos.y/TILE_UNITS)-RadarScrollY;
                        x -= RadarMapOriginX;
                        y -= RadarMapOriginY;
                        x *= boxSizeH;
                        y *= boxSizeV;

                        {

                              if((x < VisWidth) && (y < VisHeight) && (x >= 0) && (y >= 0)) {
                                    Ptr = screen + x + y*Modulus + OffsetX + OffsetY*Modulus;

                                    if((clan == selectedPlayer) && (gameTime-psDroid->timeLastHit < HIT_NOTIFICATION))
                                    {
                                                col = flashCol;
                                    }
                                    else
                                    {
                                                col = playerCol;
                                    }

                                    for(c=0; c<SizeV; c++)
                                    {
                                          WPtr = Ptr;
                                          for(d=0; d<SizeH; d++)
                                          {
                                                *WPtr = col.rgba;
                                                WPtr++;
                                          }
                                          Ptr += Modulus;
                                    }
                              }
                        }
                  }
            }
      }

      /* Do the same for structures */
      for(clan = 0; clan < MAX_PLAYERS; clan++)
      {
            //see if have to draw enemy/ally color
            if (bEnemyAllyRadarColor)
            {
                  if (clan == selectedPlayer)
                  {
                        playerCol = colRadarMe;
                  }
                  else
                  {
                        playerCol = (aiCheckAlliances(selectedPlayer,clan) ? colRadarAlly: colRadarEnemy);
                  }
            }
            else
            {
                  //original 8-color mode
                  playerCol = clanColours[getPlayerColour(clan)];
            }

            flashCol = flashColours[getPlayerColour(clan)];

            /* Go through all structures */
            for(psStruct = apsStructLists[clan]; psStruct != NULL;
                  psStruct = psStruct->psNext)
            {
                  if (psStruct->visible[selectedPlayer]
                      || godMode
                      || (bMultiPlayer && game.alliance == ALLIANCES_TEAMS
                          && aiCheckAlliances(selectedPlayer,psStruct->player)))
                  {
                        x=(psStruct->pos.x/TILE_UNITS)-RadarScrollX;
                        y=(psStruct->pos.y/TILE_UNITS)-RadarScrollY;
                        x -= RadarMapOriginX;
                        y -= RadarMapOriginY;
                        x *= boxSizeH;
                        y *= boxSizeV;

      // Get structures tile size.
                        bw = (UWORD)psStruct->pStructureType->baseWidth;
                        bh = (UWORD)psStruct->pStructureType->baseBreadth;

      // Need to offset for the structures top left corner.
                        x -= bw >> 1;
                        y -= bh >> 1;
                        x = x&(~(boxSizeH-1));
                        y = y&(~(boxSizeV-1));

                              SSizeH = (SWORD)boxSizeH*bh;
                              SSizeV = (SWORD)boxSizeV*bw;

                              // Clip the structure box.
                              if(x < 0) {
                                    SSizeH += x;
                                    x = 0;
                              }

                              if(y < 0) {
                                    SSizeV += y;
                                    y=0;
                              }

                              if(x+SSizeH > VisWidth) {
                                    SSizeH -= (x+SSizeH) - VisWidth;
                              }

                              if(y+SSizeV > VisHeight) {
                                    SSizeV -= (y+SSizeV) - VisHeight;
                              }

                              // And draw it.
                              if((SSizeV > 0) && (SSizeH > 0)) {
                                    Ptr = screen + x + y*Modulus + OffsetX + OffsetY*Modulus;
                                                                  if((clan == selectedPlayer) && (gameTime - psStruct->timeLastHit < HIT_NOTIFICATION))
                                    {
                                                col = flashCol;
                                    }
                                    else
                                    {
                                                col = playerCol;
                                    }

                                    for(c=0; c<SSizeV; c++)
                                    {
                                          WPtr = Ptr;
                                          for(d=0; d<SSizeH; d++)
                                          {
                                                *WPtr = col.rgba;
                                                WPtr++;
                                          }
                                          Ptr += Modulus;
                                    }
                              }
                  }
            }
      }

      //now set up coords for Proximity Messages - but only for selectedPlayer
      for(psProxDisp = apsProxDisp[selectedPlayer]; psProxDisp != NULL;
            psProxDisp = psProxDisp->psNext)
      {
            if (psProxDisp->type == POS_PROXDATA)
            {
                  psViewProx = (VIEW_PROXIMITY *)((VIEWDATA *)psProxDisp->psMessage->
                        pViewData)->pData;
                  x = (psViewProx->x/TILE_UNITS)-RadarScrollX;
                  y = (psViewProx->y/TILE_UNITS)-RadarScrollY;
            }
            else if (psProxDisp->type == POS_PROXOBJ)
            {
                  x = (((BASE_OBJECT *)psProxDisp->psMessage->pViewData)->pos.x /
                        TILE_UNITS) - RadarScrollX;
                  y = (((BASE_OBJECT *)psProxDisp->psMessage->pViewData)->pos.y /
                        TILE_UNITS) - RadarScrollY;
            }
            x -= RadarMapOriginX;
            y -= RadarMapOriginY;
            x *= boxSizeH;
            y *= boxSizeV;

                  psProxDisp->radarX = 0;
                  psProxDisp->radarY = 0;
                  if((x < VisWidth) && (y < VisHeight) && (x >= 0) && (y >= 0))
                  {
                        //store the coords
                        psProxDisp->radarX = x + OffsetX;
                        psProxDisp->radarY = y + OffsetY;
                  }
      }
}


// Rotate an array of 2d vectors about a given angle, also translates them after rotating.
//
static void RotateVector2D(Vector3i *Vector, Vector3i *TVector, Vector3i *Pos, int Angle, int Count)
{
      int Cos = COS(Angle);
      int Sin = SIN(Angle);
      int ox = 0;
      int oy = 0;
      int i;
      Vector3i *Vec = Vector;
      Vector3i *TVec = TVector;

      if (Pos)
      {
            ox = Pos->x;
            oy = Pos->y;
      }

      for (i = 0; i < Count; i++)
      {
            TVec->x = ( (Vec->x*Cos + Vec->y*Sin) >> FP12_SHIFT ) + ox;
            TVec->y = ( (Vec->y*Cos - Vec->x*Sin) >> FP12_SHIFT ) + oy;
            Vec++;
            TVec++;
      }
}

static SDWORD getDistanceAdjust( void )
{
      UDWORD      origDistance = MAXDISTANCE;
      SDWORD      dif = MAX(origDistance - distance, 0);

      return dif / 100;
}

static SDWORD getLengthAdjust( void )
{
      SDWORD      pitch;
      UDWORD      lookingDown,lookingFar;
      SDWORD      dif;

      pitch = 360 - (player.r.x/DEG_1);

      // Max at
      lookingDown = (0 - MIN_PLAYER_X_ANGLE);
      lookingFar = (0 - MAX_PLAYER_X_ANGLE);
      dif = MAX(pitch - lookingFar, 0);
      if (dif > (lookingDown - lookingFar)) 
      {
            dif = (lookingDown - lookingFar);
      }

      return dif / 2;
}

/* Draws a Myth/FF7 style viewing window */
static void drawViewingWindow(UDWORD x, UDWORD y, UDWORD pixSizeH, UDWORD pixSizeV)
{
      Vector3i v[4], tv[4], centre;
      int   shortX, longX, yDrop, yDropVar;
      int   dif = getDistanceAdjust();
      int   dif2 = getLengthAdjust();
      PIELIGHT colour;

      shortX = ((visibleTiles.x / 4) - (dif / 6)) * pixSizeH;
      longX = ((visibleTiles.x / 2) - (dif / 4)) * pixSizeH;
      yDropVar = ((visibleTiles.y / 2) - (dif2 / 3)) * pixSizeV;
      yDrop = ((visibleTiles.y / 2) - dif2 / 3) * pixSizeV;

      v[0].x = longX;
      v[0].y = -yDropVar;

      v[1].x = -longX;
      v[1].y = -yDropVar;

      v[2].x = shortX;
      v[2].y = yDrop;

      v[3].x = -shortX;
      v[3].y = yDrop;

      centre.x = RADTLX + x + (visibleTiles.x * pixSizeH) / 2;
      centre.y = RADTLY + y + (visibleTiles.y * pixSizeV) / 2;

      RotateVector2D(v,tv,&centre,player.r.y,4);

      switch (getCampaignNumber())
      {
      case 1:
      case 2:
            // white
            colour.byte.r = UBYTE_MAX;
            colour.byte.g = UBYTE_MAX;
            colour.byte.b = UBYTE_MAX;
            colour.byte.a = 0x3f;
            break;
      case 3:
            // greenish
            colour.byte.r = 0x3f;
            colour.byte.a = 0x3f;
            colour.byte.g = UBYTE_MAX;
            colour.byte.b = 0x3f;
      default:
            // black
            colour.rgba = 0;
            colour.byte.a = 0x3f;
            break;

      }

      /* Send the four points to the draw routine and the clip box params */
      pie_DrawViewingWindow(tv,RADTLX,RADTLY,RADTLX+RADWIDTH,RADTLY+RADHEIGHT,colour);
}

static void DrawRadarExtras(UWORD boxSizeH, UWORD boxSizeV)
{
      SDWORD      viewX = ((player.p.x / TILE_UNITS) - RadarScrollX - RadarMapOriginX) * boxSizeH + RadarOffsetX;
      SDWORD      viewY = ((player.p.z / TILE_UNITS) - RadarScrollY - RadarMapOriginY) * boxSizeV + RadarOffsetY;

      viewX = viewX&(~(boxSizeH-1));
      viewY = viewY&(~(boxSizeV-1));

      drawViewingWindow(viewX, viewY, boxSizeH, boxSizeV);
      RenderWindowFrame(FRAME_RADAR, RADTLX - 1, RADTLY - 1, RADWIDTH + 2, RADHEIGHT + 2);
}

// Does a screen coordinate lie within the radar area?
//
BOOL CoordInRadar(int x,int y)
{
      if (x >= RADTLX - 1 && x < RADTLX + RADWIDTH + 1 && y >= RADTLY - 1 && y < RADTLY + RADHEIGHT + 1)
      {
            return true;
      }

      return false;
}

void radarColour(UDWORD tileNumber, uint8_t r, uint8_t g, uint8_t b)
{
      tileColours[tileNumber].byte.r = r;
      tileColours[tileNumber].byte.g = g;
      tileColours[tileNumber].byte.b = b;
      tileColours[tileNumber].byte.a = 255;
}

Generated by  Doxygen 1.6.0   Back to index