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:
parent
64f2e1d626
commit
13d6e457e2
15 changed files with 337 additions and 330 deletions
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
130
src/include/viewport.h
Normal 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
|
|
@ -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);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
109
src/ui/ui.cpp
109
src/ui/ui.cpp
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue