00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00030
00031
00032
00033
00034
00035 #include "stratagus.h"
00036 #include "unit.h"
00037 #include "video.h"
00038 #include "map.h"
00039 #include "ui.h"
00040 #include "missile.h"
00041 #include "unittype.h"
00042 #include "particle.h"
00043 #include "patch_type.h"
00044 #include "patch.h"
00045 #include "patch_manager.h"
00046 #include "editor.h"
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00070 bool CViewport::AnyMapAreaVisibleInViewport(int sx, int sy, int ex, int ey) const
00071 {
00072 if (ex < this->MapX || ey < this->MapY ||
00073 sx >= this->MapX + this->MapWidth || sy >= this->MapY + this->MapHeight) {
00074 return false;
00075 }
00076 return true;
00077 }
00078
00079 bool CViewport::IsInsideMapArea(int x, int y) const
00080 {
00081 int tilex;
00082 int tiley;
00083
00084 tilex = x - this->X + this->MapX * TileSizeX + this->OffsetX;
00085 if (tilex < 0) {
00086 tilex = (tilex - TileSizeX + 1) / TileSizeX;
00087 } else {
00088 tilex /= TileSizeX;
00089 }
00090
00091 tiley = y - this->Y + this->MapY * TileSizeY + this->OffsetY;
00092 if (tiley < 0) {
00093 tiley = (tiley - TileSizeY + 1) / TileSizeY;
00094 } else {
00095 tiley /= TileSizeY;
00096 }
00097
00098 return (tilex >= 0 && tiley >= 0 && tilex < Map.Info.MapWidth && tiley < Map.Info.MapHeight);
00099 }
00100
00110 int CViewport::Viewport2MapX(int x) const
00111 {
00112 int r = (x - this->X + this->MapX * TileSizeX + this->OffsetX) / TileSizeX;
00113 return std::min(r, Map.Info.MapWidth - 1);
00114 }
00115
00125 int CViewport::Viewport2MapY(int y) const
00126 {
00127 int r = (y - this->Y + this->MapY * TileSizeY + this->OffsetY) / TileSizeY;
00128 return std::min(r, Map.Info.MapHeight - 1);
00129 }
00130
00139 int CViewport::Map2ViewportX(int x) const
00140 {
00141 return this->X + (x - this->MapX) * TileSizeX - this->OffsetX;
00142 }
00143
00152 int CViewport::Map2ViewportY(int y) const
00153 {
00154 return this->Y + (y - this->MapY) * TileSizeY - this->OffsetY;
00155 }
00156
00160 void CViewport::MapPixel2Viewport(int &x, int &y) const
00161 {
00162 x = x + this->X - (this->MapX * TileSizeX + this->OffsetX);
00163 y = y + this->Y - (this->MapY * TileSizeY + this->OffsetY);
00164 }
00165
00174 void CViewport::Set(int x, int y, int offsetx, int offsety)
00175 {
00176 x = x * TileSizeX + offsetx;
00177 y = y * TileSizeY + offsety;
00178
00179 if (x < -UI.MapArea.ScrollPaddingLeft) {
00180 x = -UI.MapArea.ScrollPaddingLeft;
00181 }
00182 if (y < -UI.MapArea.ScrollPaddingTop) {
00183 y = -UI.MapArea.ScrollPaddingTop;
00184 }
00185 if (x > Map.Info.MapWidth * TileSizeX - (this->EndX - this->X) - 1 + UI.MapArea.ScrollPaddingRight) {
00186 x = Map.Info.MapWidth * TileSizeX - (this->EndX - this->X) - 1 + UI.MapArea.ScrollPaddingRight;
00187 }
00188 if (y > Map.Info.MapHeight * TileSizeY - (this->EndY - this->Y) - 1 + UI.MapArea.ScrollPaddingBottom) {
00189 y = Map.Info.MapHeight * TileSizeY - (this->EndY - this->Y) - 1 + UI.MapArea.ScrollPaddingBottom;
00190 }
00191
00192 this->MapX = x / TileSizeX;
00193 if (x < 0 && x % TileSizeX) {
00194 this->MapX--;
00195 }
00196 this->MapY = y / TileSizeY;
00197 if (y < 0 && y % TileSizeY) {
00198 this->MapY--;
00199 }
00200 this->OffsetX = x % TileSizeX;
00201 if (this->OffsetX < 0) {
00202 this->OffsetX += TileSizeX;
00203 }
00204 this->OffsetY = y % TileSizeY;
00205 if (this->OffsetY < 0) {
00206 this->OffsetY += TileSizeY;
00207 }
00208 this->MapWidth = ((this->EndX - this->X) + this->OffsetX - 1) / TileSizeX + 1;
00209 this->MapHeight = ((this->EndY - this->Y) + this->OffsetY - 1) / TileSizeY + 1;
00210 }
00211
00220 void CViewport::Center(int x, int y, int offsetx, int offsety)
00221 {
00222 x = x * TileSizeX + offsetx - (this->EndX - this->X) / 2;
00223 y = y * TileSizeY + offsety - (this->EndY - this->Y) / 2;
00224 this->Set(x / TileSizeX, y / TileSizeY, x % TileSizeX, y % TileSizeY);
00225 }
00226
00252 void CViewport::DrawMapBackgroundInViewport() const
00253 {
00254 std::list<CPatch *> patches = Map.PatchManager.getPatches();
00255 while (!patches.empty()) {
00256 CPatch *patch = patches.front();
00257 patches.pop_front();
00258
00259 const CGraphic *g = patch->getType()->getGraphic();
00260 int x = this->X - ((this->MapX - patch->getX()) * TileSizeX + this->OffsetX);
00261 int y = this->Y - ((this->MapY - patch->getY()) * TileSizeY + this->OffsetY);
00262 g->DrawClip(x, y);
00263
00264 if (Editor.Running && Editor.ShowPatchOutlines) {
00265 Video.DrawRectangleClip(Editor.PatchOutlineColor, x, y,
00266 patch->getType()->getTileWidth() * TileSizeX,
00267 patch->getType()->getTileHeight() * TileSizeY);
00268 }
00269 }
00270 }
00271
00275 void CViewport::Draw() const
00276 {
00277 CUnit *table[UnitMax];
00278 Missile *missiletable[MAX_MISSILES];
00279 int nunits;
00280 int nmissiles;
00281 int i;
00282 int j;
00283
00284 PushClipping();
00285 SetClipping(this->X, this->Y, this->EndX, this->EndY);
00286 this->DrawMapBackgroundInViewport();
00287
00288
00289
00290
00291 nunits = FindAndSortUnits(this, table, UnitMax);
00292 nmissiles = FindAndSortMissiles(this, missiletable, MAX_MISSILES);
00293
00294 i = 0;
00295 j = 0;
00296 CurrentViewport = this;
00297 while (i < nunits && j < nmissiles) {
00298 if (table[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
00299 table[i]->Draw();
00300 ++i;
00301 } else {
00302 missiletable[j]->DrawMissile();
00303 ++j;
00304 }
00305 }
00306 for (; i < nunits; ++i) {
00307 table[i]->Draw();
00308 }
00309 for (; j < nmissiles; ++j) {
00310 missiletable[j]->DrawMissile();
00311 }
00312
00313 ParticleManager.draw(this);
00314
00315 this->DrawMapFogOfWar();
00316
00317
00318
00319
00320
00321 if (Preference.ShowOrders < 0 ||
00322 (ShowOrdersCount >= GameCycle) || (KeyModifiers & ModifierShift)) {
00323 for (i = 0; i < NumSelected; ++i) {
00324 ShowOrder(Selected[i]);
00325 }
00326 }
00327
00328 DrawBorder();
00329
00330 PopClipping();
00331 }
00332
00336 void CViewport::DrawBorder() const
00337 {
00338
00339 if (UI.NumViewports == 1) {
00340 return;
00341 }
00342
00343 Uint32 color = ColorBlack;
00344 if (this == UI.SelectedViewport) {
00345 color = ColorOrange;
00346 }
00347
00348 Video.DrawRectangle(color, this->X, this->Y, this->EndX - this->X + 1,
00349 this->EndY - this->Y + 1);
00350 }
00351