1 /*!
2 * Copyright (C) 2011-2016 OpenDungeons Team
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "gamemap/MiniMapDrawnFull.h"
19
20 #include "entities/GameEntityType.h"
21 #include "entities/Tile.h"
22 #include "game/Player.h"
23 #include "game/Seat.h"
24 #include "gamemap/GameMap.h"
25 #include "render/ODFrameListener.h"
26
27 #include <OgrePrerequisites.h>
28 #include <OgreSceneNode.h>
29 #include <OgreTextureManager.h>
30
31 #include <CEGUI/BasicImage.h>
32 #include <CEGUI/Image.h>
33 #include <CEGUI/ImageManager.h>
34 #include <CEGUI/PropertyHelper.h>
35 #include <CEGUI/RendererModules/Ogre/Renderer.h>
36 #include <CEGUI/Size.h>
37 #include <CEGUI/System.h>
38 #include <CEGUI/Texture.h>
39 #include <CEGUI/Window.h>
40 #include <CEGUI/WindowManager.h>
41
42 class MiniMapDrawnFullTileStateListener : public TileStateListener
43 {
44 public:
MiniMapDrawnFullTileStateListener(MiniMapDrawnFull & minimap,uint32_t minimapXMin,uint32_t minimapXMax,uint32_t minimapYMin,uint32_t minimapYMax,uint32_t tileXMin,uint32_t tileXMax,uint32_t tileYMin,uint32_t tileYMax)45 MiniMapDrawnFullTileStateListener(MiniMapDrawnFull& minimap,
46 uint32_t minimapXMin, uint32_t minimapXMax, uint32_t minimapYMin,
47 uint32_t minimapYMax, uint32_t tileXMin, uint32_t tileXMax,
48 uint32_t tileYMin, uint32_t tileYMax) :
49 mMinimapXMin(minimapXMin),
50 mMinimapXMax(minimapXMax),
51 mMinimapYMin(minimapYMin),
52 mMinimapYMax(minimapYMax),
53 mTileXMin(tileXMin),
54 mTileXMax(tileXMax),
55 mTileYMin(tileYMin),
56 mTileYMax(tileYMax),
57 mMinimap(minimap)
58 {}
59
~MiniMapDrawnFullTileStateListener()60 virtual ~MiniMapDrawnFullTileStateListener()
61 {}
62
tileStateChanged(Tile & tile)63 void tileStateChanged(Tile& tile) override
64 {
65 fireTileStateChanged();
66 }
67
fireTileStateChanged()68 void fireTileStateChanged()
69 {
70 mMinimap.updateTileState(mMinimapXMin, mMinimapXMax, mMinimapYMin,
71 mMinimapYMax, mTileXMin, mTileXMax, mTileYMin, mTileYMax);
72 }
73
74 const uint32_t mMinimapXMin;
75 const uint32_t mMinimapXMax;
76 const uint32_t mMinimapYMin;
77 const uint32_t mMinimapYMax;
78 const uint32_t mTileXMin;
79 const uint32_t mTileXMax;
80 const uint32_t mTileYMin;
81 const uint32_t mTileYMax;
82
83 private:
84 MiniMapDrawnFull& mMinimap;
85 };
86
87 //! \brief This enum represents the possible values a pixel can have in the minimap.
88 //! If a pixel corresponds to several game tiles, the highest value will be used
89 //! to display the pixel
90 enum class MiniMapDrawnFullPixel
91 {
92 dirtFull,
93 dirtGround,
94 rockFull,
95 rockGround,
96 claimedFull,
97 claimedGround,
98 lava,
99 water,
100 goldFull,
101 goldGround,
102 gemFull,
103 gemGround,
104 pickupEntity,
105 alliedCreature,
106 enemyCreature
107 };
108
109 namespace
110 {
getPixelValueFromTile(Seat & playerSeat,Tile & tile)111 MiniMapDrawnFullPixel getPixelValueFromTile(Seat& playerSeat, Tile& tile)
112 {
113 MiniMapDrawnFullPixel value = MiniMapDrawnFullPixel::dirtFull;
114 const std::vector<GameEntity*>& entities = tile.getEntitiesInTile();
115 for(GameEntity* entity : entities)
116 {
117 if(entity->getObjectType() == GameEntityType::creature)
118 {
119 if(!entity->getSeat()->isAlliedSeat(&playerSeat))
120 {
121 if(value < MiniMapDrawnFullPixel::enemyCreature)
122 value = MiniMapDrawnFullPixel::enemyCreature;
123 }
124 else
125 {
126 if(value < MiniMapDrawnFullPixel::alliedCreature)
127 value = MiniMapDrawnFullPixel::alliedCreature;
128 }
129 }
130 else if(entity->tryPickup(&playerSeat))
131 {
132 if(value < MiniMapDrawnFullPixel::pickupEntity)
133 value = MiniMapDrawnFullPixel::pickupEntity;
134 }
135 }
136
137 // If something interesting is on the tile, we return the computed value
138 if(value != MiniMapDrawnFullPixel::dirtFull)
139 return value;
140
141 // Otherwise, we compute a value according to its type
142 switch(tile.getTileVisual())
143 {
144 case TileVisual::lavaGround:
145 value = MiniMapDrawnFullPixel::lava;
146 break;
147 case TileVisual::waterGround:
148 value = MiniMapDrawnFullPixel::water;
149 break;
150 case TileVisual::goldFull:
151 value = MiniMapDrawnFullPixel::goldFull;
152 break;
153 case TileVisual::goldGround:
154 value = MiniMapDrawnFullPixel::goldGround;
155 break;
156 case TileVisual::gemFull:
157 value = MiniMapDrawnFullPixel::gemFull;
158 break;
159 case TileVisual::gemGround:
160 value = MiniMapDrawnFullPixel::gemGround;
161 break;
162 case TileVisual::rockFull:
163 value = MiniMapDrawnFullPixel::rockFull;
164 break;
165 case TileVisual::rockGround:
166 value = MiniMapDrawnFullPixel::rockGround;
167 break;
168 case TileVisual::claimedGround:
169 value = MiniMapDrawnFullPixel::claimedGround;
170 break;
171 case TileVisual::claimedFull:
172 value = MiniMapDrawnFullPixel::claimedFull;
173 break;
174 case TileVisual::dirtGround:
175 value = MiniMapDrawnFullPixel::dirtGround;
176 break;
177 case TileVisual::dirtFull:
178 value = MiniMapDrawnFullPixel::dirtFull;
179 break;
180 default:
181 break;
182 }
183
184 return value;
185 }
186
colourFromPixelValue(MiniMapDrawnFullPixel pixelValue,Seat * seatIfClaimed,Ogre::HardwarePixelBufferSharedPtr pixelBuffer,Ogre::PixelBox pixelBox,uint32_t minimapWidth,uint32_t minimapHeight,uint32_t minimapXMin,uint32_t minimapXMax,uint32_t minimapYMin,uint32_t minimapYMax)187 void colourFromPixelValue(MiniMapDrawnFullPixel pixelValue, Seat* seatIfClaimed,
188 Ogre::HardwarePixelBufferSharedPtr pixelBuffer, Ogre::PixelBox pixelBox,
189 uint32_t minimapWidth, uint32_t minimapHeight, uint32_t minimapXMin,
190 uint32_t minimapXMax, uint32_t minimapYMin, uint32_t minimapYMax)
191 {
192 Ogre::uint8 RR = 0x00;
193 Ogre::uint8 GG = 0x00;
194 Ogre::uint8 BB = 0x00;
195 switch(pixelValue)
196 {
197 case MiniMapDrawnFullPixel::enemyCreature:
198 {
199 RR = 0xFF;
200 GG = 0x00;
201 BB = 0x00;
202 break;
203 }
204 case MiniMapDrawnFullPixel::claimedFull:
205 {
206 if(seatIfClaimed == nullptr)
207 {
208 RR = 0x86;
209 GG = 0x50;
210 BB = 0x28;
211 }
212 else
213 {
214 const Ogre::ColourValue& color = seatIfClaimed->getColorValue();
215 RR = color.r * 255.0;
216 GG = color.g * 255.0;
217 BB = color.b * 255.0;
218 }
219 break;
220 }
221 case MiniMapDrawnFullPixel::claimedGround:
222 {
223 if(seatIfClaimed == nullptr)
224 {
225 RR = 0x5C;
226 GG = 0x37;
227 BB = 0x1B;
228 }
229 else
230 {
231 const Ogre::ColourValue& color = seatIfClaimed->getColorValue();
232 RR = color.r * 200.0;
233 GG = color.g * 200.0;
234 BB = color.b * 200.0;
235 }
236 break;
237 }
238 case MiniMapDrawnFullPixel::goldFull:
239 {
240 RR = 0xB5;
241 GG = 0xB3;
242 BB = 0x2F;
243 break;
244 }
245 case MiniMapDrawnFullPixel::goldGround:
246 {
247 RR = 0x3B;
248 GG = 0x1D;
249 BB = 0x08;
250 break;
251 }
252 case MiniMapDrawnFullPixel::water:
253 {
254 RR = 0x21;
255 GG = 0x36;
256 BB = 0x7A;
257 break;
258 }
259 case MiniMapDrawnFullPixel::lava:
260 {
261 RR = 0xB2;
262 GG = 0x22;
263 BB = 0x22;
264 break;
265 }
266 case MiniMapDrawnFullPixel::dirtGround:
267 {
268 RR = 0x3B;
269 GG = 0x1D;
270 BB = 0x08;
271 break;
272 }
273 case MiniMapDrawnFullPixel::dirtFull:
274 {
275 RR = 0x5B;
276 GG = 0x2D;
277 BB = 0x0C;
278 break;
279 }
280 case MiniMapDrawnFullPixel::rockGround:
281 {
282 RR = 0x30;
283 GG = 0x30;
284 BB = 0x30;
285 break;
286 }
287 case MiniMapDrawnFullPixel::rockFull:
288 {
289 RR = 0x41;
290 GG = 0x41;
291 BB = 0x41;
292 break;
293 }
294 default:
295 {
296 RR = 0x00;
297 GG = 0x00;
298 BB = 0xFF;
299 break;
300 }
301 case MiniMapDrawnFullPixel::pickupEntity:
302 {
303 RR = 0xDD;
304 GG = 0xDD;
305 BB = 0x12;
306 break;
307 }
308 }
309
310 pixelBuffer->lock(pixelBox, Ogre::HardwareBuffer::HBL_NORMAL);
311 for(uint32_t x = minimapXMin; x < minimapXMax; ++x)
312 {
313 for(uint32_t y = minimapYMin; y < minimapYMax; ++y)
314 {
315 Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBuffer->getCurrentLock().data) - 1;
316 pDest += (minimapWidth * (minimapHeight - y - 1) * 4);
317 pDest += (x * 4);
318
319 pDest++; //A, unused, shouldn't be here
320 // this is the order of colors I empirically found out to be working :)
321 *pDest++ = BB; //B
322 *pDest++ = GG; //G
323 *pDest++ = RR; //R
324 }
325 }
326 pixelBuffer->unlock();
327 }
328 }
329
MiniMapDrawnFull(CEGUI::Window * miniMapWindow)330 MiniMapDrawnFull::MiniMapDrawnFull(CEGUI::Window* miniMapWindow) :
331 mMiniMapWindow(miniMapWindow),
332 mGameMap(*ODFrameListener::getSingleton().getClientGameMap()),
333 mCameraManager(*ODFrameListener::getSingleton().getCameraManager()),
334 mTopLeftCornerX(0),
335 mTopLeftCornerY(0),
336 mWidth(static_cast<unsigned int>(mMiniMapWindow->getPixelSize().d_width)),
337 mHeight(static_cast<unsigned int>(mMiniMapWindow->getPixelSize().d_height)),
338 mPixelBox(mWidth, mHeight, 1, Ogre::PF_R8G8B8),
339 mMiniMapOgreTexture(Ogre::TextureManager::getSingletonPtr()->createManual(
340 "miniMapOgreTexture",
341 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
342 Ogre::TEX_TYPE_2D,
343 mWidth, mHeight, 0, Ogre::PF_R8G8B8,
344 Ogre::TU_DYNAMIC_WRITE_ONLY)),
345 mPixelBuffer(mMiniMapOgreTexture->getBuffer())
346 {
347 uint32_t tileXMax = mGameMap.getMapSizeX();
348 uint32_t tileYMax = mGameMap.getMapSizeY();
349 uint32_t tileX = 0;
350 uint32_t tileY = 0;
351 uint32_t mapX = 0;
352 uint32_t mapY = 0;
353
354 Ogre::Real gainX = static_cast<Ogre::Real>(mWidth) / static_cast<Ogre::Real>(tileXMax);
355 Ogre::Real gainY = static_cast<Ogre::Real>(mHeight) / static_cast<Ogre::Real>(tileYMax);
356
357 while((mapX < mWidth) && (mapY < mHeight) && (tileX < tileXMax) && (tileY < tileYMax))
358 {
359 uint32_t tileXNext = static_cast<uint32_t>(round(static_cast<Ogre::Real>(mapX + 1) / gainX));
360 uint32_t tileYNext = static_cast<uint32_t>(round(static_cast<Ogre::Real>(mapY + 1) / gainY));
361 uint32_t mapXNext = static_cast<uint32_t>(round(static_cast<Ogre::Real>(tileX + 1) * gainX));
362 uint32_t mapYNext = static_cast<uint32_t>(round(static_cast<Ogre::Real>(tileY + 1) * gainY));
363
364 if(tileXNext == tileX)
365 ++tileXNext;
366 if(tileYNext == tileY)
367 ++tileYNext;
368 if(mapXNext == mapX)
369 ++mapXNext;
370 if(mapYNext == mapY)
371 ++mapYNext;
372
373 MiniMapDrawnFullTileStateListener* listener = new MiniMapDrawnFullTileStateListener(*this,
374 mapX, mapXNext, mapY, mapYNext, tileX, tileXNext, tileY, tileYNext);
375
376 mTileStateListeners.push_back(listener);
377
378 mapX = mapXNext;
379 tileX = tileXNext;
380 if(tileXNext >= tileXMax)
381 {
382 mapY = mapYNext;
383 tileY = tileYNext;
384 mapX = 0;
385 tileX = 0;
386 }
387 }
388
389 // It start, we fire the tile state changed event to make sure every pixel is
390 // correctly initialized. We also set the listeners on the tiles
391 for(MiniMapDrawnFullTileStateListener* listener : mTileStateListeners)
392 {
393 for(uint32_t xxx = listener->mTileXMin; xxx < listener->mTileXMax; ++xxx)
394 {
395 for(uint32_t yyy = listener->mTileYMin; yyy < listener->mTileYMax; ++yyy)
396 {
397 Tile* tile = mGameMap.getTile(xxx, yyy);
398 if(tile == nullptr)
399 continue;
400
401 tile->addTileStateListener(*listener);
402 }
403 }
404
405 listener->fireTileStateChanged();
406 }
407
408 CEGUI::Texture& miniMapTextureGui = static_cast<CEGUI::OgreRenderer*>(CEGUI::System::getSingletonPtr()
409 ->getRenderer())->createTexture("miniMapTextureGui", mMiniMapOgreTexture);
410
411 CEGUI::BasicImage& imageset = dynamic_cast<CEGUI::BasicImage&>(CEGUI::ImageManager::getSingletonPtr()->create("BasicImage", "MiniMapImageset"));
412 imageset.setArea(CEGUI::Rectf(CEGUI::Vector2f(0.0, 0.0),
413 CEGUI::Size<float>(
414 static_cast<float>(mWidth), static_cast<float>(mHeight)
415 )
416 ));
417
418 // Link the image to the minimap
419 imageset.setTexture(&miniMapTextureGui);
420 mMiniMapWindow->setProperty("Image", CEGUI::PropertyHelper<CEGUI::Image*>::toString(&imageset));
421
422 mMiniMapOgreTexture->load();
423
424 mTopLeftCornerX = mMiniMapWindow->getUnclippedOuterRect().get().getPosition().d_x;
425 mTopLeftCornerY = mMiniMapWindow->getUnclippedOuterRect().get().getPosition().d_y;
426 }
427
~MiniMapDrawnFull()428 MiniMapDrawnFull::~MiniMapDrawnFull()
429 {
430 for(MiniMapDrawnFullTileStateListener* listener : mTileStateListeners)
431 {
432 for(uint32_t xxx = listener->mTileXMin; xxx < listener->mTileXMax; ++xxx)
433 {
434 for(uint32_t yyy = listener->mTileYMin; yyy < listener->mTileYMax; ++yyy)
435 {
436 Tile* tile = mGameMap.getTile(xxx, yyy);
437 if(tile == nullptr)
438 continue;
439
440 tile->removeTileStateListener(*listener);
441 }
442 }
443 delete listener;
444 }
445 mTileStateListeners.clear();
446
447 mMiniMapWindow->setProperty("Image", "");
448 Ogre::TextureManager::getSingletonPtr()->remove("miniMapOgreTexture");
449 CEGUI::ImageManager::getSingletonPtr()->destroy("MiniMapImageset");
450 CEGUI::System::getSingletonPtr()->getRenderer()->destroyTexture("miniMapTextureGui");
451 }
452
camera_2dPositionFromClick(int xx,int yy)453 Ogre::Vector2 MiniMapDrawnFull::camera_2dPositionFromClick(int xx, int yy)
454 {
455 Ogre::Vector2 v(0, 0);
456 Ogre::Real gainX = static_cast<Ogre::Real>(mGameMap.getMapSizeX())
457 / static_cast<Ogre::Real>(mWidth);
458 Ogre::Real gainY = static_cast<Ogre::Real>(mGameMap.getMapSizeY())
459 / static_cast<Ogre::Real>(mHeight);
460
461 v.x = round(static_cast<Ogre::Real>(xx - mTopLeftCornerX) * gainX);
462 v.y = round(static_cast<Ogre::Real>(mHeight - yy + mTopLeftCornerY) * gainY);
463
464 return v;
465 }
466
updateTileState(uint32_t minimapXMin,uint32_t minimapXMax,uint32_t minimapYMin,uint32_t minimapYMax,uint32_t tileXMin,uint32_t tileXMax,uint32_t tileYMin,uint32_t tileYMax)467 void MiniMapDrawnFull::updateTileState(uint32_t minimapXMin, uint32_t minimapXMax,
468 uint32_t minimapYMin, uint32_t minimapYMax, uint32_t tileXMin,
469 uint32_t tileXMax, uint32_t tileYMin, uint32_t tileYMax)
470 {
471 Seat& localPlayerSeat = *(mGameMap.getLocalPlayer()->getSeat());
472 // We compute the tile representation
473 MiniMapDrawnFullPixel curValue = MiniMapDrawnFullPixel::dirtFull;
474 Seat* seatIfClaimed = nullptr;
475 for(uint32_t xxx = tileXMin; xxx < tileXMax; ++xxx)
476 {
477 for(uint32_t yyy = tileYMin; yyy < tileYMax; ++yyy)
478 {
479 Tile* tile = mGameMap.getTile(xxx, yyy);
480 if(tile == nullptr)
481 continue;
482
483 MiniMapDrawnFullPixel value = getPixelValueFromTile(localPlayerSeat,
484 *tile);
485 if(value > curValue)
486 {
487 curValue = value;
488 switch(value)
489 {
490 case MiniMapDrawnFullPixel::claimedGround:
491 case MiniMapDrawnFullPixel::claimedFull:
492 seatIfClaimed = tile->getSeat();
493 break;
494 default:
495 break;
496 }
497 }
498 }
499 }
500
501 // We paint corresponding pixels
502 colourFromPixelValue(curValue, seatIfClaimed, mPixelBuffer, mPixelBox,
503 mWidth, mHeight, minimapXMin, minimapXMax, minimapYMin, minimapYMax);
504 }
505
crossSegment(const Ogre::Vector3 & p1,const Ogre::Vector3 & p2,uint32_t xMin,uint32_t xMax,uint32_t yMin,uint32_t yMax)506 bool MiniMapDrawnFull::crossSegment(const Ogre::Vector3& p1, const Ogre::Vector3& p2,
507 uint32_t xMin, uint32_t xMax, uint32_t yMin, uint32_t yMax)
508 {
509 if((p1.x < static_cast<Ogre::Real>(xMin)) &&
510 (p2.x < static_cast<Ogre::Real>(xMin)))
511 {
512 return false;
513 }
514 if((p1.x > static_cast<Ogre::Real>(xMax)) &&
515 (p2.x > static_cast<Ogre::Real>(xMax)))
516 {
517 return false;
518 }
519
520 if((p1.y < static_cast<Ogre::Real>(yMin)) &&
521 (p2.y < static_cast<Ogre::Real>(yMin)))
522 {
523 return false;
524 }
525 if((p1.y > static_cast<Ogre::Real>(yMax)) &&
526 (p2.y > static_cast<Ogre::Real>(yMax)))
527 {
528 return false;
529 }
530
531 Ogre::Real diffYPoints = p2.y - p1.y;
532 Ogre::Real diffXPoints = p2.x - p1.x;
533 Ogre::Real diffYMin = p2.y - static_cast<Ogre::Real>(yMin);
534 Ogre::Real diffXMin = p2.x - static_cast<Ogre::Real>(xMin);
535 Ogre::Real diffYMax = p2.y - static_cast<Ogre::Real>(yMax);
536 Ogre::Real diffXMax = p2.x - static_cast<Ogre::Real>(xMax);
537
538 // Magic number to change the size of the line
539 static const Ogre::Real DIFF_MIN = 5;
540 if(
541 (
542 (diffYMin * diffXPoints - diffYPoints * diffXMin - DIFF_MIN< 0) &&
543 (diffYMax * diffXPoints - diffYPoints * diffXMax + DIFF_MIN >= 0)
544 ) ||
545 (
546 (diffYMax * diffXPoints - diffYPoints * diffXMax - DIFF_MIN< 0) &&
547 (diffYMin * diffXPoints - diffYPoints * diffXMin + DIFF_MIN >= 0)
548 )
549 )
550 {
551 return true;
552 }
553
554 return false;
555 }
556
update(Ogre::Real timeSinceLastFrame,const std::vector<Ogre::Vector3> & cornerTiles)557 void MiniMapDrawnFull::update(Ogre::Real timeSinceLastFrame, const std::vector<Ogre::Vector3>& cornerTiles)
558 {
559 const Ogre::Vector3& topRight = cornerTiles[0];
560 const Ogre::Vector3& topLeft = cornerTiles[1];
561 const Ogre::Vector3& bottomLeft = cornerTiles[2];
562 const Ogre::Vector3& bottomRight = cornerTiles[3];
563
564 bool isSame = (mLastCornerTiles.size() == cornerTiles.size());
565 static const Ogre::Real squareDiffMin = 0.5;
566 for(uint32_t iii = 0; isSame && iii < mLastCornerTiles.size(); ++iii)
567 {
568 Ogre::Real val = (mLastCornerTiles[iii] - cornerTiles[iii]).squaredLength();
569 isSame &= (val <= squareDiffMin);
570 }
571
572 if(isSame)
573 return;
574
575 // We save corner tiles
576 mLastCornerTiles = cornerTiles;
577
578 // We refresh the old rectangle
579 for(MiniMapDrawnFullTileStateListener* listener : mVisibleRectangle)
580 {
581 listener->fireTileStateChanged();
582 }
583 mVisibleRectangle.clear();
584
585 // And we paint the new visible rectangle
586 mPixelBuffer->lock(mPixelBox, Ogre::HardwareBuffer::HBL_NORMAL);
587
588 // we look for the tiles at the border of vision to paint them black
589 for(MiniMapDrawnFullTileStateListener* listener : mTileStateListeners)
590 {
591 bool isInBorder = false;
592
593 // We check if the listener tiles are on the top line
594 if(!isInBorder &&
595 crossSegment(topRight, topLeft, listener->mTileXMin, listener->mTileXMax,
596 listener->mTileYMin, listener->mTileYMax))
597 {
598 isInBorder = true;
599 }
600
601 if(!isInBorder &&
602 crossSegment(topLeft, bottomLeft, listener->mTileXMin, listener->mTileXMax,
603 listener->mTileYMin, listener->mTileYMax))
604 {
605 isInBorder = true;
606 }
607
608 if(!isInBorder &&
609 crossSegment(bottomLeft, bottomRight, listener->mTileXMin, listener->mTileXMax,
610 listener->mTileYMin, listener->mTileYMax))
611 {
612 isInBorder = true;
613 }
614
615 if(!isInBorder &&
616 crossSegment(bottomRight, topRight, listener->mTileXMin, listener->mTileXMax,
617 listener->mTileYMin, listener->mTileYMax))
618 {
619 isInBorder = true;
620 }
621
622 if(!isInBorder)
623 continue;
624
625 mVisibleRectangle.push_back(listener);
626 for(uint32_t xxx = listener->mMinimapXMin; xxx < listener->mMinimapXMax; ++xxx)
627 {
628 for(uint32_t yyy = listener->mMinimapYMin; yyy < listener->mMinimapYMax; ++yyy)
629 {
630 Ogre::uint8* pDest = static_cast<Ogre::uint8*>(mPixelBuffer->getCurrentLock().data) - 1;
631 pDest += (mWidth * (mHeight - yyy - 1) * 4);
632 pDest += (xxx * 4);
633
634 pDest++; //A, unused, shouldn't be here
635 // this is the order of colors I empirically found out to be working :)
636 *pDest++ = 0x00; //B
637 *pDest++ = 0x00; //G
638 *pDest++ = 0x00; //R
639 }
640 }
641 }
642 mPixelBuffer->unlock();
643 }
644