Move CViewport in its own header,

rename X, Y into TopLeftPos
rename EndX, EndY into BottomRightPos
Factorize code with new methods Contains, Restrict, SetClipping
Change Center param: now takes directly mapPixelPos instead of tilePos + offset.
fix typo in mouse.cpp from previous commit.
This commit is contained in:
Joris 2012-04-26 18:29:43 +02:00
parent 64f2e1d626
commit 13d6e457e2
15 changed files with 337 additions and 330 deletions

View file

@ -500,6 +500,7 @@ set(stratagus_generic_HDRS
src/include/vec2i.h
src/include/version.h
src/include/video.h
src/include/viewport.h
src/include/wav.h
src/include/widgets.h
)

View file

@ -895,18 +895,17 @@ static void DrawMapCursor()
if (Editor.State == EditorEditTile && Editor.SelectedTileIndex != -1) {
const unsigned short frame = Map.Tileset.Table[Editor.ShownTileTypes[Editor.SelectedTileIndex]];
PushClipping();
SetClipping(UI.MouseViewport->X, UI.MouseViewport->Y,
UI.MouseViewport->EndX, UI.MouseViewport->EndY);
UI.MouseViewport->SetClipping();
PixelPos screenPosIt;
for (int j = 0; j < TileCursorSize; ++j) {
screenPosIt.y = screenPos.y + j * PixelTileSize.y;
if (screenPosIt.y >= UI.MouseViewport->EndY) {
if (screenPosIt.y >= UI.MouseViewport->GetBottomRightPos().y) {
break;
}
for (int i = 0; i < TileCursorSize; ++i) {
screenPosIt.x = screenPos.x + i * PixelTileSize.x;
if (screenPosIt.x >= UI.MouseViewport->EndX) {
if (screenPosIt.x >= UI.MouseViewport->GetBottomRightPos().x) {
break;
}
Map.TileGraphic->DrawFrameClip(frame, screenPosIt.x, screenPosIt.y);
@ -919,8 +918,7 @@ static void DrawMapCursor()
// is drawn somewhere else (Check DrawUnitSelection.)
if (UnitUnderCursor != NULL) {
PushClipping();
SetClipping(UI.MouseViewport->X, UI.MouseViewport->Y,
UI.MouseViewport->EndX, UI.MouseViewport->EndY);
UI.MouseViewport->SetClipping();
Video.DrawRectangleClip(ColorWhite, screenPos.x, screenPos.y, PixelTileSize.x, PixelTileSize.y);
PopClipping();
}
@ -936,7 +934,7 @@ static void DrawStartLocations()
const CUnitType *type = Editor.StartUnit;
for (const CViewport *vp = UI.Viewports; vp < UI.Viewports + UI.NumViewports; ++vp) {
PushClipping();
SetClipping(vp->X, vp->Y, vp->EndX, vp->EndY);
vp->SetClipping();
for (int i = 0; i < PlayerMax; i++) {
if (Map.Info.PlayerType[i] != PlayerNobody && Map.Info.PlayerType[i] != PlayerNeutral) {
@ -956,7 +954,6 @@ static void DrawStartLocations()
}
}
}
PopClipping();
}
}
@ -1180,7 +1177,7 @@ static void EditorCallbackButtonDown(unsigned button)
if (MouseButtons & LeftButton) { // enter move mini-mode
const PixelPos cursorPixelPos = {CursorX, CursorY};
const Vec2i tilePos = UI.Minimap.ScreenToTilePos(cursorPixelPos);
UI.SelectedViewport->Center(tilePos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(tilePos));
}
return;
}
@ -1303,7 +1300,8 @@ static void EditorCallbackButtonDown(unsigned button)
}
}
CViewport *vp = GetViewport(CursorX, CursorY);
const PixelPos cursorScreenpos = {CursorX, CursorY};
CViewport *vp = GetViewport(cursorScreenpos);
Assert(vp);
if ((MouseButtons & LeftButton) && UI.SelectedViewport != vp) {
// viewport changed
@ -1540,6 +1538,7 @@ static void EditorCallbackMouse(int x, int y)
char buf[256];
HandleCursorMove(&x, &y); // Reduce to screen
const PixelPos screenPos = {x, y};
//
// Move map.
@ -1579,8 +1578,8 @@ static void EditorCallbackMouse(int x, int y)
}
// Automatically unpress when map tile has changed
const PixelPos screenPos = {CursorX, CursorY};
const Vec2i cursorTilePos = UI.SelectedViewport->ScreenToTilePos(screenPos);
const PixelPos cursorScreenPos = {CursorX, CursorY};
const Vec2i cursorTilePos = UI.SelectedViewport->ScreenToTilePos(cursorScreenPos);
if (LastMapX != cursorTilePos.x || LastMapY != cursorTilePos.y) {
LastMapX = cursorTilePos.x;
@ -1596,18 +1595,18 @@ static void EditorCallbackMouse(int x, int y)
//
// Scroll the map
//
if (CursorX <= UI.SelectedViewport->X) {
if (CursorX <= UI.SelectedViewport->GetTopLeftPos().x) {
vpTilePos.x--;
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
} else if (CursorX >= UI.SelectedViewport->EndX) {
} else if (CursorX >= UI.SelectedViewport->GetBottomRightPos().x) {
vpTilePos.x++;
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
}
if (CursorY <= UI.SelectedViewport->Y) {
if (CursorY <= UI.SelectedViewport->GetTopLeftPos().y) {
vpTilePos.y--;
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
} else if (CursorY >= UI.SelectedViewport->EndY) {
} else if (CursorY >= UI.SelectedViewport->GetBottomRightPos().y) {
vpTilePos.y++;
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
}
@ -1641,7 +1640,7 @@ static void EditorCallbackMouse(int x, int y)
const PixelPos cursorPixelPos = {CursorX, CursorY};
const Vec2i tilePos = UI.Minimap.ScreenToTilePos(cursorPixelPos);
UI.SelectedViewport->Center(tilePos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(tilePos));
return;
}
@ -1653,11 +1652,8 @@ static void EditorCallbackMouse(int x, int y)
Editor.CursorTileIndex = -1;
ButtonUnderCursor = -1;
//
// Minimap
//
if (x >= UI.Minimap.X && x < UI.Minimap.X + UI.Minimap.W
&& y >= UI.Minimap.Y && y < UI.Minimap.Y + UI.Minimap.H) {
if (UI.Minimap.Contains(screenPos)) {
CursorOn = CursorOnMinimap;
}
@ -1727,9 +1723,7 @@ static void EditorCallbackMouse(int x, int y)
}
}
//
// Handle tile area
//
if (Editor.State == EditorEditTile) {
i = 0;
bx = UI.InfoPanel.X + 4;
@ -1770,9 +1764,7 @@ static void EditorCallbackMouse(int x, int y)
}
}
//
// Handle buttons
//
if (UI.InfoPanel.X + 4 < CursorX
&& CursorX < UI.InfoPanel.X + 4 + Editor.Select.Icon->G->Width
&& UI.InfoPanel.Y + 4 < CursorY
@ -1822,10 +1814,7 @@ static void EditorCallbackMouse(int x, int y)
return;
}
if (UI.MenuButton.X != -1) {
if (x >= UI.MenuButton.X
&& x <= UI.MenuButton.X + UI.MenuButton.Style->Width
&& y > UI.MenuButton.Y
&& y <= UI.MenuButton.Y + UI.MenuButton.Style->Height) {
if (UI.MenuButton.Contains(screenPos)) {
ButtonAreaUnderCursor = ButtonAreaMenu;
ButtonUnderCursor = ButtonUnderMenu;
CursorOn = CursorOnButton;
@ -1833,22 +1822,16 @@ static void EditorCallbackMouse(int x, int y)
}
}
//
// Minimap
//
if (x >= UI.Minimap.X && x < UI.Minimap.X + UI.Minimap.W
&& y >= UI.Minimap.Y && y < UI.Minimap.Y + UI.Minimap.H) {
if (UI.Minimap.Contains(screenPos)) {
CursorOn = CursorOnMinimap;
return;
}
//
// Map
//
UnitUnderCursor = NoUnitP;
if (x >= UI.MapArea.X && x <= UI.MapArea.EndX
&& y >= UI.MapArea.Y && y <= UI.MapArea.EndY) {
CViewport *vp = GetViewport(x, y);
if (UI.MapArea.Contains(screenPos)) {
CViewport *vp = GetViewport(screenPos);
Assert(vp);
if (UI.MouseViewport != vp) { // viewport changed
UI.MouseViewport = vp;
@ -1861,11 +1844,10 @@ static void EditorCallbackMouse(int x, int y)
// Look if there is an unit under the cursor.
// FIXME: use Viewport2MapX Viewport2MapY
//
UnitUnderCursor = UnitOnScreen(NULL,
CursorX - UI.MouseViewport->X +
UI.MouseViewport->MapX * PixelTileSize.x + UI.MouseViewport->OffsetX,
CursorY - UI.MouseViewport->Y +
UI.MouseViewport->MapY * PixelTileSize.y + UI.MouseViewport->OffsetY);
const PixelPos cursorScreenPos = {CursorX, CursorY};
const PixelPos cursorMapPos = UI.MouseViewport->ScreenToMapPixelPos(cursorScreenPos);
UnitUnderCursor = UnitOnScreen(NULL, cursorMapPos.x, cursorMapPos.y);
if (UnitUnderCursor != NULL) {
ShowUnitInfo(*UnitUnderCursor);
return;

View file

@ -751,7 +751,7 @@ void CreateGame(const std::string &filename, CMap *map)
UI.SelectedViewport = UI.Viewports;
}
#endif
UI.SelectedViewport->Center(ThisPlayer->StartPos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(ThisPlayer->StartPos));
//
// Various hacks wich must be done after the map is loaded.

View file

@ -60,6 +60,9 @@
#ifndef __MINIMAP_H__
#include "minimap.h"
#endif
#include "viewport.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
@ -140,90 +143,6 @@ public:
#define MAX_NUM_VIEWPORTS 8 /// Number of supported viewports
/**
** A map viewport.
**
** A part of the map displayed on sceen.
**
** CViewport::X CViewport::Y
** CViewport::EndX CViewport::EndY
**
** upper left corner of this viewport is located at pixel
** coordinates (X, Y) with respect to upper left corner of
** stratagus's window, similarly lower right corner of this
** viewport is (EndX, EndY) pixels away from the UL corner of
** stratagus's window.
**
** CViewport::MapX CViewport::MapY
** CViewport::MapWidth CViewport::MapHeight
**
** Tile coordinates of UL corner of this viewport with respect to
** UL corner of the whole map.
**
** CViewport::Unit
**
** Viewport is bound to a unit. If the unit moves the viewport
** changes the position together with the unit.
** @todo binding to a group.
*/
class CViewport
{
public:
CViewport() : X(0), Y(0), EndX(0), EndY(0), MapX(0), MapY(0),
OffsetX(0), OffsetY(0), MapWidth(0), MapHeight(0), Unit(NULL)
{}
~CViewport();
/// Check if pos pixels are within map area
bool IsInsideMapArea(const PixelPos &screenPixelPos) const;
/// Convert screen coordinates into map pixel coordinates
PixelPos ScreenToMapPixelPos(const PixelPos &screenPixelPos) const;
// Convert map pixel coordinates into screen coordinates
PixelPos MapToScreenPixelPos(const PixelPos &mapPixelPos) const;
/// convert screen coordinate into tilepos
Vec2i ScreenToTilePos(const PixelPos &screenPixelPos) const;
/// convert tilepos coordonates into screen (take the top left of the tile)
PixelPos TilePosToScreen_TopLeft(const Vec2i &tilePos) const;
/// convert tilepos coordonates into screen (take the center of the tile)
PixelPos TilePosToScreen_Center(const Vec2i &tilePos) const;
/// Set the current map view to x,y(upper,left corner)
void Set(const Vec2i &tilePos, const PixelDiff &offset);
/// Center map on point in viewport
void Center(const Vec2i &pos, const PixelDiff &offset);
protected:
/// Set the current map view to x,y(upper,left corner)
void Set(const PixelPos &mapPixelPos);
/// Draw the map background
void DrawMapBackgroundInViewport() const;
/// Draw the map fog of war
void DrawMapFogOfWar() const;
public:
/// Draw the full Viewport.
void Draw() const;
void DrawBorder() const;
/// Check if any part of an area is visible in viewport
bool AnyMapAreaVisibleInViewport(const Vec2i &boxmin, const Vec2i &boxmax) const;
//private:
int X; /// Screen pixel left corner x coordinate
int Y; /// Screen pixel upper corner y coordinate
int EndX; /// Screen pixel right x coordinate
int EndY; /// Screen pixel bottom y coordinate
int MapX; /// Map tile left corner x coordinate
int MapY; /// Map tile upper corner y coordinate
int OffsetX; /// X Offset within MapX
int OffsetY; /// Y Offset within MapY
int MapWidth; /// Width in map tiles
int MapHeight; /// Height in map tiles
CUnit *Unit; /// Bound to this unit
};
/**
** Enumeration of the different predefined viewport configurations.
**
@ -977,7 +896,7 @@ extern void RestrictCursorToViewport();
extern void RestrictCursorToMinimap();
/// Get viewport for screen pixel position
extern CViewport *GetViewport(int x, int y);
extern CViewport *GetViewport(const PixelPos &screenPos);
/// Cycle through all available viewport modes
extern void CycleViewportMode(int);
/// Select viewport mode

130
src/include/viewport.h Normal file
View file

@ -0,0 +1,130 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name viewport.h - The Viewport header file. */
//
// (c) Copyright 2012 by Joris Dauphin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; only version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
#ifndef VIEWPORT_H
#define VIEWPORT_H
//@{
#include "vec2i.h"
class CUnit;
/**
** A map viewport.
**
** A part of the map displayed on screen.
**
** CViewport::TopLeftPos
** CViewport::BottomRightPos
**
** upper left corner of this viewport is located at pixel
** coordinates (TopLeftPosTopLeftPos) with respect to upper left corner of
** stratagus's window, similarly lower right corner of this
** viewport is (BottomRightPos) pixels away from the UL corner of
** stratagus's window.
**
** CViewport::MapX CViewport::MapY
** CViewport::MapWidth CViewport::MapHeight
**
** Tile coordinates of UL corner of this viewport with respect to
** UL corner of the whole map.
**
** CViewport::Unit
**
** Viewport is bound to a unit. If the unit moves the viewport
** changes the position together with the unit.
*/
class CViewport
{
public:
CViewport();
~CViewport();
/// Check if pos pixels are within map area
bool IsInsideMapArea(const PixelPos &screenPixelPos) const;
/// Convert screen coordinates into map pixel coordinates
PixelPos ScreenToMapPixelPos(const PixelPos &screenPixelPos) const;
// Convert map pixel coordinates into screen coordinates
PixelPos MapToScreenPixelPos(const PixelPos &mapPixelPos) const;
/// convert screen coordinate into tilepos
Vec2i ScreenToTilePos(const PixelPos &screenPixelPos) const;
/// convert tilepos coordonates into screen (take the top left of the tile)
PixelPos TilePosToScreen_TopLeft(const Vec2i &tilePos) const;
/// convert tilepos coordonates into screen (take the center of the tile)
PixelPos TilePosToScreen_Center(const Vec2i &tilePos) const;
/// Set the current map view to x,y(upper,left corner)
void Set(const Vec2i &tilePos, const PixelDiff &offset);
/// Center map on point in viewport
void Center(const PixelPos &mapPixelPos);
void SetClipping() const;
/// Draw the full Viewport.
void Draw() const;
void DrawBorder() const;
/// Check if any part of an area is visible in viewport
bool AnyMapAreaVisibleInViewport(const Vec2i &boxmin, const Vec2i &boxmax) const;
bool Contains(const PixelPos &screenPos) const;
void Restrict(int &screenPosX, int &screenPosY) const;
PixelSize GetPixelSize() const;
const PixelPos &GetTopLeftPos() const { return TopLeftPos;}
const PixelPos &GetBottomRightPos() const { return BottomRightPos;}
private:
/// Set the current map view to x,y(upper,left corner)
void Set(const PixelPos &mapPixelPos);
/// Draw the map background
void DrawMapBackgroundInViewport() const;
/// Draw the map fog of war
void DrawMapFogOfWar() const;
public:
//private:
PixelPos TopLeftPos; /// Screen pixel top-left corner
PixelPos BottomRightPos; /// Screen pixel bottom-right corner
public:
int MapX; /// Map tile left corner x coordinate
int MapY; /// Map tile upper corner y coordinate
int OffsetX; /// X Offset within MapX
int OffsetY; /// Y Offset within MapY
int MapWidth; /// Width in map tiles
int MapHeight; /// Height in map tiles
CUnit *Unit; /// Bound to this unit
};
//@}
#endif // VIEWPORT_H

View file

@ -29,33 +29,63 @@
//@{
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
#include "stratagus.h"
#include "unit.h"
#include "tileset.h"
#include "video.h"
#include "map.h"
#include "player.h"
#include "pathfinder.h"
#include "ui.h"
#include "missile.h"
#include "unittype.h"
#include "viewport.h"
#include "font.h"
#include "map.h"
#include "missile.h"
#include "pathfinder.h"
#include "player.h"
#include "tileset.h"
#include "unit.h"
#include "unittype.h"
#include "ui.h"
#include "video.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
CViewport::CViewport() : MapX(0), MapY(0),
OffsetX(0), OffsetY(0), MapWidth(0), MapHeight(0), Unit(NULL)
{
this->TopLeftPos.x = this->TopLeftPos.y = 0;
this->BottomRightPos.x = this->BottomRightPos.y = 0;
}
/*----------------------------------------------------------------------------
-- Global functions
----------------------------------------------------------------------------*/
CViewport::~CViewport()
{
}
bool CViewport::Contains(const PixelPos &screenPos) const
{
return this->GetTopLeftPos().x <= screenPos.x && screenPos.x <= this->GetBottomRightPos().x
&& this->GetTopLeftPos().y <= screenPos.y && screenPos.y <= this->GetBottomRightPos().y;
}
void CViewport::Restrict(int &screenPosX, int &screenPosY) const
{
if (screenPosX < this->GetTopLeftPos().x) {
screenPosX = this->GetTopLeftPos().x;
} else if (screenPosX > this->GetBottomRightPos().x - 1) {
screenPosX = this->GetBottomRightPos().x - 1;
}
if (screenPosY < this->GetTopLeftPos().y) {
screenPosY = this->GetTopLeftPos().y;
} else if (screenPosY > this->GetBottomRightPos().y - 1) {
screenPosY = this->GetBottomRightPos().y - 1;
}
}
PixelSize CViewport::GetPixelSize() const
{
return this->BottomRightPos - this->TopLeftPos;
}
void CViewport::SetClipping() const
{
::SetClipping(this->TopLeftPos.x, this->TopLeftPos.y, this->BottomRightPos.x, this->BottomRightPos.y);
}
/**
** Check if any part of an area is visible in a viewport.
@ -88,8 +118,9 @@ bool CViewport::IsInsideMapArea(const PixelPos &screenPixelPos) const
// Convert viewport coordinates into map pixel coordinates
PixelPos CViewport::ScreenToMapPixelPos(const PixelPos &screenPixelPos) const
{
const int x = screenPixelPos.x - this->X + this->MapX * PixelTileSize.x + this->OffsetX;
const int y = screenPixelPos.y - this->Y + this->MapY * PixelTileSize.y + this->OffsetY;
const PixelDiff relPos = screenPixelPos - this->TopLeftPos;
const int x = relPos.x + this->MapX * PixelTileSize.x + this->OffsetX;
const int y = relPos.y + this->MapY * PixelTileSize.y + this->OffsetY;
const PixelPos mapPixelPos = {x, y};
return mapPixelPos;
@ -98,11 +129,11 @@ PixelPos CViewport::ScreenToMapPixelPos(const PixelPos &screenPixelPos) const
// Convert map pixel coordinates into viewport coordinates
PixelPos CViewport::MapToScreenPixelPos(const PixelPos &mapPixelPos) const
{
PixelPos screenPixelPos = {
mapPixelPos.x + this->X - (this->MapX * PixelTileSize.x + this->OffsetX),
mapPixelPos.y + this->Y - (this->MapY * PixelTileSize.y + this->OffsetY)
const PixelDiff relPos = {
mapPixelPos.x - (this->MapX * PixelTileSize.x + this->OffsetX),
mapPixelPos.y - (this->MapY * PixelTileSize.y + this->OffsetY)
};
return screenPixelPos;
return this->TopLeftPos + relPos;
}
/// convert screen coordinate into tilepos
@ -144,8 +175,9 @@ void CViewport::Set(const PixelPos &mapPos)
x = std::max(x, -UI.MapArea.ScrollPaddingLeft);
y = std::max(y, -UI.MapArea.ScrollPaddingTop);
x = std::min(x, Map.Info.MapWidth * PixelTileSize.x - (this->EndX - this->X) - 1 + UI.MapArea.ScrollPaddingRight);
y = std::min(y, Map.Info.MapHeight * PixelTileSize.y - (this->EndY - this->Y) - 1 + UI.MapArea.ScrollPaddingBottom);
const PixelSize pixelSize = this->GetPixelSize();
x = std::min(x, Map.Info.MapWidth * PixelTileSize.x - (pixelSize.x) - 1 + UI.MapArea.ScrollPaddingRight);
y = std::min(y, Map.Info.MapHeight * PixelTileSize.y - (pixelSize.y) - 1 + UI.MapArea.ScrollPaddingBottom);
this->MapX = x / PixelTileSize.x;
if (x < 0 && x % PixelTileSize.x) {
@ -163,8 +195,8 @@ void CViewport::Set(const PixelPos &mapPos)
if (this->OffsetY < 0) {
this->OffsetY += PixelTileSize.y;
}
this->MapWidth = ((this->EndX - this->X) + this->OffsetX - 1) / PixelTileSize.x + 1;
this->MapHeight = ((this->EndY - this->Y) + this->OffsetY - 1) / PixelTileSize.y + 1;
this->MapWidth = (pixelSize.x + this->OffsetX - 1) / PixelTileSize.x + 1;
this->MapHeight = (pixelSize.y + this->OffsetY - 1) / PixelTileSize.y + 1;
}
/**
@ -185,16 +217,11 @@ void CViewport::Set(const Vec2i &tilePos, const PixelDiff &offset)
/**
** Center map viewport v on map tile (pos).
**
** @param pos map tile position.
** @param offset offset in tile.
** @param mapPixelPos map pixel position.
*/
void CViewport::Center(const Vec2i &pos, const PixelDiff &offset)
void CViewport::Center(const PixelPos &mapPixelPos)
{
const int x = pos.x * PixelTileSize.x + offset.x - (this->EndX - this->X) / 2;
const int y = pos.y * PixelTileSize.y + offset.y - (this->EndY - this->Y) / 2;
const PixelPos mapPixelPos = {x, y};
this->Set(mapPixelPos);
this->Set(mapPixelPos - this->GetPixelSize() / 2);
}
/**
@ -224,10 +251,10 @@ void CViewport::Center(const Vec2i &pos, const PixelDiff &offset)
*/
void CViewport::DrawMapBackgroundInViewport() const
{
int ex = this->EndX;
int ex = this->BottomRightPos.x;
int ey = this->BottomRightPos.y;
int sy = this->MapY;
int dy = this->Y - this->OffsetY;
int ey = this->EndY;
int dy = this->TopLeftPos.y - this->OffsetY;
const int map_max = Map.Info.MapWidth * Map.Info.MapHeight;
unsigned short int tile;
@ -247,7 +274,7 @@ void CViewport::DrawMapBackgroundInViewport() const
}
*/
int sx = this->MapX + sy;
int dx = this->X - this->OffsetX;
int dx = this->TopLeftPos.x - this->OffsetX;
while (dx <= ex && (sx - sy < Map.Info.MapWidth)) {
if (sx - sy < 0) {
++sx;
@ -309,7 +336,7 @@ void CViewport::DrawMapBackgroundInViewport() const
void CViewport::Draw() const
{
PushClipping();
SetClipping(this->X, this->Y, this->EndX, this->EndY);
this->SetClipping();
/* this may take while */
this->DrawMapBackgroundInViewport();
@ -377,12 +404,8 @@ void CViewport::DrawBorder() const
color = ColorOrange;
}
Video.DrawRectangle(color, this->X, this->Y, this->EndX - this->X + 1,
this->EndY - this->Y + 1);
}
CViewport::~CViewport()
{
const PixelSize pixelSize = this->GetPixelSize();
Video.DrawRectangle(color, this->TopLeftPos.x, this->TopLeftPos.y, pixelSize.x + 1, pixelSize.y + 1);
}
//@}

View file

@ -554,14 +554,14 @@ void CViewport::DrawMapFogOfWar() const
}
my_index += Map.Info.MapWidth;
}
ex = EndX;
ex = this->BottomRightPos.x;
int sy = MapY * Map.Info.MapWidth;
int dy = Y - OffsetY;
ey = EndY;
int dy = this->TopLeftPos.y - OffsetY;
ey = this->BottomRightPos.y;
while (dy <= ey) {
sx = MapX + sy;
int dx = X - OffsetX;
int dx = this->TopLeftPos.x - OffsetX;
while (dx <= ex) {
if (VisibleTable[sx]) {
DrawFogOfWarTile(sx, sy, dx, dy);

View file

@ -251,7 +251,7 @@ static int CclCenterMap(lua_State *l)
LuaCheckArgs(l, 2);
const Vec2i pos = {LuaToNumber(l, 1), LuaToNumber(l, 2)};
UI.SelectedViewport->Center(pos, PixelTileSize);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(pos));
return 0;
}

View file

@ -168,9 +168,7 @@ void DrawMapArea()
if (vp->Unit->Destroyed || vp->Unit->CurrentAction() == UnitActionDie) {
vp->Unit = NoUnitP;
} else {
const PixelSize offset = {vp->Unit->IX + PixelTileSize.x / 2, vp->Unit->IY + PixelTileSize.y / 2};
vp->Center(vp->Unit->tilePos, offset);
vp->Center(vp->Unit->GetMapPixelPosCenter());
}
}
vp->Draw();

View file

@ -154,29 +154,27 @@ static void UiUnselectAll()
*/
static void UiCenterOnGroup(unsigned group, GroupSelectionMode mode = SELECTABLE_BY_RECTANGLE_ONLY)
{
CUnit **units;
int n;
Vec2i pos = { -1, -1};
int n = GetNumberUnitsOfGroup(group, SELECT_ALL);
n = GetNumberUnitsOfGroup(group, SELECT_ALL);
if (n--) {
units = GetUnitsOfGroup(group);
CUnit **units = GetUnitsOfGroup(group);
PixelPos pos = { -1, -1};
// FIXME: what should we do with the removed units? ignore?
if (units[n]->Type && units[n]->Type->CanSelect(mode)) {
pos = units[n]->tilePos;
pos = units[n]->GetMapPixelPosCenter();
}
while (n--) {
if (units[n]->Type && units[n]->Type->CanSelect(mode)) {
if (pos.x != -1) {
pos += (units[n]->tilePos - pos) / 2;
pos += (units[n]->GetMapPixelPosCenter() - pos) / 2;
} else {
pos = units[n]->tilePos;
pos = units[n]->GetMapPixelPosCenter();
}
}
}
if (pos.x != -1) {
UI.SelectedViewport->Center(pos, PixelTileSize / 2);
UI.SelectedViewport->Center(pos);
}
}
}
@ -402,12 +400,12 @@ static void UiCenterOnSelected()
int n = NumSelected;
if (n) {
Vec2i pos = Selected[--n]->tilePos;
PixelPos pos = Selected[--n]->GetMapPixelPosCenter();
while (n--) {
pos += (Selected[n]->tilePos - pos) / 2;
pos += (Selected[n]->GetMapPixelPosCenter() - pos) / 2;
}
UI.SelectedViewport->Center(pos, PixelTileSize / 2);
UI.SelectedViewport->Center(pos);
}
}
@ -465,7 +463,7 @@ static void UiFindIdleWorker()
CurrentButtonLevel = 0;
PlayUnitSound(*Selected[0], VoiceSelected);
SelectionChanged();
UI.SelectedViewport->Center(unit->tilePos, PixelTileSize / 2);
UI.SelectedViewport->Center(unit->GetMapPixelPosCenter());
}
}

View file

@ -1255,7 +1255,7 @@ void CenterOnMessage()
return;
}
const Vec2i pos = {MessagesEventX[MessagesEventIndex], MessagesEventY[MessagesEventIndex]};
UI.SelectedViewport->Center(pos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(pos));
SetMessage(_("~<Event: %s~>"), MessagesEvent[MessagesEventIndex]);
++MessagesEventIndex;
}

View file

@ -676,7 +676,7 @@ static void HandleMouseOn(int x, int y)
} else {
const size_t size = UI.SelectedButtons.size();
for (size_t i = std::min<size_t>(NumSelected, size); i >= 0;) {
for (size_t i = std::min<size_t>(NumSelected, size); i != 0;) {
--i;
if (UI.SelectedButtons[i].Contains(screenPos)) {
ButtonAreaUnderCursor = ButtonAreaSelected;
@ -706,7 +706,7 @@ static void HandleMouseOn(int x, int y)
// Map
if (!on_ui && UI.MapArea.Contains(screenPos)) {
CViewport *vp = GetViewport(x, y);
CViewport *vp = GetViewport(screenPos);
Assert(vp);
// viewport changed
if (UI.MouseViewport != vp) {
@ -755,24 +755,9 @@ void HandleMouseExit()
*/
void RestrictCursorToViewport()
{
if (CursorX < UI.SelectedViewport->X) {
CursorStartX = UI.SelectedViewport->X;
} else if (CursorX >= UI.SelectedViewport->EndX) {
CursorStartX = UI.SelectedViewport->EndX - 1;
} else {
CursorStartX = CursorX;
}
if (CursorY < UI.SelectedViewport->Y) {
CursorStartY = UI.SelectedViewport->Y;
} else if (CursorY >= UI.SelectedViewport->EndY) {
CursorStartY = UI.SelectedViewport->EndY - 1;
} else {
CursorStartY = CursorY;
}
UI.MouseWarpX = CursorX = CursorStartX;
UI.MouseWarpY = CursorY = CursorStartY;
UI.SelectedViewport->Restrict(CursorX, CursorY);
UI.MouseWarpX = CursorStartX = CursorX;
UI.MouseWarpY = CursorStartY = CursorY;
CursorOn = CursorOnMap;
}
@ -843,16 +828,7 @@ void UIHandleMouseMove(int x, int y)
//
if (CursorState == CursorStateRectangle) {
// Restrict cursor to viewport.
if (CursorX < UI.SelectedViewport->X) {
CursorX = UI.SelectedViewport->X;
} else if (CursorX >= UI.SelectedViewport->EndX) {
CursorX = UI.SelectedViewport->EndX - 1;
}
if (CursorY < UI.SelectedViewport->Y) {
CursorY = UI.SelectedViewport->Y;
} else if (CursorY >= UI.SelectedViewport->EndY) {
CursorY = UI.SelectedViewport->EndY - 1;
}
UI.SelectedViewport->Restrict(CursorX, CursorY);
UI.MouseWarpX = CursorX;
UI.MouseWarpY = CursorY;
return;
@ -894,7 +870,7 @@ void UIHandleMouseMove(int x, int y)
const Vec2i cursorPos = {UI.Minimap.Screen2MapX(CursorX), UI.Minimap.Screen2MapY(CursorY)};
RestrictCursorToMinimap();
UI.SelectedViewport->Center(cursorPos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(cursorPos));
return;
}
@ -962,7 +938,7 @@ void UIHandleMouseMove(int x, int y)
//
// Minimap move viewpoint
//
UI.SelectedViewport->Center(cursorPos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(cursorPos));
}
}
// FIXME: must move minimap if right button is down !
@ -989,7 +965,7 @@ void UIHandleMouseMove(int x, int y)
//
const Vec2i cursorPos = {UI.Minimap.Screen2MapX(CursorX), UI.Minimap.Screen2MapY(CursorY)};
UI.SelectedViewport->Center(cursorPos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(cursorPos));
CursorStartX = CursorX;
CursorStartY = CursorY;
return;
@ -1454,7 +1430,7 @@ static void UISelectStateButtonDown(unsigned)
}
SendCommand(cursorTilePos);
} else {
UI.SelectedViewport->Center(cursorTilePos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(cursorTilePos));
}
return;
}
@ -1650,10 +1626,10 @@ void UIHandleButtonDown(unsigned button)
} else if (MouseButtons & LeftButton) { // enter select mode
CursorStartX = CursorX;
CursorStartY = CursorY;
CursorStartScrMapX = CursorStartX - UI.MouseViewport->X +
PixelTileSize.x * UI.MouseViewport->MapX + UI.MouseViewport->OffsetX;
CursorStartScrMapY = CursorStartY - UI.MouseViewport->Y +
PixelTileSize.y * UI.MouseViewport->MapY + UI.MouseViewport->OffsetY;
const PixelPos screenCursorPos = {CursorX, CursorY};
const PixelPos mapCursorPos = UI.MouseViewport->ScreenToMapPixelPos(screenCursorPos);
CursorStartScrMapX = mapCursorPos.x;
CursorStartScrMapY = mapCursorPos.y;
GameCursor = UI.Cross.Cursor;
CursorState = CursorStateRectangle;
} else if (MouseButtons & MiddleButton) {// enter move map mode
@ -1668,7 +1644,7 @@ void UIHandleButtonDown(unsigned button)
const Vec2i cursorTilePos = {UI.Minimap.Screen2MapX(CursorX), UI.Minimap.Screen2MapY(CursorY)};
if (MouseButtons & LeftButton) { // enter move mini-mode
UI.SelectedViewport->Center(cursorTilePos, PixelTileSize / 2);
UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(cursorTilePos));
} else if (MouseButtons & RightButton) {
if (!GameObserve && !GamePaused) {
const PixelPos mapPixelPos = Map.TilePosToMapPixelPos_Center(cursorTilePos);
@ -1708,12 +1684,8 @@ void UIHandleButtonDown(unsigned button)
// clicked on single unit shown
//
if (ButtonUnderCursor == 0 && NumSelected == 1) {
const PixelPos offset = {Selected[0]->IX + PixelTileSize.x / 2,
Selected[0]->IY + PixelTileSize.y / 2
};
PlayGameSound(GameSounds.Click.Sound, MaxSampleVolume);
UI.SelectedViewport->Center(Selected[0]->tilePos, offset);
UI.SelectedViewport->Center(Selected[0]->GetMapPixelPosCenter());
}
//
// clicked on training button
@ -1875,10 +1847,10 @@ void UIHandleButtonUp(unsigned button)
|| CursorStartY < CursorY - 1 || CursorStartY > CursorY + 1) {
int x0 = CursorStartScrMapX;
int y0 = CursorStartScrMapY;
int x1 = CursorX - UI.MouseViewport->X +
UI.MouseViewport->MapX * PixelTileSize.x + UI.MouseViewport->OffsetX;
int y1 = CursorY - UI.MouseViewport->Y +
UI.MouseViewport->MapY * PixelTileSize.y + UI.MouseViewport->OffsetY;
const PixelPos cursorScreenPos = {CursorX, CursorY};
const PixelPos cursorMapPos = UI.MouseViewport->ScreenToMapPixelPos(cursorScreenPos);
int x1 = cursorMapPos.x;
int y1 = cursorMapPos.y;
if (x0 > x1) {
std::swap(x0, x1);
@ -2043,7 +2015,7 @@ void DrawPieMenu()
CLabel label(GetGameFont());
CViewport *vp = UI.SelectedViewport;
PushClipping();
SetClipping(vp->X, vp->Y, vp->EndX, vp->EndY);
vp->SetClipping();
// Draw background
if (UI.PieMenu.G) {

View file

@ -333,8 +333,7 @@ void FreeButtonStyles()
** Takes coordinates of a pixel in stratagus's window and computes
** the map viewport which contains this pixel.
**
** @param x x pixel coordinate with origin at UL corner of screen
** @param y y pixel coordinate with origin at UL corner of screen
** @param screenPos pixel coordinate with origin at UL corner of screen
**
** @return viewport pointer or NULL if this pixel is not inside
** any of the viewports.
@ -342,10 +341,10 @@ void FreeButtonStyles()
** @note This functions only works with rectangular viewports, when
** we support shaped map window, this must be rewritten.
*/
CViewport *GetViewport(int x, int y)
CViewport *GetViewport(const PixelPos &screenPos)
{
for (CViewport *vp = UI.Viewports; vp < UI.Viewports + UI.NumViewports; ++vp) {
if (x >= vp->X && x <= vp->EndX && y >= vp->Y && y <= vp->EndY) {
if (vp->Contains(screenPos)) {
return vp;
}
}
@ -365,26 +364,19 @@ CViewport *GetViewport(int x, int y)
*/
static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
{
if (UI.NumViewports < num_vps) {
// Compute location of the viewport using oldviewport
for (int i = 0; i < num_vps; ++i) {
new_vps[i].MapX = 0;
new_vps[i].MapY = 0;
const CViewport *vp = GetViewport(new_vps[i].X, new_vps[i].Y);
if (vp) {
new_vps[i].OffsetX = new_vps[i].X - vp->X + vp->MapX * PixelTileSize.x + vp->OffsetX;
new_vps[i].OffsetY = new_vps[i].Y - vp->Y + vp->MapY * PixelTileSize.y + vp->OffsetY;
} else {
new_vps[i].OffsetX = 0;
new_vps[i].OffsetY = 0;
}
}
} else {
for (int i = 0; i < num_vps; ++i) {
new_vps[i].MapX = UI.Viewports[i].MapX;
new_vps[i].MapY = UI.Viewports[i].MapY;
new_vps[i].OffsetX = UI.Viewports[i].OffsetX;
new_vps[i].OffsetY = UI.Viewports[i].OffsetY;
// Compute location of the viewport using oldviewport
for (int i = 0; i < num_vps; ++i) {
new_vps[i].MapX = 0;
new_vps[i].MapY = 0;
const CViewport *vp = GetViewport(new_vps[i].GetTopLeftPos());
if (vp) {
const PixelDiff relDiff = new_vps[i].GetTopLeftPos() - vp->GetTopLeftPos();
new_vps[i].OffsetX = relDiff.x + vp->MapX * PixelTileSize.x + vp->OffsetX;
new_vps[i].OffsetY = relDiff.y + vp->MapY * PixelTileSize.y + vp->OffsetY;
} else {
new_vps[i].OffsetX = 0;
new_vps[i].OffsetY = 0;
}
}
@ -392,10 +384,8 @@ static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
for (int i = 0; i < num_vps; ++i) {
CViewport &vp = UI.Viewports[i];
vp.X = new_vps[i].X;
vp.EndX = new_vps[i].EndX;
vp.Y = new_vps[i].Y;
vp.EndY = new_vps[i].EndY;
vp.TopLeftPos = new_vps[i].TopLeftPos;
vp.BottomRightPos = new_vps[i].BottomRightPos;
const Vec2i vpTilePos = {new_vps[i].MapX, new_vps[i].MapY};
const PixelDiff offset = {new_vps[i].OffsetX, new_vps[i].OffsetY};
vp.Set(vpTilePos, offset);
@ -405,7 +395,8 @@ static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
//
// Update the viewport pointers
//
UI.MouseViewport = GetViewport(CursorX, CursorY);
PixelPos CursorScreenPos = {CursorX, CursorY};
UI.MouseViewport = GetViewport(CursorScreenPos);
if (UI.SelectedViewport > UI.Viewports + UI.NumViewports - 1) {
UI.SelectedViewport = UI.Viewports + UI.NumViewports - 1;
}
@ -430,15 +421,15 @@ static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
static void ClipViewport(CViewport &vp, int ClipX, int ClipY)
{
// begin with maximum possible viewport size
vp.EndX = vp.X + Map.Info.MapWidth * PixelTileSize.x - 1;
vp.EndY = vp.Y + Map.Info.MapHeight * PixelTileSize.y - 1;
vp.BottomRightPos.x = vp.TopLeftPos.x + Map.Info.MapWidth * PixelTileSize.x - 1;
vp.BottomRightPos.y = vp.TopLeftPos.y + Map.Info.MapHeight * PixelTileSize.y - 1;
// first clip it to MapArea size if necessary
vp.EndX = std::min<int>(vp.EndX, ClipX);
vp.EndY = std::min<int>(vp.EndY, ClipY);
vp.BottomRightPos.x = std::min<int>(vp.BottomRightPos.x, ClipX);
vp.BottomRightPos.y = std::min<int>(vp.BottomRightPos.y, ClipY);
Assert(vp.EndX <= UI.MapArea.EndX);
Assert(vp.EndY <= UI.MapArea.EndY);
Assert(vp.BottomRightPos.x <= UI.MapArea.EndX);
Assert(vp.BottomRightPos.y <= UI.MapArea.EndY);
}
/**
@ -455,8 +446,8 @@ static void SetViewportModeSingle()
DebugPrint("Single viewport set\n");
new_vps[0].X = UI.MapArea.X;
new_vps[0].Y = UI.MapArea.Y;
new_vps[0].TopLeftPos.x = UI.MapArea.X;
new_vps[0].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[0], UI.MapArea.EndX, UI.MapArea.EndY);
FinishViewportModeConfiguration(new_vps, 1);
@ -478,13 +469,13 @@ static void SetViewportModeSplitHoriz()
DebugPrint("Two horizontal viewports set\n");
new_vps[0].X = UI.MapArea.X;
new_vps[0].Y = UI.MapArea.Y;
new_vps[0].TopLeftPos.x = UI.MapArea.X;
new_vps[0].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[0], UI.MapArea.EndX,
UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
new_vps[1].X = UI.MapArea.X;
new_vps[1].Y = new_vps[0].EndY + 1;
new_vps[1].TopLeftPos.x = UI.MapArea.X;
new_vps[1].TopLeftPos.y = new_vps[0].BottomRightPos.y + 1;
ClipViewport(new_vps[1], UI.MapArea.EndX, UI.MapArea.EndY);
FinishViewportModeConfiguration(new_vps, 2);
@ -507,19 +498,19 @@ static void SetViewportModeSplitHoriz3()
DebugPrint("Horizontal 3-way viewport division set\n");
new_vps[0].X = UI.MapArea.X;
new_vps[0].Y = UI.MapArea.Y;
new_vps[0].TopLeftPos.x = UI.MapArea.X;
new_vps[0].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[0], UI.MapArea.EndX,
UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
new_vps[1].X = UI.MapArea.X;
new_vps[1].Y = new_vps[0].EndY + 1;
new_vps[1].TopLeftPos.x = UI.MapArea.X;
new_vps[1].TopLeftPos.y = new_vps[0].BottomRightPos.y + 1;
ClipViewport(new_vps[1],
UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
UI.MapArea.EndY);
new_vps[2].X = new_vps[1].EndX + 1;
new_vps[2].Y = new_vps[0].EndY + 1;
new_vps[2].TopLeftPos.x = new_vps[1].BottomRightPos.x + 1;
new_vps[2].TopLeftPos.y = new_vps[0].BottomRightPos.y + 1;
ClipViewport(new_vps[2], UI.MapArea.EndX, UI.MapArea.EndY);
FinishViewportModeConfiguration(new_vps, 3);
@ -541,14 +532,14 @@ static void SetViewportModeSplitVert()
DebugPrint("Two vertical viewports set\n");
new_vps[0].X = UI.MapArea.X;
new_vps[0].Y = UI.MapArea.Y;
new_vps[0].TopLeftPos.x = UI.MapArea.X;
new_vps[0].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[0],
UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
UI.MapArea.EndY);
new_vps[1].X = new_vps[0].EndX + 1;
new_vps[1].Y = UI.MapArea.Y;
new_vps[1].TopLeftPos.x = new_vps[0].BottomRightPos.x + 1;
new_vps[1].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[1], UI.MapArea.EndX, UI.MapArea.EndY);
FinishViewportModeConfiguration(new_vps, 2);
@ -570,26 +561,26 @@ static void SetViewportModeQuad()
DebugPrint("Four viewports set\n");
new_vps[0].X = UI.MapArea.X;
new_vps[0].Y = UI.MapArea.Y;
new_vps[0].TopLeftPos.x = UI.MapArea.X;
new_vps[0].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[0],
UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
new_vps[1].X = new_vps[0].EndX + 1;
new_vps[1].Y = UI.MapArea.Y;
new_vps[1].TopLeftPos.x = new_vps[0].BottomRightPos.x + 1;
new_vps[1].TopLeftPos.y = UI.MapArea.Y;
ClipViewport(new_vps[1],
UI.MapArea.EndX,
UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
new_vps[2].X = UI.MapArea.X;
new_vps[2].Y = new_vps[0].EndY + 1;
new_vps[2].TopLeftPos.x = UI.MapArea.X;
new_vps[2].TopLeftPos.y = new_vps[0].BottomRightPos.y + 1;
ClipViewport(new_vps[2],
UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
UI.MapArea.EndY);
new_vps[3].X = new_vps[1].X;
new_vps[3].Y = new_vps[2].Y;
new_vps[3].TopLeftPos.x = new_vps[1].TopLeftPos.x;
new_vps[3].TopLeftPos.y = new_vps[2].TopLeftPos.y;
ClipViewport(new_vps[3], UI.MapArea.EndX, UI.MapArea.EndY);
FinishViewportModeConfiguration(new_vps, 4);

View file

@ -1476,11 +1476,13 @@ bool CUnit::IsVisibleInViewport(const CViewport *vp) const
//
int x = tilePos.x * PixelTileSize.x + IX - (Type->Width - Type->TileWidth * PixelTileSize.x) / 2 + Type->OffsetX;
int y = tilePos.y * PixelTileSize.y + IY - (Type->Height - Type->TileHeight * PixelTileSize.y) / 2 + Type->OffsetY;
const PixelSize vpSize = vp->GetPixelSize();
const PixelPos vpTopLeftMapPos = {vp->MapX * PixelTileSize.x + vp->OffsetX,
vp->MapY * PixelTileSize.y + vp->OffsetY};
const PixelPos vpBottomRightMapPos = vpTopLeftMapPos + vpSize;
if (x + Type->Width < vp->MapX * PixelTileSize.x + vp->OffsetX
|| x > vp->MapX * PixelTileSize.x + vp->OffsetX + (vp->EndX - vp->X)
|| y + Type->Height < vp->MapY * PixelTileSize.y + vp->OffsetY
|| y > vp->MapY * PixelTileSize.y + vp->OffsetY + (vp->EndY - vp->Y)) {
if (x + Type->Width < vpTopLeftMapPos.x || x > vpBottomRightMapPos.x
|| y + Type->Height < vpTopLeftMapPos.y || y > vpBottomRightMapPos.y) {
return false;
}

View file

@ -159,16 +159,7 @@ static void DrawVisibleRectangleCursor(int x, int y, int x1, int y1)
// Clip to map window.
// FIXME: should re-use CLIP_RECTANGLE in some way from linedraw.c ?
//
if (x1 < vp.X) {
x1 = vp.X;
} else if (x1 > vp.EndX) {
x1 = vp.EndX;
}
if (y1 < vp.Y) {
y1 = vp.Y;
} else if (y1 > vp.EndY) {
y1 = vp.EndY;
}
vp.Restrict(x1, y1);
if (x > x1) {
w = x - x1 + 1;
@ -212,7 +203,7 @@ static void DrawBuildingCursor()
}
#endif
PushClipping();
SetClipping(vp.X, vp.Y, vp.EndX, vp.EndY);
vp.SetClipping();
DrawShadow(*CursorBuilding, CursorBuilding->StillFrame, screenPos.x, screenPos.y);
DrawUnitType(*CursorBuilding, CursorBuilding->Sprite, ThisPlayer->Index,
CursorBuilding->StillFrame, screenPos.x, screenPos.y);
@ -281,10 +272,10 @@ void DrawCursor()
{
// Selecting rectangle
if (CursorState == CursorStateRectangle && (CursorStartX != CursorX || CursorStartY != CursorY)) {
DrawVisibleRectangleCursor(
CursorStartScrMapX + UI.MouseViewport->X - PixelTileSize.x * UI.MouseViewport->MapX - UI.MouseViewport->OffsetX,
CursorStartScrMapY + UI.MouseViewport->Y - PixelTileSize.y * UI.MouseViewport->MapY - UI.MouseViewport->OffsetY,
CursorX, CursorY);
const PixelPos cursorStartMapPos = {CursorStartScrMapX, CursorStartScrMapY};
const PixelPos cursorStartScreenPos = UI.MouseViewport->MapToScreenPixelPos(cursorStartMapPos);
DrawVisibleRectangleCursor(cursorStartScreenPos.x, cursorStartScreenPos.y, CursorX, CursorY);
} else if (CursorBuilding && CursorOn == CursorOnMap) {
// Selecting position for building
DrawBuildingCursor();