Clean CViewPort interface :
Use PixelPos or Vec2i instead of x, y
This commit is contained in:
parent
22c596f62a
commit
409aa786c4
16 changed files with 302 additions and 364 deletions
src
editor
include
map
particle
stratagus
tolua
ui
unit
video
|
@ -867,13 +867,8 @@ static void DrawEditorPanel()
|
|||
*/
|
||||
static void DrawMapCursor()
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
//
|
||||
// Affect CursorBuilding if necessary.
|
||||
// (Menu reset CursorBuilding)
|
||||
//
|
||||
if (!CursorBuilding) {
|
||||
switch (Editor.State) {
|
||||
case EditorSelecting:
|
||||
|
@ -892,44 +887,42 @@ static void DrawMapCursor()
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw map cursor
|
||||
//
|
||||
if (UI.MouseViewport && !CursorBuilding) {
|
||||
x = UI.MouseViewport->Viewport2MapX(CursorX);
|
||||
y = UI.MouseViewport->Viewport2MapY(CursorY);
|
||||
x = UI.MouseViewport->Map2ViewportX(x);
|
||||
y = UI.MouseViewport->Map2ViewportY(y);
|
||||
const PixelPos screenCursorPos = { CursorX, CursorY };
|
||||
const Vec2i tilePos = UI.MouseViewport->ScreenToTilePos(screenCursorPos);
|
||||
const PixelPos screenPos = UI.MouseViewport->TilePosToScreen_TopLeft(tilePos);
|
||||
|
||||
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);
|
||||
|
||||
PixelPos screenPosIt;
|
||||
for (int j = 0; j < TileCursorSize; ++j) {
|
||||
const int ty = y + j * PixelTileSize.y;
|
||||
if (ty >= UI.MouseViewport->EndY) {
|
||||
screenPosIt.y = screenPos.y + j * PixelTileSize.y;
|
||||
if (screenPosIt.y >= UI.MouseViewport->EndY) {
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < TileCursorSize; ++i) {
|
||||
const int tx = x + i * PixelTileSize.x;
|
||||
if (tx >= UI.MouseViewport->EndX) {
|
||||
screenPosIt.x = screenPos.x + i * PixelTileSize.x;
|
||||
if (screenPosIt.x >= UI.MouseViewport->EndX) {
|
||||
break;
|
||||
}
|
||||
Map.TileGraphic->DrawFrameClip(
|
||||
Map.Tileset.Table[Editor.ShownTileTypes[Editor.SelectedTileIndex]], tx, ty);
|
||||
Map.TileGraphic->DrawFrameClip(frame, screenPosIt.x, screenPosIt.y);
|
||||
}
|
||||
}
|
||||
Video.DrawRectangleClip(ColorWhite, x, y, PixelTileSize.x * TileCursorSize, PixelTileSize.y * TileCursorSize);
|
||||
Video.DrawRectangleClip(ColorWhite, screenPos.x, screenPos.y, PixelTileSize.x * TileCursorSize, PixelTileSize.y * TileCursorSize);
|
||||
PopClipping();
|
||||
} else {
|
||||
//
|
||||
// If there is an unit under the cursor, it's selection thing
|
||||
// is drawn somewhere else (Check DrawUnitSelection.)
|
||||
//
|
||||
if (UnitUnderCursor != NULL) {
|
||||
PushClipping();
|
||||
SetClipping(UI.MouseViewport->X, UI.MouseViewport->Y,
|
||||
UI.MouseViewport->EndX, UI.MouseViewport->EndY);
|
||||
Video.DrawRectangleClip(ColorWhite, x, y, PixelTileSize.x, PixelTileSize.y);
|
||||
Video.DrawRectangleClip(ColorWhite, screenPos.x, screenPos.y, PixelTileSize.x, PixelTileSize.y);
|
||||
PopClipping();
|
||||
}
|
||||
}
|
||||
|
@ -948,14 +941,19 @@ static void DrawStartLocations()
|
|||
|
||||
for (int i = 0; i < PlayerMax; i++) {
|
||||
if (Map.Info.PlayerType[i] != PlayerNobody && Map.Info.PlayerType[i] != PlayerNeutral) {
|
||||
int x = vp->Map2ViewportX(Players[i].StartX);
|
||||
int y = vp->Map2ViewportY(Players[i].StartY);
|
||||
const Vec2i startTilePos = {Players[i].StartX, Players[i].StartY};
|
||||
const PixelPos startScreenPos = vp->TilePosToScreen_TopLeft(startTilePos);
|
||||
|
||||
if (type) {
|
||||
DrawUnitType(*type, type->Sprite, i, 0, x, y);
|
||||
} else {
|
||||
Video.DrawLineClip(PlayerColors[i][0], x, y, x + PixelTileSize.x, y + PixelTileSize.y);
|
||||
Video.DrawLineClip(PlayerColors[i][0], x, y + PixelTileSize.y, x + PixelTileSize.x, y);
|
||||
DrawUnitType(*type, type->Sprite, i, 0, startScreenPos.x, startScreenPos.y);
|
||||
} else { // Draw a cross
|
||||
const int x = startScreenPos.x;
|
||||
const int y = startScreenPos.y;
|
||||
const int w = PixelTileSize.x;
|
||||
const int h = PixelTileSize.y;
|
||||
|
||||
Video.DrawLineClip(PlayerColors[i][0], x, y, x + w, y + h);
|
||||
Video.DrawLineClip(PlayerColors[i][0], x, y + h, x + w, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1182,11 +1180,9 @@ static void EditorCallbackButtonDown(unsigned button)
|
|||
//
|
||||
if (CursorOn == CursorOnMinimap) {
|
||||
if (MouseButtons & LeftButton) { // enter move mini-mode
|
||||
UI.SelectedViewport->Set(
|
||||
UI.Minimap.Screen2MapX(CursorX) -
|
||||
UI.SelectedViewport->MapWidth / 2,
|
||||
UI.Minimap.Screen2MapY(CursorY) -
|
||||
UI.SelectedViewport->MapHeight / 2, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
const Vec2i tilePos = UI.Minimap.ScreenToTilePos(cursorPixelPos);
|
||||
UI.SelectedViewport->Center(tilePos, PixelTileSize / 2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1319,7 +1315,8 @@ static void EditorCallbackButtonDown(unsigned button)
|
|||
}
|
||||
|
||||
if (MouseButtons & LeftButton) {
|
||||
const Vec2i tilePos = { UI.MouseViewport->Viewport2MapX(CursorX), UI.MouseViewport->Viewport2MapY(CursorY)};
|
||||
const PixelPos screenPos = {CursorX, CursorY};
|
||||
const Vec2i tilePos = UI.MouseViewport->ScreenToTilePos(screenPos);
|
||||
|
||||
if (Editor.State == EditorEditTile &&
|
||||
Editor.SelectedTileIndex != -1) {
|
||||
|
@ -1553,47 +1550,46 @@ static void EditorCallbackMouse(int x, int y)
|
|||
// Move map.
|
||||
//
|
||||
if (GameCursor == UI.Scroll.Cursor) {
|
||||
int xo;
|
||||
int yo;
|
||||
Vec2i tilePos = {UI.MouseViewport->MapX, UI.MouseViewport->MapY};
|
||||
|
||||
// FIXME: Support with CTRL for faster scrolling.
|
||||
// FIXME: code duplication, see ../ui/mouse.c
|
||||
xo = UI.MouseViewport->MapX;
|
||||
yo = UI.MouseViewport->MapY;
|
||||
if (UI.MouseScrollSpeedDefault < 0) {
|
||||
if (x < CursorStartX) {
|
||||
xo++;
|
||||
tilePos.x++;
|
||||
} else if (x > CursorStartX) {
|
||||
xo--;
|
||||
tilePos.x--;
|
||||
}
|
||||
if (y < CursorStartY) {
|
||||
yo++;
|
||||
tilePos.y++;
|
||||
} else if (y > CursorStartY) {
|
||||
yo--;
|
||||
tilePos.y--;
|
||||
}
|
||||
} else {
|
||||
if (x < CursorStartX) {
|
||||
xo--;
|
||||
tilePos.x--;
|
||||
} else if (x > CursorStartX) {
|
||||
xo++;
|
||||
tilePos.x++;
|
||||
}
|
||||
if (y < CursorStartY) {
|
||||
yo--;
|
||||
tilePos.y--;
|
||||
} else if (y > CursorStartY) {
|
||||
yo++;
|
||||
tilePos.y++;
|
||||
}
|
||||
}
|
||||
UI.MouseWarpX = CursorStartX;
|
||||
UI.MouseWarpY = CursorStartY;
|
||||
UI.MouseViewport->Set(xo, yo, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
UI.MouseViewport->Set(tilePos, PixelTileSize / 2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Automatically unpress when map tile has changed
|
||||
if (LastMapX != UI.SelectedViewport->Viewport2MapX(CursorX) ||
|
||||
LastMapY != UI.SelectedViewport->Viewport2MapY(CursorY)) {
|
||||
LastMapX = UI.SelectedViewport->Viewport2MapX(CursorX);
|
||||
LastMapY = UI.SelectedViewport->Viewport2MapY(CursorY);
|
||||
const PixelPos screenPos = {CursorX, CursorY};
|
||||
const Vec2i cursorTilePos = UI.SelectedViewport->ScreenToTilePos(screenPos);
|
||||
|
||||
if (LastMapX != cursorTilePos.x || LastMapY != cursorTilePos.y) {
|
||||
LastMapX = cursorTilePos.x;
|
||||
LastMapY = cursorTilePos.y;
|
||||
UnitPlacedThisPress = false;
|
||||
}
|
||||
//
|
||||
|
@ -1601,37 +1597,32 @@ static void EditorCallbackMouse(int x, int y)
|
|||
//
|
||||
if (CursorOn == CursorOnMap && (MouseButtons & LeftButton) &&
|
||||
(Editor.State == EditorEditTile || Editor.State == EditorEditUnit)) {
|
||||
|
||||
Vec2i vpTilePos = {UI.SelectedViewport->MapX, UI.SelectedViewport->MapX};
|
||||
//
|
||||
// Scroll the map
|
||||
//
|
||||
if (CursorX <= UI.SelectedViewport->X) {
|
||||
UI.SelectedViewport->Set(
|
||||
UI.SelectedViewport->MapX - 1,
|
||||
UI.SelectedViewport->MapY, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
vpTilePos.x--;
|
||||
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
|
||||
} else if (CursorX >= UI.SelectedViewport->EndX) {
|
||||
UI.SelectedViewport->Set(
|
||||
UI.SelectedViewport->MapX + 1,
|
||||
UI.SelectedViewport->MapY, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
vpTilePos.x++;
|
||||
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
|
||||
}
|
||||
|
||||
if (CursorY <= UI.SelectedViewport->Y) {
|
||||
UI.SelectedViewport->Set(
|
||||
UI.SelectedViewport->MapX,
|
||||
UI.SelectedViewport->MapY - 1, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
vpTilePos.y--;
|
||||
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
|
||||
} else if (CursorY >= UI.SelectedViewport->EndY) {
|
||||
UI.SelectedViewport->Set(
|
||||
UI.SelectedViewport->MapX,
|
||||
UI.SelectedViewport->MapY + 1, PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
|
||||
vpTilePos.y++;
|
||||
UI.SelectedViewport->Set(vpTilePos, PixelTileSize / 2);
|
||||
}
|
||||
|
||||
//
|
||||
// Scroll the map, if cursor moves outside the viewport.
|
||||
//
|
||||
RestrictCursorToViewport();
|
||||
|
||||
const Vec2i tilePos = {UI.SelectedViewport->Viewport2MapX(CursorX), UI.SelectedViewport->Viewport2MapY(CursorY)};
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
const Vec2i tilePos = UI.SelectedViewport->ScreenToTilePos(cursorPixelPos);
|
||||
|
||||
if (Editor.State == EditorEditTile && Editor.SelectedTileIndex != -1) {
|
||||
EditTiles(tilePos, Editor.ShownTileTypes[Editor.SelectedTileIndex], TileCursorSize);
|
||||
|
@ -1653,11 +1644,10 @@ static void EditorCallbackMouse(int x, int y)
|
|||
//
|
||||
if (CursorOn == CursorOnMinimap && (MouseButtons & LeftButton)) {
|
||||
RestrictCursorToMinimap();
|
||||
UI.SelectedViewport->Set(
|
||||
UI.Minimap.Screen2MapX(CursorX)
|
||||
- UI.SelectedViewport->MapWidth / 2,
|
||||
UI.Minimap.Screen2MapY(CursorY)
|
||||
- UI.SelectedViewport->MapHeight / 2, 0, 0);
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
const Vec2i tilePos = UI.Minimap.ScreenToTilePos(cursorPixelPos);
|
||||
|
||||
UI.SelectedViewport->Center(tilePos, PixelTileSize / 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,9 @@ public:
|
|||
void DrawCursor(int vx, int vy);
|
||||
void AddEvent(int x, int y, Uint32 color);
|
||||
|
||||
int Screen2MapX(int x);
|
||||
int Screen2MapY(int y);
|
||||
Vec2i ScreenToTilePos(const PixelPos& screenPos) const;
|
||||
int Screen2MapX(int x) const;
|
||||
int Screen2MapY(int y) const;
|
||||
|
||||
int X;
|
||||
int Y;
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
void add(CParticle *particle);
|
||||
void clear();
|
||||
|
||||
CPosition getScreenPos(const CPosition &pos);
|
||||
CPosition getScreenPos(const CPosition &pos) const;
|
||||
|
||||
inline void setLowDetail(bool detail) { lowDetail = detail; }
|
||||
inline bool getLowDetail() const { return lowDetail; }
|
||||
|
|
|
@ -169,29 +169,29 @@ public:
|
|||
~CViewport();
|
||||
|
||||
|
||||
/// Check if X and Y pixels are within map area
|
||||
bool IsInsideMapArea(int x, int y) const;
|
||||
/// Convert screen X pixel to map tile
|
||||
int Viewport2MapX(int x) const;
|
||||
/// Convert screen Y pixel to map tile
|
||||
int Viewport2MapY(int y) const;
|
||||
/// Convert map tile to screen X pixel
|
||||
int Map2ViewportX(int x) const;
|
||||
/// Convert map tile to screen Y pixel
|
||||
int Map2ViewportY(int y) const;
|
||||
/// Convert map pixel coordinates into viewport coordinates
|
||||
void MapPixel2Viewport(int &x, int &y) const;
|
||||
/// 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 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;
|
||||
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(int x, int y, int offsetx, int offsety);
|
||||
void Set(const Vec2i &tilePos, const PixelDiff &offset);
|
||||
/// Center map on point in viewport
|
||||
void Center(const Vec2i& pos, const PixelPos &offset);
|
||||
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
|
||||
|
@ -203,8 +203,8 @@ public:
|
|||
void Draw() const;
|
||||
void DrawBorder() const;
|
||||
/// Check if any part of an area is visible in viewport
|
||||
bool AnyMapAreaVisibleInViewport(int sx, int sy, int ex, int ey) const;
|
||||
|
||||
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
|
||||
|
|
|
@ -60,114 +60,36 @@
|
|||
/**
|
||||
** Check if any part of an area is visible in a viewport.
|
||||
**
|
||||
** @param sx X map tile position of area in map to be checked.
|
||||
** @param sy Y map tile position of area in map to be checked.
|
||||
** @param ex X map tile position of area in map to be checked.
|
||||
** @param ey Y map tile position of area in map to be checked.
|
||||
** @param boxmin map tile position of area in map to be checked.
|
||||
** @param boxmax map tile position of area in map to be checked.
|
||||
**
|
||||
** @return True if any part of area is visible, false otherwise
|
||||
*/
|
||||
bool CViewport::AnyMapAreaVisibleInViewport(int sx, int sy, int ex, int ey) const
|
||||
bool CViewport::AnyMapAreaVisibleInViewport(const Vec2i &boxmin, const Vec2i &boxmax) const
|
||||
{
|
||||
if (ex < this->MapX || ey < this->MapY ||
|
||||
sx >= this->MapX + this->MapWidth || sy >= this->MapY + this->MapHeight) {
|
||||
Assert(boxmin.x <= boxmax.x && boxmin.y <= boxmax.y);
|
||||
|
||||
if (boxmax.x < this->MapX
|
||||
|| boxmax.y < this->MapY
|
||||
|| boxmin.x >= this->MapX + this->MapWidth
|
||||
|| boxmin.y >= this->MapY + this->MapHeight) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CViewport::IsInsideMapArea(int x, int y) const
|
||||
bool CViewport::IsInsideMapArea(const PixelPos &screenPixelPos) const
|
||||
{
|
||||
int tilex;
|
||||
int tiley;
|
||||
const Vec2i tilePos = ScreenToTilePos(screenPixelPos);
|
||||
|
||||
tilex = x - this->X + this->MapX * PixelTileSize.x + this->OffsetX;
|
||||
if (tilex < 0) {
|
||||
tilex = (tilex - PixelTileSize.x + 1) / PixelTileSize.x;
|
||||
} else {
|
||||
tilex /= PixelTileSize.x;
|
||||
}
|
||||
|
||||
tiley = y - this->Y + this->MapY * PixelTileSize.y + this->OffsetY;
|
||||
if (tiley < 0) {
|
||||
tiley = (tiley - PixelTileSize.y + 1) / PixelTileSize.y;
|
||||
} else {
|
||||
tiley /= PixelTileSize.y;
|
||||
}
|
||||
|
||||
return (tilex >= 0 && tiley >= 0 && tilex < Map.Info.MapWidth && tiley < Map.Info.MapHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
** Convert viewport x coordinate to map tile x coordinate.
|
||||
**
|
||||
** @param x X coordinate into this viewport (in pixels, relative
|
||||
** to origin of Stratagus's window - not the viewport
|
||||
** itself!).
|
||||
**
|
||||
** @return X map tile coordinate.
|
||||
*/
|
||||
int CViewport::Viewport2MapX(int x) const
|
||||
{
|
||||
int r = (x - this->X + this->MapX * PixelTileSize.x + this->OffsetX) / PixelTileSize.x;
|
||||
return std::min<int>(r, Map.Info.MapWidth - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
** Convert viewport y coordinate to map tile y coordinate.
|
||||
**
|
||||
** @param y Y coordinate into this viewport (in pixels, relative
|
||||
** to origin of Stratagus's window - not the viewport
|
||||
** itself!).
|
||||
**
|
||||
** @return Y map tile coordinate.
|
||||
*/
|
||||
int CViewport::Viewport2MapY(int y) const
|
||||
{
|
||||
int r = (y - this->Y + this->MapY * PixelTileSize.y + this->OffsetY) / PixelTileSize.y;
|
||||
return std::min<int>(r, Map.Info.MapHeight - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
** Convert a map tile X coordinate into a viewport x pixel coordinate.
|
||||
**
|
||||
** @param x The map tile's X coordinate.
|
||||
**
|
||||
** @return X screen coordinate in pixels (relative
|
||||
** to origin of Stratagus's window).
|
||||
*/
|
||||
int CViewport::Map2ViewportX(int x) const
|
||||
{
|
||||
return this->X + (x - this->MapX) * PixelTileSize.x - this->OffsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
** Convert a map tile Y coordinate into a viewport y pixel coordinate.
|
||||
**
|
||||
** @param y The map tile's Y coordinate.
|
||||
**
|
||||
** @return Y screen coordinate in pixels (relative
|
||||
** to origin of Stratagus's window).
|
||||
*/
|
||||
int CViewport::Map2ViewportY(int y) const
|
||||
{
|
||||
return this->Y + (y - this->MapY) * PixelTileSize.y - this->OffsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
** Convert map pixel coordinates into viewport coordinates.
|
||||
*/
|
||||
void CViewport::MapPixel2Viewport(int &x, int &y) const
|
||||
{
|
||||
x = x + this->X - (this->MapX * PixelTileSize.x + this->OffsetX);
|
||||
y = y + this->Y - (this->MapY * PixelTileSize.y + this->OffsetY);
|
||||
return Map.Info.IsPointOnMap(tilePos);
|
||||
}
|
||||
|
||||
// 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 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 PixelPos mapPixelPos = {x, y};
|
||||
|
||||
return mapPixelPos;
|
||||
|
@ -181,34 +103,49 @@ PixelPos CViewport::MapToScreenPixelPos(const PixelPos &mapPixelPos) const
|
|||
mapPixelPos.y + this->Y - (this->MapY * PixelTileSize.y + this->OffsetY)
|
||||
};
|
||||
return screenPixelPos;
|
||||
}
|
||||
|
||||
/// convert screen coordinate into tilepos
|
||||
Vec2i CViewport::ScreenToTilePos(const PixelPos& screenPixelPos) const
|
||||
{
|
||||
const PixelPos mapPixelPos = ScreenToMapPixelPos(screenPixelPos);
|
||||
const Vec2i tilePos = {mapPixelPos.x / PixelTileSize.x, mapPixelPos.y / PixelTileSize.y};
|
||||
|
||||
return tilePos;
|
||||
}
|
||||
|
||||
/// convert tilepos coordonates into screen (take the top left of the tile)
|
||||
PixelPos CViewport::TilePosToScreen_TopLeft(const Vec2i &tilePos) const
|
||||
{
|
||||
const PixelPos mapPos = {tilePos.x * PixelTileSize.x, tilePos.y * PixelTileSize.y};
|
||||
|
||||
return MapToScreenPixelPos(mapPos);
|
||||
}
|
||||
|
||||
/// convert tilepos coordonates into screen (take the center of the tile)
|
||||
PixelPos CViewport::TilePosToScreen_Center(const Vec2i &tilePos) const
|
||||
{
|
||||
const PixelPos topLeft = TilePosToScreen_TopLeft(tilePos);
|
||||
|
||||
return topLeft + PixelTileSize / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
** Change viewpoint of map viewport v to x,y.
|
||||
** Change viewpoint of map viewport v to tilePos.
|
||||
**
|
||||
** @param x X map tile position.
|
||||
** @param y Y map tile position.
|
||||
** @param offsetx X offset in tile.
|
||||
** @param offsety Y offset in tile.
|
||||
** @param tilePos map tile position.
|
||||
** @param offset offset in tile.
|
||||
*/
|
||||
void CViewport::Set(int x, int y, int offsetx, int offsety)
|
||||
void CViewport::Set(const PixelPos &mapPos)
|
||||
{
|
||||
x = x * PixelTileSize.x + offsetx;
|
||||
y = y * PixelTileSize.y + offsety;
|
||||
int x = mapPos.x;
|
||||
int y = mapPos.y;
|
||||
|
||||
if (x < -UI.MapArea.ScrollPaddingLeft) {
|
||||
x = -UI.MapArea.ScrollPaddingLeft;
|
||||
}
|
||||
if (y < -UI.MapArea.ScrollPaddingTop) {
|
||||
y = -UI.MapArea.ScrollPaddingTop;
|
||||
}
|
||||
if (x > Map.Info.MapWidth * PixelTileSize.x - (this->EndX - this->X) - 1 + UI.MapArea.ScrollPaddingRight) {
|
||||
x = Map.Info.MapWidth * PixelTileSize.x- (this->EndX - this->X) - 1 + UI.MapArea.ScrollPaddingRight;
|
||||
}
|
||||
if (y > Map.Info.MapHeight * PixelTileSize.y- (this->EndY - this->Y) - 1 + UI.MapArea.ScrollPaddingBottom) {
|
||||
y = Map.Info.MapHeight * PixelTileSize.y- (this->EndY - this->Y) - 1 + UI.MapArea.ScrollPaddingBottom;
|
||||
}
|
||||
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);
|
||||
|
||||
this->MapX = x / PixelTileSize.x;
|
||||
if (x < 0 && x % PixelTileSize.x) {
|
||||
|
@ -230,6 +167,21 @@ void CViewport::Set(int x, int y, int offsetx, int offsety)
|
|||
this->MapHeight = ((this->EndY - this->Y) + this->OffsetY - 1) / PixelTileSize.y + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Change viewpoint of map viewport v to tilePos.
|
||||
**
|
||||
** @param tilePos map tile position.
|
||||
** @param offset offset in tile.
|
||||
*/
|
||||
void CViewport::Set(const Vec2i &tilePos, const PixelDiff &offset)
|
||||
{
|
||||
const int x = tilePos.x * PixelTileSize.x + offset.x;
|
||||
const int y = tilePos.y * PixelTileSize.y + offset.y;
|
||||
const PixelPos mapPixelPos = {x, y};
|
||||
|
||||
this->Set(mapPixelPos);
|
||||
}
|
||||
|
||||
/**
|
||||
** Center map viewport v on map tile (pos).
|
||||
**
|
||||
|
@ -238,9 +190,11 @@ void CViewport::Set(int x, int y, int offsetx, int offsety)
|
|||
*/
|
||||
void CViewport::Center(const Vec2i &pos, const PixelDiff &offset)
|
||||
{
|
||||
int x = pos.x * PixelTileSize.x + offset.x - (this->EndX - this->X) / 2;
|
||||
int y = pos.y * PixelTileSize.y + offset.y - (this->EndY - this->Y) / 2;
|
||||
this->Set(x / PixelTileSize.x, y / PixelTileSize.y, x % PixelTileSize.x, y % PixelTileSize.y);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -353,38 +307,36 @@ void CViewport::DrawMapBackgroundInViewport() const
|
|||
|
||||
class CDrawProxy {
|
||||
public:
|
||||
CDrawProxy(): nunits(0), nmissiles(0) {}
|
||||
CDrawProxy() : nunits(0), nmissiles(0) {}
|
||||
|
||||
void Update(const CViewport *const vp)
|
||||
void Update(const CViewport &vp)
|
||||
{
|
||||
//
|
||||
// We find and sort units after draw level.
|
||||
//
|
||||
if (lock.TryLock()) {
|
||||
nunits = FindAndSortUnits(vp, unittable);
|
||||
nmissiles = FindAndSortMissiles(*vp, missiletable, MAX_MISSILES * 9);
|
||||
nunits = FindAndSortUnits(&vp, unittable);
|
||||
nmissiles = FindAndSortMissiles(vp, missiletable, MAX_MISSILES * 9);
|
||||
lock.UnLock();
|
||||
}
|
||||
}
|
||||
|
||||
void Draw(const CViewport *const vp)
|
||||
void Draw(const CViewport &vp)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
lock.Lock ();
|
||||
while (i < nunits && j < nmissiles) {
|
||||
if (unittable[i].Type->DrawLevel <= missiletable[j].Type->DrawLevel) {
|
||||
unittable[i].Draw(vp);
|
||||
unittable[i].Draw(&vp);
|
||||
++i;
|
||||
} else {
|
||||
missiletable[j].DrawMissile(*vp);
|
||||
missiletable[j].DrawMissile(vp);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
for (; i < nunits; ++i) {
|
||||
unittable[i].Draw(vp);
|
||||
unittable[i].Draw(&vp);
|
||||
}
|
||||
for (; j < nmissiles; ++j) {
|
||||
missiletable[j].DrawMissile(*vp);
|
||||
missiletable[j].DrawMissile(vp);
|
||||
}
|
||||
lock.UnLock();
|
||||
}
|
||||
|
@ -401,7 +353,7 @@ void CViewport::UpdateUnits()
|
|||
if (!Proxy) {
|
||||
Proxy = new CDrawProxy();
|
||||
}
|
||||
Proxy->Update(this);
|
||||
Proxy->Update(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,7 +361,6 @@ void CViewport::UpdateUnits()
|
|||
*/
|
||||
void CViewport::Draw() const
|
||||
{
|
||||
|
||||
PushClipping();
|
||||
SetClipping(this->X, this->Y, this->EndX, this->EndY);
|
||||
|
||||
|
@ -418,16 +369,14 @@ void CViewport::Draw() const
|
|||
|
||||
CurrentViewport = this;
|
||||
if (Proxy) {
|
||||
Proxy->Draw(this);
|
||||
} else {
|
||||
Proxy->Draw(*this);
|
||||
} else {
|
||||
CUnit *unittable[UnitMax];
|
||||
Missile* missiletable[MAX_MISSILES * 9];
|
||||
|
||||
//
|
||||
// We find and sort units after draw level.
|
||||
//
|
||||
int nunits = FindAndSortUnits(this, unittable);
|
||||
int nmissiles = FindAndSortMissiles(*this, missiletable, MAX_MISSILES * 9);
|
||||
const int nunits = FindAndSortUnits(this, unittable);
|
||||
const int nmissiles = FindAndSortMissiles(*this, missiletable, MAX_MISSILES * 9);
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
|
@ -455,16 +404,14 @@ void CViewport::Draw() const
|
|||
// Drawn here so that they are shown even when the unit is out of the screen.
|
||||
//
|
||||
//FIXME: This is still unsecure during parallel
|
||||
if (!Preference.ShowOrders){}
|
||||
else if (Preference.ShowOrders < 0 ||
|
||||
if (!Preference.ShowOrders) {
|
||||
} else if (Preference.ShowOrders < 0 ||
|
||||
(ShowOrdersCount >= GameCycle) || (KeyModifiers & ModifierShift)) {
|
||||
for (int i = 0; i < NumSelected; ++i) {
|
||||
ShowOrder(*Selected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DrawBorder();
|
||||
|
||||
PopClipping();
|
||||
}
|
||||
|
||||
|
@ -488,9 +435,7 @@ void CViewport::DrawBorder() const
|
|||
}
|
||||
|
||||
CViewport::~CViewport() {
|
||||
if (Proxy) {
|
||||
delete Proxy;
|
||||
}
|
||||
delete Proxy;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -662,7 +662,7 @@ void CMinimap::Draw(int, int)
|
|||
**
|
||||
** @return Tile X coordinate.
|
||||
*/
|
||||
int CMinimap::Screen2MapX(int x)
|
||||
int CMinimap::Screen2MapX(int x) const
|
||||
{
|
||||
int tx;
|
||||
|
||||
|
@ -680,7 +680,7 @@ int CMinimap::Screen2MapX(int x)
|
|||
**
|
||||
** @return Tile Y coordinate.
|
||||
*/
|
||||
int CMinimap::Screen2MapY(int y)
|
||||
int CMinimap::Screen2MapY(int y) const
|
||||
{
|
||||
int ty;
|
||||
|
||||
|
@ -691,6 +691,13 @@ int CMinimap::Screen2MapY(int y)
|
|||
return std::min<int>(ty, Map.Info.MapHeight - 1);
|
||||
}
|
||||
|
||||
Vec2i CMinimap::ScreenToTilePos(const PixelPos& screenPos) const
|
||||
{
|
||||
const Vec2i tilePos = {Screen2MapX(screenPos.x), Screen2MapY(screenPos.y)};
|
||||
|
||||
return tilePos;
|
||||
}
|
||||
|
||||
/**
|
||||
** Destroy mini-map.
|
||||
*/
|
||||
|
|
|
@ -109,12 +109,12 @@ void CParticleManager::add(CParticle *particle)
|
|||
new_particles.push_back(particle);
|
||||
}
|
||||
|
||||
CPosition CParticleManager::getScreenPos(const CPosition &pos)
|
||||
CPosition CParticleManager::getScreenPos(const CPosition &pos) const
|
||||
{
|
||||
int x = (int)pos.x;
|
||||
int y = (int)pos.y;
|
||||
vp->MapPixel2Viewport(x, y);
|
||||
return CPosition(x, y);
|
||||
const PixelPos mapPixelPos = { (int)pos.x, (int)pos.y};
|
||||
const PixelPos screenPixelPos = vp->MapToScreenPixelPos(mapPixelPos);
|
||||
|
||||
return CPosition(screenPixelPos.x, screenPixelPos.y);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -182,7 +182,10 @@ void DoScrollArea(int state, bool fast)
|
|||
if (state & ScrollLeft) {
|
||||
stepx = -stepx;
|
||||
}
|
||||
vp->Set(vp->MapX, vp->MapY, vp->OffsetX + stepx, vp->OffsetY + stepy);
|
||||
const Vec2i vpTilePos = {vp->MapX, vp->MapY};
|
||||
const PixelDiff offset = {vp->OffsetX + stepx, vp->OffsetY + stepy};
|
||||
|
||||
vp->Set(vpTilePos, offset);
|
||||
|
||||
// This recalulates some values
|
||||
HandleMouseMove(CursorX, CursorY);
|
||||
|
|
|
@ -490,7 +490,7 @@ static int MissileVisibleInViewport(const CViewport &vp, const Missile &missile)
|
|||
Vec2i boxmax;
|
||||
|
||||
GetMissileMapArea(missile, boxmin, boxmax);
|
||||
if (!vp.AnyMapAreaVisibleInViewport(boxmin.x, boxmin.y, boxmax.x, boxmax.y)) {
|
||||
if (!vp.AnyMapAreaVisibleInViewport(boxmin, boxmax)) {
|
||||
return 0;
|
||||
}
|
||||
Vec2i pos;
|
||||
|
|
|
@ -42,8 +42,6 @@ class CMapArea
|
|||
|
||||
class CViewport
|
||||
{
|
||||
int Viewport2MapX(int x);
|
||||
int Viewport2MapY(int y);
|
||||
};
|
||||
|
||||
class CFiller
|
||||
|
|
|
@ -428,8 +428,9 @@ static void UiSaveMapPosition(unsigned position)
|
|||
*/
|
||||
static void UiRecallMapPosition(unsigned position)
|
||||
{
|
||||
UI.SelectedViewport->Set(
|
||||
SavedMapPositionX[position], SavedMapPositionY[position], PixelTileSize.x / 2, PixelTileSize.y / 2);
|
||||
const Vec2i savedTilePos = {SavedMapPositionX[position], SavedMapPositionY[position]};
|
||||
|
||||
UI.SelectedViewport->Set(savedTilePos, PixelTileSize / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -795,9 +795,11 @@ void MouseScrollMap(int x, int y)
|
|||
speed = UI.MouseScrollSpeedDefault;
|
||||
}
|
||||
|
||||
UI.MouseViewport->Set(UI.MouseViewport->MapX, UI.MouseViewport->MapY,
|
||||
UI.MouseViewport->OffsetX + speed * (x - CursorStartX),
|
||||
UI.MouseViewport->OffsetY + speed * (y - CursorStartY));
|
||||
const Vec2i vpTilePos = {UI.MouseViewport->MapX, UI.MouseViewport->MapY};
|
||||
const PixelDiff vpOffset = {UI.MouseViewport->OffsetX, UI.MouseViewport->OffsetY};
|
||||
const PixelDiff diff = {x - CursorX, y - CursorY};
|
||||
|
||||
UI.MouseViewport->Set(vpTilePos, vpOffset + speed * diff);
|
||||
UI.MouseWarpX = CursorStartX;
|
||||
UI.MouseWarpY = CursorStartY;
|
||||
}
|
||||
|
@ -883,13 +885,15 @@ void UIHandleMouseMove(int x, int y)
|
|||
|
||||
// This is forbidden for unexplored and not visible space
|
||||
// FIXME: This must done new, moving units, scrolling...
|
||||
if (CursorOn == CursorOnMap && UI.MouseViewport->IsInsideMapArea(CursorX, CursorY)) {
|
||||
const CViewport *vp = UI.MouseViewport;
|
||||
const Vec2i tilePos = {vp->Viewport2MapX(x), vp->Viewport2MapY(y)};
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
if (CursorOn == CursorOnMap && UI.MouseViewport->IsInsideMapArea(cursorPixelPos)) {
|
||||
const CViewport &vp = *UI.MouseViewport;
|
||||
const PixelPos screenPos = {x, y};
|
||||
const Vec2i tilePos = vp.ScreenToTilePos(screenPos);
|
||||
|
||||
if (Map.IsFieldExplored(*ThisPlayer, tilePos) || ReplayRevealMap) {
|
||||
UnitUnderCursor = UnitOnScreen(NULL, x - vp->X + vp->MapX * PixelTileSize.x + vp->OffsetX,
|
||||
y - vp->Y + vp->MapY * PixelTileSize.y + vp->OffsetY);
|
||||
const PixelPos mapPixelPos = vp.ScreenToMapPixelPos(screenPos);
|
||||
UnitUnderCursor = UnitOnScreen(NULL, mapPixelPos.x, mapPixelPos.y);
|
||||
}
|
||||
} else if (CursorOn == CursorOnMinimap) {
|
||||
const Vec2i tilePos = {UI.Minimap.Screen2MapX(x), UI.Minimap.Screen2MapY(y)};
|
||||
|
@ -1408,7 +1412,8 @@ static void UISelectStateButtonDown(unsigned)
|
|||
//
|
||||
// Clicking on the map.
|
||||
//
|
||||
if (CursorOn == CursorOnMap && UI.MouseViewport->IsInsideMapArea(CursorX, CursorY)) {
|
||||
const PixelPos screenPixelPos = {CursorX, CursorY};
|
||||
if (CursorOn == CursorOnMap && UI.MouseViewport->IsInsideMapArea(screenPixelPos)) {
|
||||
UI.StatusLine.Clear();
|
||||
ClearCosts();
|
||||
CursorState = CursorStatePoint;
|
||||
|
@ -1419,7 +1424,6 @@ static void UISelectStateButtonDown(unsigned)
|
|||
|
||||
if (MouseButtons & LeftButton) {
|
||||
const CViewport &vp = *UI.MouseViewport;
|
||||
const PixelPos screenPixelPos = {CursorX, CursorY};
|
||||
const PixelPos mapPixelPos = vp.ScreenToMapPixelPos(screenPixelPos);
|
||||
|
||||
if (!ClickMissile.empty()) {
|
||||
|
@ -1575,16 +1579,15 @@ void UIHandleButtonDown(unsigned button)
|
|||
if (!DoubleLeftButton)
|
||||
return;
|
||||
#endif
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
// Possible Selected[0] was removed from map
|
||||
// need to make sure there is a unit to build
|
||||
if (Selected[0] && (MouseButtons & LeftButton) &&
|
||||
UI.MouseViewport->IsInsideMapArea(CursorX, CursorY)) {// enter select mode
|
||||
int explored;
|
||||
const Vec2i tilePos = {UI.MouseViewport->Viewport2MapX(CursorX),
|
||||
UI.MouseViewport->Viewport2MapY(CursorY)};
|
||||
if (Selected[0] && (MouseButtons & LeftButton)
|
||||
&& UI.MouseViewport->IsInsideMapArea(cursorPixelPos)) {// enter select mode
|
||||
int explored = 1;
|
||||
const Vec2i tilePos = UI.MouseViewport->ScreenToTilePos(cursorPixelPos);
|
||||
// FIXME: error messages
|
||||
|
||||
explored = 1;
|
||||
for (int j = 0; explored && j < Selected[0]->Type->TileHeight; ++j) {
|
||||
for (int i = 0; i < Selected[0]->Type->TileWidth; ++i) {
|
||||
const Vec2i tempPos = {i, j};
|
||||
|
@ -1629,12 +1632,12 @@ void UIHandleButtonDown(unsigned button)
|
|||
#else
|
||||
} else if (MouseButtons & RightButton) {
|
||||
#endif
|
||||
if (!GameObserve && !GamePaused && UI.MouseViewport->IsInsideMapArea(CursorX, CursorY)) {
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
if (!GameObserve && !GamePaused && UI.MouseViewport->IsInsideMapArea(cursorPixelPos)) {
|
||||
CUnit *unit;
|
||||
// FIXME: Rethink the complete chaos of coordinates here
|
||||
// FIXME: Johns: Perhaps we should use a pixel map coordinates
|
||||
const Vec2i tilePos = {UI.MouseViewport->Viewport2MapX(CursorX),
|
||||
UI.MouseViewport->Viewport2MapY(CursorY)};
|
||||
const Vec2i tilePos = UI.MouseViewport->ScreenToTilePos(cursorPixelPos);
|
||||
|
||||
if (UnitUnderCursor != NULL && (unit = UnitOnMapTile(tilePos, -1)) &&
|
||||
!UnitUnderCursor->Type->Decoration) {
|
||||
|
@ -1933,13 +1936,13 @@ void UIHandleButtonUp(unsigned button)
|
|||
//
|
||||
// cade: cannot select unit on invisible space
|
||||
// FIXME: johns: only complete invisibile units
|
||||
const Vec2i cursorTilePos = {UI.MouseViewport->Viewport2MapX(CursorX),
|
||||
UI.MouseViewport->Viewport2MapY(CursorY)};
|
||||
if (Map.IsFieldVisible(*ThisPlayer, cursorTilePos) || ReplayRevealMap) {
|
||||
int pixelposx = CursorX - UI.MouseViewport->X + UI.MouseViewport->MapX * PixelTileSize.x + UI.MouseViewport->OffsetX;
|
||||
int pixelposy = CursorY - UI.MouseViewport->Y + UI.MouseViewport->MapY * PixelTileSize.y + UI.MouseViewport->OffsetY;
|
||||
const PixelPos cursorPixelPos = {CursorX, CursorY};
|
||||
const Vec2i cursorTilePos = UI.MouseViewport->ScreenToTilePos(cursorPixelPos);
|
||||
|
||||
unit = UnitOnScreen(unit, pixelposx, pixelposy);
|
||||
if (Map.IsFieldVisible(*ThisPlayer, cursorTilePos) || ReplayRevealMap) {
|
||||
const PixelPos cursorMapPos = UI.MouseViewport->ScreenToMapPixelPos(cursorPixelPos);
|
||||
|
||||
unit = UnitOnScreen(unit, cursorMapPos.x, cursorMapPos.y);
|
||||
}
|
||||
if (unit) {
|
||||
// FIXME: Not nice coded, button number hardcoded!
|
||||
|
|
|
@ -360,13 +360,15 @@ static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
|
|||
|
||||
// Affect the old viewport.
|
||||
for (int i = 0; i < num_vps; ++i) {
|
||||
CViewport *vp = UI.Viewports + 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->Set(new_vps[i].MapX, new_vps[i].MapY, new_vps[i].OffsetX, new_vps[i].OffsetY);
|
||||
vp.X = new_vps[i].X;
|
||||
vp.EndX = new_vps[i].EndX;
|
||||
vp.Y = new_vps[i].Y;
|
||||
vp.EndY = new_vps[i].EndY;
|
||||
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);
|
||||
}
|
||||
UI.NumViewports = num_vps;
|
||||
|
||||
|
|
|
@ -2765,8 +2765,8 @@ CUnit *UnitOnScreen(CUnit *ounit, int x, int y)
|
|||
|
||||
PixelPos CUnit::GetMapPixelPosCenter() const
|
||||
{
|
||||
const PixelPos center = { tilePos.x * PixelTileSize.x + Type->TileWidth * PixelTileSize.x / 2,
|
||||
tilePos.y * PixelTileSize.y + Type->TileHeight * PixelTileSize.y / 2};
|
||||
const PixelPos center = { tilePos.x * PixelTileSize.x + IX + Type->TileWidth * PixelTileSize.x / 2,
|
||||
tilePos.y * PixelTileSize.y + IY + Type->TileHeight * PixelTileSize.y / 2};
|
||||
return center;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,15 +171,14 @@ void DrawUnitSelection(const CViewport *vp, const CUnit &unit)
|
|||
return;
|
||||
}
|
||||
|
||||
const CUnitType *type = unit.Type;
|
||||
int x = vp->Map2ViewportX(unit.tilePos.x) + unit.IX +
|
||||
type->TileWidth * PixelTileSize.x / 2 - type->BoxWidth / 2 -
|
||||
(type->Width - type->Sprite->Width) / 2;
|
||||
int y = vp->Map2ViewportY(unit.tilePos.y) + unit.IY +
|
||||
type->TileHeight * PixelTileSize.y / 2 - type->BoxHeight / 2 -
|
||||
(type->Height - type->Sprite->Height) / 2;
|
||||
const CUnitType &type = *unit.Type;
|
||||
const PixelPos screenPos = vp->TilePosToScreen_TopLeft(unit.tilePos);
|
||||
const int x = screenPos.x + unit.IX +type.TileWidth * PixelTileSize.x / 2
|
||||
- type.BoxWidth / 2 - (type.Width - type.Sprite->Width) / 2;
|
||||
const int y = screenPos.y + unit.IY + type.TileHeight * PixelTileSize.y / 2
|
||||
- type.BoxHeight / 2 - (type.Height - type.Sprite->Height) / 2;
|
||||
|
||||
DrawSelection(color, x, y, x + type->BoxWidth, y + type->BoxHeight);
|
||||
DrawSelection(color, x, y, x + type.BoxWidth, y + type.BoxHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -670,36 +669,32 @@ void DrawShadow(const CUnitType &type, int frame, int x, int y)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param order Pointer to order.
|
||||
** @param x Resulting screen X cordinate.
|
||||
** @param y Resulting screen Y cordinate.
|
||||
** @param pos Resulting screen cordinates.
|
||||
*/
|
||||
static void GetOrderPosition(const CUnit &unit, const COrderPtr order, int *x, int *y)
|
||||
static void GetOrderPosition(const CUnit &unit, const COrder &order, PixelPos *screenPos)
|
||||
{
|
||||
Assert(screenPos);
|
||||
|
||||
CUnit *goal;
|
||||
|
||||
// FIXME: n0body: Check for goal gone?
|
||||
if ((goal = order->GetGoal()) && (!goal->Removed)) {
|
||||
if ((goal = order.GetGoal()) && (!goal->Removed)) {
|
||||
// Order has a goal, get it's location.
|
||||
*x = CurrentViewport->Map2ViewportX(goal->tilePos.x) + goal->IX +
|
||||
goal->Type->TileWidth * PixelTileSize.x / 2;
|
||||
*y = CurrentViewport->Map2ViewportY(goal->tilePos.y) + goal->IY +
|
||||
goal->Type->TileHeight * PixelTileSize.y / 2;
|
||||
const PixelPos mapPos = goal->GetMapPixelPosCenter();
|
||||
*screenPos = CurrentViewport->MapToScreenPixelPos(mapPos);
|
||||
} else {
|
||||
if (order->goalPos.x >= 0 && order->goalPos.y >= 0) {
|
||||
if (Map.Info.IsPointOnMap(order.goalPos)) {
|
||||
// Order is for a location, show that.
|
||||
*x = CurrentViewport->Map2ViewportX(order->goalPos.x) + PixelTileSize.x / 2;
|
||||
*y = CurrentViewport->Map2ViewportY(order->goalPos.y) + PixelTileSize.y / 2;
|
||||
*screenPos = CurrentViewport->TilePosToScreen_Center(order.goalPos);
|
||||
} else {
|
||||
// Some orders ignore x,y (like StandStill).
|
||||
// Use the unit's position instead.
|
||||
*x = CurrentViewport->Map2ViewportX(unit.tilePos.x) + unit.IX +
|
||||
unit.Type->TileWidth * PixelTileSize.x / 2;
|
||||
*y = CurrentViewport->Map2ViewportY(unit.tilePos.y) + unit.IY +
|
||||
unit.Type->TileHeight * PixelTileSize.y / 2;
|
||||
const PixelPos mapPos = unit.GetMapPixelPosCenter();
|
||||
*screenPos = CurrentViewport->MapToScreenPixelPos(mapPos);
|
||||
}
|
||||
if (order->Action == UnitActionBuild) {
|
||||
*x += (order->Arg1.Type->TileWidth - 1) * PixelTileSize.x / 2;
|
||||
*y += (order->Arg1.Type->TileHeight - 1) * PixelTileSize.y / 2;
|
||||
if (order.Action == UnitActionBuild) {
|
||||
screenPos->x += (order.Arg1.Type->TileWidth - 1) * PixelTileSize.x / 2;
|
||||
screenPos->y += (order.Arg1.Type->TileHeight - 1) * PixelTileSize.y / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -708,22 +703,20 @@ static void GetOrderPosition(const CUnit &unit, const COrderPtr order, int *x, i
|
|||
** Show the order on map.
|
||||
**
|
||||
** @param unit Unit pointer.
|
||||
** @param x1 X pixel coordinate.
|
||||
** @param y1 Y pixel coordinate.
|
||||
** @param pos screen pixel coordinate.
|
||||
** @param order Order to display.
|
||||
*/
|
||||
static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr order)
|
||||
static void ShowSingleOrder(const CUnit &unit, const PixelPos &pos, const COrder &order)
|
||||
{
|
||||
int x2;
|
||||
int y2;
|
||||
Uint32 color;
|
||||
Uint32 e_color;
|
||||
bool dest;
|
||||
|
||||
GetOrderPosition(unit, order, &x2, &y2);
|
||||
PixelPos pos1 = pos;
|
||||
PixelPos pos2;
|
||||
GetOrderPosition(unit, order, &pos2);
|
||||
|
||||
dest = false;
|
||||
switch (order->Action) {
|
||||
bool dest = false;
|
||||
switch (order.Action) {
|
||||
case UnitActionNone:
|
||||
e_color = color = ColorGray;
|
||||
break;
|
||||
|
@ -743,10 +736,9 @@ static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr o
|
|||
break;
|
||||
|
||||
case UnitActionPatrol:
|
||||
Video.DrawLineClip(ColorGreen, x1, y1, x2, y2);
|
||||
Video.DrawLineClip(ColorGreen, pos1.x, pos1.y, pos2.x, pos2.y);
|
||||
e_color = color = ColorBlue;
|
||||
x1 = CurrentViewport->Map2ViewportX(order->Arg1.Patrol.x) + PixelTileSize.x / 2;
|
||||
y1 = CurrentViewport->Map2ViewportY(order->Arg1.Patrol.y) + PixelTileSize.y / 2;
|
||||
pos1 = CurrentViewport->TilePosToScreen_Center(order.Arg1.Patrol);
|
||||
dest = true;
|
||||
break;
|
||||
|
||||
|
@ -756,8 +748,7 @@ static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr o
|
|||
break;
|
||||
|
||||
case UnitActionAttackGround:
|
||||
x2 = CurrentViewport->Map2ViewportX(order->goalPos.x) + PixelTileSize.x / 2;
|
||||
y2 = CurrentViewport->Map2ViewportY(order->goalPos.y) + PixelTileSize.y / 2;
|
||||
pos2 = CurrentViewport->TilePosToScreen_Center(order.goalPos);
|
||||
// FALL THROUGH
|
||||
case UnitActionAttack:
|
||||
if (unit.SubAction & 2) { // Show weak targets.
|
||||
|
@ -802,10 +793,9 @@ static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr o
|
|||
|
||||
case UnitActionBuild:
|
||||
{
|
||||
int w = order->Arg1.Type->BoxWidth;
|
||||
int h = order->Arg1.Type->BoxHeight;
|
||||
DrawSelection(ColorGray, x2 - w / 2, y2 - h / 2, x2 + w / 2,
|
||||
y2 + h / 2);
|
||||
int w = order.Arg1.Type->BoxWidth;
|
||||
int h = order.Arg1.Type->BoxHeight;
|
||||
DrawSelection(ColorGray, pos2.x - w / 2, pos2.y - h / 2, pos2.x + w / 2, pos2.y + h / 2);
|
||||
e_color = color = ColorGreen;
|
||||
dest = true;
|
||||
}
|
||||
|
@ -827,14 +817,14 @@ static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr o
|
|||
|
||||
default:
|
||||
e_color = color = ColorGray;
|
||||
DebugPrint("Unknown action %d\n" _C_ order->Action);
|
||||
DebugPrint("Unknown action %d\n" _C_ order.Action);
|
||||
break;
|
||||
}
|
||||
|
||||
Video.FillCircleClip(color, x1, y1, 2);
|
||||
Video.FillCircleClip(color, pos1.x, pos1.y, 2);
|
||||
if (dest) {
|
||||
Video.DrawLineClip(color, x1, y1, x2, y2);
|
||||
Video.FillCircleClip(e_color, x2, y2, 3);
|
||||
Video.DrawLineClip(color, pos1.x, pos1.y, pos2.x, pos2.y);
|
||||
Video.FillCircleClip(e_color, pos2.x, pos2.y, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,23 +835,16 @@ static void ShowSingleOrder(const CUnit &unit, int x1, int y1, const COrderPtr o
|
|||
*/
|
||||
void ShowOrder(const CUnit &unit)
|
||||
{
|
||||
int x1;
|
||||
int y1;
|
||||
COrderPtr order;
|
||||
|
||||
if (unit.Destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (unit.Player != ThisPlayer && !ThisPlayer->IsAllied(unit)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current position
|
||||
x1 = CurrentViewport->Map2ViewportX(
|
||||
unit.tilePos.x) + unit.IX + unit.Type->TileWidth * PixelTileSize.x / 2;
|
||||
y1 = CurrentViewport->Map2ViewportY(
|
||||
unit.tilePos.y) + unit.IY + unit.Type->TileHeight * PixelTileSize.y / 2;
|
||||
const PixelPos mapPos = unit.GetMapPixelPosCenter();
|
||||
PixelPos screenStartPos = CurrentViewport->MapToScreenPixelPos(mapPos);
|
||||
COrderPtr order;
|
||||
|
||||
// If the current order is cancelled show the next one
|
||||
if (unit.Orders.size() > 1 && unit.OrderFlush) {
|
||||
|
@ -869,17 +852,18 @@ void ShowOrder(const CUnit &unit)
|
|||
} else {
|
||||
order = unit.Orders[0];
|
||||
}
|
||||
ShowSingleOrder(unit, x1, y1, order);
|
||||
ShowSingleOrder(unit, screenStartPos, *order);
|
||||
|
||||
// Show the rest of the orders
|
||||
for (size_t i = 1 + (unit.OrderFlush ? 1 : 0); i < unit.Orders.size(); ++i) {
|
||||
GetOrderPosition(unit, unit.Orders[i - 1], &x1, &y1);
|
||||
ShowSingleOrder(unit, x1, y1, unit.Orders[i]);
|
||||
PixelPos screenPos;
|
||||
GetOrderPosition(unit, *unit.Orders[i - 1], &screenPos);
|
||||
ShowSingleOrder(unit, screenPos, *unit.Orders[i]);
|
||||
}
|
||||
|
||||
// Show order for new trained units
|
||||
if (!unit.CanMove() && unit.NewOrder) {
|
||||
ShowSingleOrder(unit, x1, y1, unit.NewOrder);
|
||||
if (unit.NewOrder) {
|
||||
ShowSingleOrder(unit, screenStartPos, *unit.NewOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1118,14 +1102,12 @@ void CUnit::Draw(const CViewport *vp) const
|
|||
int player = this->RescuedFrom ? this->RescuedFrom->Index : this->Player->Index;
|
||||
int action = this->CurrentAction();
|
||||
if (ReplayRevealMap || IsVisible) {
|
||||
const PixelPos &screenPos = vp->TilePosToScreen_TopLeft(this->tilePos);
|
||||
type = this->Type;
|
||||
frame = this->Frame;
|
||||
y = this->IY;
|
||||
x = this->IX;
|
||||
x += vp->Map2ViewportX(this->tilePos.x);
|
||||
y += vp->Map2ViewportY(this->tilePos.y);
|
||||
state = (action == UnitActionBuilt) |
|
||||
((action == UnitActionUpgradeTo) << 1);
|
||||
x = screenPos.x + this->IX;
|
||||
y = screenPos.y + this->IY;
|
||||
state = (action == UnitActionBuilt) | ((action == UnitActionUpgradeTo) << 1);
|
||||
constructed = this->Constructed;
|
||||
// Reset Type to the type being upgraded to
|
||||
if (state == 2) {
|
||||
|
@ -1134,10 +1116,11 @@ void CUnit::Draw(const CViewport *vp) const
|
|||
// This is trash unless the unit is being built, and that's when we use it.
|
||||
cframe = this->CurrentOrder()->Data.Built.Frame;
|
||||
} else {
|
||||
y = this->Seen.IY;
|
||||
x = this->Seen.IX;
|
||||
x += vp->Map2ViewportX(this->Seen.X);
|
||||
y += vp->Map2ViewportY(this->Seen.Y);
|
||||
const Vec2i seenTilePos = {this->Seen.X, this->Seen.Y};
|
||||
const PixelPos &screenPos = vp->TilePosToScreen_TopLeft(seenTilePos);
|
||||
|
||||
x = screenPos.x + this->Seen.IX;
|
||||
y = screenPos.y + this->Seen.IY;
|
||||
frame = this->Seen.Frame;
|
||||
type = this->Seen.Type;
|
||||
constructed = this->Seen.Constructed;
|
||||
|
@ -1401,8 +1384,10 @@ void CUnitDrawProxy::DrawSelectionAt(int x, int y) const
|
|||
|
||||
void CUnitDrawProxy::Draw(const CViewport *vp) const
|
||||
{
|
||||
int x = this->IX + vp->Map2ViewportX(this->X);
|
||||
int y = this->IY + vp->Map2ViewportY(this->Y);
|
||||
const Vec2i tilePos = {this->X, this->Y};
|
||||
const PixelPos screenPos = vp->TilePosToScreen_TopLeft(tilePos);
|
||||
const int x = screenPos.x + this->IX;
|
||||
const int y = screenPos.y + this->IY;
|
||||
|
||||
/* FIXME: check if we have to push real type here?*/
|
||||
if (state == 1 && cframe) {
|
||||
|
|
|
@ -193,9 +193,12 @@ static void DrawBuildingCursor()
|
|||
{
|
||||
// Align to grid
|
||||
const CViewport &vp = *UI.MouseViewport;
|
||||
int x = CursorX - (CursorX - vp.X + vp.OffsetX) % PixelTileSize.x;
|
||||
int y = CursorY - (CursorY - vp.Y + vp.OffsetY) % PixelTileSize.y;
|
||||
const Vec2i mpos = {vp.Viewport2MapX(x), vp.Viewport2MapY(y)};
|
||||
const PixelPos cursorScreenPos = {CursorX, CursorY};
|
||||
// int x = CursorX - (CursorX - vp.X + vp.OffsetX) % PixelTileSize.x;
|
||||
// int y = CursorY - (CursorY - vp.Y + vp.OffsetY) % PixelTileSize.y;
|
||||
const Vec2i mpos = vp.ScreenToTilePos(cursorScreenPos);
|
||||
const PixelPos screenPos = vp.TilePosToScreen_TopLeft(mpos);
|
||||
|
||||
CUnit *ontop = NULL;
|
||||
|
||||
//
|
||||
|
@ -208,13 +211,13 @@ static void DrawBuildingCursor()
|
|||
#endif
|
||||
PushClipping();
|
||||
SetClipping(vp.X, vp.Y, vp.EndX, vp.EndY);
|
||||
DrawShadow(*CursorBuilding, CursorBuilding->StillFrame, x, y);
|
||||
DrawShadow(*CursorBuilding, CursorBuilding->StillFrame, screenPos.x, screenPos.y);
|
||||
DrawUnitType(*CursorBuilding, CursorBuilding->Sprite, ThisPlayer->Index,
|
||||
CursorBuilding->StillFrame, x, y);
|
||||
CursorBuilding->StillFrame, screenPos.x, screenPos.y);
|
||||
if (CursorBuilding->CanAttack && CursorBuilding->Stats->Variables[ATTACKRANGE_INDEX].Value>0){
|
||||
Video.DrawCircleClip(ColorRed,
|
||||
x + CursorBuilding->TileWidth * PixelTileSize.x / 2,
|
||||
y + CursorBuilding->TileHeight * PixelTileSize.y / 2,
|
||||
screenPos.x + CursorBuilding->TileWidth * PixelTileSize.x / 2,
|
||||
screenPos.y + CursorBuilding->TileHeight * PixelTileSize.y / 2,
|
||||
(CursorBuilding->Stats->Variables[ATTACKRANGE_INDEX].Max + (CursorBuilding->TileWidth - 1)) * PixelTileSize.x + 1);
|
||||
}
|
||||
|
||||
|
@ -261,8 +264,8 @@ static void DrawBuildingCursor()
|
|||
} else {
|
||||
color = ColorRed;
|
||||
}
|
||||
Video.FillTransRectangleClip(color, x + w * PixelTileSize.x, y + h *
|
||||
PixelTileSize.y, PixelTileSize.x, PixelTileSize.y, 95);
|
||||
Video.FillTransRectangleClip(color, screenPos.x + w * PixelTileSize.x,
|
||||
screenPos.y + h * PixelTileSize.y, PixelTileSize.x, PixelTileSize.y, 95);
|
||||
}
|
||||
}
|
||||
PopClipping();
|
||||
|
|
Loading…
Add table
Reference in a new issue