mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 19:56:42 +00:00 
			
		
		
		
	Merge remote branch 'scrawl/minimap' into next
This commit is contained in:
		
						commit
						9ec1e55aaf
					
				
					 19 changed files with 831 additions and 26 deletions
				
			
		|  | @ -14,7 +14,8 @@ set(GAME_HEADER | |||
| source_group(game FILES ${GAME} ${GAME_HEADER}) | ||||
| 
 | ||||
| add_openmw_dir (mwrender | ||||
|     renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface | ||||
|     renderingmanager debugging sky player animation npcanimation creatureanimation actors objects | ||||
|     renderinginterface localmap | ||||
|     ) | ||||
| 
 | ||||
| add_openmw_dir (mwinput | ||||
|  |  | |||
|  | @ -61,6 +61,8 @@ HUD::HUD(int width, int height, int fpsLevel) | |||
|     setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); | ||||
|     setSpellStatus(65, 100); | ||||
|     setEffect("icons\\s\\tx_s_chameleon.dds"); | ||||
| 
 | ||||
|     LocalMapBase::init(minimap, this); | ||||
| } | ||||
| 
 | ||||
| void HUD::setFPS(float fps) | ||||
|  | @ -142,3 +144,161 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v | |||
|             } | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| void HUD::setPlayerDir(const float x, const float y) | ||||
| { | ||||
|     MyGUI::ISubWidget* main = compass->getSubWidgetMain(); | ||||
|     MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); | ||||
|     rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); | ||||
|     float angle = std::atan2(x,y); | ||||
|     rotatingSubskin->setAngle(angle); | ||||
| } | ||||
| 
 | ||||
| void HUD::setPlayerPos(const float x, const float y) | ||||
| { | ||||
|     MyGUI::IntSize size = minimap->getCanvasSize(); | ||||
|     MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); | ||||
|     MyGUI::IntCoord viewsize = minimap->getCoord(); | ||||
|     MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); | ||||
| 
 | ||||
|     minimap->setViewOffset(pos); | ||||
|     compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); | ||||
| } | ||||
| 
 | ||||
| MapWindow::MapWindow() | ||||
|   : Layout("openmw_map_window_layout.xml"), mGlobal(false) | ||||
| { | ||||
|     setCoord(500,0,320,300); | ||||
|     setText("WorldButton", "World"); | ||||
|     setImage("Compass", "textures\\compass.dds"); | ||||
| 
 | ||||
|     // Obviously you should override this later on
 | ||||
|     setCellName("No Cell Loaded"); | ||||
| 
 | ||||
|     getWidget(mLocalMap, "LocalMap"); | ||||
|     getWidget(mGlobalMap, "GlobalMap"); | ||||
|     getWidget(mPlayerArrow, "Compass"); | ||||
| 
 | ||||
|     getWidget(mButton, "WorldButton"); | ||||
|     mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); | ||||
| 
 | ||||
|     MyGUI::Button* eventbox; | ||||
|     getWidget(eventbox, "EventBox"); | ||||
|     eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); | ||||
|     eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); | ||||
| 
 | ||||
|     LocalMapBase::init(mLocalMap, this); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::setVisible(bool b) | ||||
| { | ||||
|     mMainWidget->setVisible(b); | ||||
|     if (b) | ||||
|         mVisible = true; | ||||
|     else | ||||
|         mVisible = false; | ||||
| } | ||||
| 
 | ||||
| void MapWindow::setCellName(const std::string& cellName) | ||||
| { | ||||
|     static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::setPlayerPos(const float x, const float y) | ||||
| { | ||||
|     if (mGlobal || mVisible) return; | ||||
|     MyGUI::IntSize size = mLocalMap->getCanvasSize(); | ||||
|     MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); | ||||
|     MyGUI::IntCoord viewsize = mLocalMap->getCoord(); | ||||
|     MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); | ||||
|     mLocalMap->setViewOffset(pos); | ||||
| 
 | ||||
|     mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::setPlayerDir(const float x, const float y) | ||||
| { | ||||
|     if (!mVisible) return; | ||||
|     MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); | ||||
|     MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); | ||||
|     rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); | ||||
|     float angle = std::atan2(x,y); | ||||
|     rotatingSubskin->setAngle(angle); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) | ||||
| { | ||||
|     if (_id!=MyGUI::MouseButton::Left) return; | ||||
|     if (!mGlobal) | ||||
|         mLastDragPos = MyGUI::IntPoint(_left, _top); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) | ||||
| { | ||||
|     if (_id!=MyGUI::MouseButton::Left) return; | ||||
| 
 | ||||
|     if (!mGlobal) | ||||
|     { | ||||
|         MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; | ||||
|         mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); | ||||
| 
 | ||||
|         mLastDragPos = MyGUI::IntPoint(_left, _top); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) | ||||
| { | ||||
|     mGlobal = !mGlobal; | ||||
|     mGlobalMap->setVisible(mGlobal); | ||||
|     mLocalMap->setVisible(!mGlobal); | ||||
| 
 | ||||
|     mButton->setCaption( mGlobal ? "Local" : "World" ); | ||||
| } | ||||
| 
 | ||||
| void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout) | ||||
| { | ||||
|     mLocalMap = widget; | ||||
|     mLayout = layout; | ||||
| } | ||||
| 
 | ||||
| void LocalMapBase::setCellPrefix(const std::string& prefix) | ||||
| { | ||||
|     mPrefix = prefix; | ||||
|     mChanged = true; | ||||
| } | ||||
| 
 | ||||
| void LocalMapBase::setActiveCell(const int x, const int y, bool interior) | ||||
| { | ||||
|     if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
 | ||||
|     for (int mx=0; mx<3; ++mx) | ||||
|     { | ||||
|         for (int my=0; my<3; ++my) | ||||
|         { | ||||
|             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" | ||||
|                     + boost::lexical_cast<std::string>(my); | ||||
| 
 | ||||
|             std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_" | ||||
|                     + boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1))); | ||||
| 
 | ||||
|             MyGUI::ImageBox* box; | ||||
|             mLayout->getWidget(box, name); | ||||
|             MyGUI::ImageBox* fog; | ||||
|             mLayout->getWidget(fog, name+"_fog"); | ||||
| 
 | ||||
|             if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) | ||||
|                 box->setImageTexture(image); | ||||
|             else | ||||
|                 box->setImageTexture("black.png"); | ||||
| 
 | ||||
|             if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) | ||||
|                 fog->setImageTexture(image+"_fog"); | ||||
|             else | ||||
|                 fog->setImageTexture("black.png"); | ||||
|         } | ||||
|     } | ||||
|     mInterior = interior; | ||||
|     mCurX = x; | ||||
|     mCurY = y; | ||||
|     mChanged = false; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,8 @@ | |||
| #include "../mwmechanics/stat.hpp" | ||||
| #include "window_base.hpp" | ||||
| 
 | ||||
| #include <cmath> | ||||
| 
 | ||||
| /*
 | ||||
|   This file contains classes corresponding to window layouts | ||||
|   defined in resources/mygui/ *.xml. | ||||
|  | @ -29,7 +31,25 @@ | |||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|   class HUD : public OEngine::GUI::Layout | ||||
|   class LocalMapBase | ||||
|   { | ||||
|   public: | ||||
|     void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout); | ||||
| 
 | ||||
|     void setCellPrefix(const std::string& prefix); | ||||
|     void setActiveCell(const int x, const int y, bool interior=false); | ||||
| 
 | ||||
|   protected: | ||||
|     int mCurX, mCurY; | ||||
|     bool mInterior; | ||||
|     MyGUI::ScrollView* mLocalMap; | ||||
|     std::string mPrefix; | ||||
|     bool mChanged; | ||||
| 
 | ||||
|     OEngine::GUI::Layout* mLayout; | ||||
|   }; | ||||
|    | ||||
|   class HUD : public OEngine::GUI::Layout, public LocalMapBase | ||||
|   { | ||||
|   public: | ||||
|     HUD(int width, int height, int fpsLevel); | ||||
|  | @ -43,13 +63,15 @@ namespace MWGui | |||
|     void setFPS(float fps); | ||||
|     void setTriangleCount(size_t count); | ||||
|     void setBatchCount(size_t count); | ||||
|     void setPlayerDir(const float x, const float y); | ||||
|     void setPlayerPos(const float x, const float y); | ||||
| 
 | ||||
|     MyGUI::ProgressPtr health, magicka, stamina; | ||||
|     MyGUI::ImageBox *weapImage, *spellImage; | ||||
|     MyGUI::ProgressPtr weapStatus, spellStatus; | ||||
|     MyGUI::WidgetPtr effectBox; | ||||
|     MyGUI::ImageBox* effect1; | ||||
|     MyGUI::ImageBox* minimap; | ||||
|     MyGUI::ScrollView* minimap; | ||||
|     MyGUI::ImageBox* compass; | ||||
|     MyGUI::ImageBox* crosshair; | ||||
| 
 | ||||
|  | @ -59,24 +81,27 @@ namespace MWGui | |||
|     MyGUI::TextBox* batchcounter; | ||||
|   }; | ||||
| 
 | ||||
|   class MapWindow : public OEngine::GUI::Layout | ||||
|   class MapWindow : public OEngine::GUI::Layout, public LocalMapBase | ||||
|   { | ||||
|   public: | ||||
|     MapWindow() | ||||
|       : Layout("openmw_map_window_layout.xml") | ||||
|     { | ||||
|       setCoord(500,0,320,300); | ||||
|       setText("WorldButton", "World"); | ||||
|       setImage("Compass", "compass.dds"); | ||||
|     MapWindow(); | ||||
| 
 | ||||
|       // Obviously you should override this later on
 | ||||
|       setCellName("No Cell Loaded"); | ||||
|     } | ||||
|     void setVisible(bool b); | ||||
|     void setPlayerPos(const float x, const float y); | ||||
|     void setPlayerDir(const float x, const float y); | ||||
|     void setCellName(const std::string& cellName); | ||||
|    | ||||
|   private: | ||||
|     void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); | ||||
|     void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); | ||||
|     void onWorldButtonClicked(MyGUI::Widget* _sender); | ||||
| 
 | ||||
|     void setCellName(const std::string& cellName) | ||||
|     { | ||||
|       static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName); | ||||
|     } | ||||
|     MyGUI::ScrollView* mGlobalMap; | ||||
|     MyGUI::ImageBox* mPlayerArrow; | ||||
|     MyGUI::Button* mButton; | ||||
|     MyGUI::IntPoint mLastDragPos; | ||||
|     bool mVisible; | ||||
|     bool mGlobal; | ||||
|   }; | ||||
| 
 | ||||
|   class MainMenu : public OEngine::GUI::Layout | ||||
|  |  | |||
|  | @ -400,3 +400,47 @@ const ESMS::ESMStore& WindowManager::getStore() const | |||
| { | ||||
|     return environment.mWorld->getStore(); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     if (!(cell->cell->data.flags & ESM::Cell::Interior)) | ||||
|     { | ||||
|         std::string name; | ||||
|         if (cell->cell->name != "") | ||||
|             name = cell->cell->name; | ||||
|         else | ||||
|             name = cell->cell->region; | ||||
| 
 | ||||
|         map->setCellName( name ); | ||||
| 
 | ||||
|         map->setCellPrefix("Cell"); | ||||
|         hud->setCellPrefix("Cell"); | ||||
|         map->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); | ||||
|         hud->setActiveCell( cell->cell->data.gridX, cell->cell->data.gridY ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         map->setCellName( cell->cell->name ); | ||||
|         map->setCellPrefix( cell->cell->name ); | ||||
|         hud->setCellPrefix( cell->cell->name ); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void WindowManager::setInteriorMapTexture(const int x, const int y) | ||||
| { | ||||
|     map->setActiveCell(x,y, true); | ||||
|     hud->setActiveCell(x,y, true); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::setPlayerPos(const float x, const float y) | ||||
| { | ||||
|     map->setPlayerPos(x,y); | ||||
|     hud->setPlayerPos(x,y); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::setPlayerDir(const float x, const float y) | ||||
| { | ||||
|     map->setPlayerDir(x,y); | ||||
|     hud->setPlayerDir(x,y); | ||||
| } | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| #include <openengine/ogre/renderer.hpp> | ||||
| #include <openengine/gui/manager.hpp> | ||||
| #include "../mwmechanics/stat.hpp" | ||||
| #include "../mwworld/ptr.hpp" | ||||
| #include "mode.hpp" | ||||
| 
 | ||||
| namespace MyGUI | ||||
|  | @ -152,6 +153,12 @@ namespace MWGui | |||
|     void setBounty (int bounty);                                           ///< set the current bounty value
 | ||||
|     void updateSkillArea();                                                ///< update display of skills, factions, birth sign, reputation and bounty
 | ||||
| 
 | ||||
|     void changeCell(MWWorld::Ptr::CellStore* cell); ///< change the active cell
 | ||||
|     void setPlayerPos(const float x, const float y); ///< set player position in map space
 | ||||
|     void setPlayerDir(const float x, const float y); ///< set player view direction in map space
 | ||||
|      | ||||
|     void setInteriorMapTexture(const int x, const int y); | ||||
|     ///< set the index of the map texture that should be used (for interiors)
 | ||||
| 
 | ||||
|     template<typename T> | ||||
|     void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
 | ||||
|  |  | |||
							
								
								
									
										312
									
								
								apps/openmw/mwrender/localmap.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								apps/openmw/mwrender/localmap.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,312 @@ | |||
| #include "localmap.hpp" | ||||
| #include "renderingmanager.hpp" | ||||
| 
 | ||||
| #include "../mwworld/environment.hpp" | ||||
| #include "../mwgui/window_manager.hpp" | ||||
| 
 | ||||
| #include <OgreOverlayManager.h> | ||||
| #include <OgreMaterialManager.h> | ||||
| 
 | ||||
| using namespace MWRender; | ||||
| using namespace Ogre; | ||||
| 
 | ||||
| LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env) | ||||
| { | ||||
|     mRendering = rend; | ||||
|     mEnvironment = env; | ||||
|      | ||||
|     mCellCamera = mRendering->getScene()->createCamera("CellCamera"); | ||||
|     mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); | ||||
|     // look down -y
 | ||||
|     const float sqrt0pt5 = 0.707106781; | ||||
|     mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); | ||||
| } | ||||
| 
 | ||||
| LocalMap::~LocalMap() | ||||
| { | ||||
|     deleteBuffers(); | ||||
| } | ||||
| 
 | ||||
| void LocalMap::deleteBuffers() | ||||
| { | ||||
|     for (std::map<std::string, uint32*>::iterator it=mBuffers.begin(); | ||||
|         it != mBuffers.end(); ++it) | ||||
|     { | ||||
|         delete it->second; | ||||
|     } | ||||
|     mBuffers.clear(); | ||||
| } | ||||
| 
 | ||||
| void LocalMap::saveTexture(const std::string& texname, const std::string& filename) | ||||
| { | ||||
|     TexturePtr tex = TextureManager::getSingleton().getByName(texname); | ||||
|     if (tex.isNull()) return; | ||||
|     HardwarePixelBufferSharedPtr readbuffer = tex->getBuffer(); | ||||
|     readbuffer->lock(HardwareBuffer::HBL_NORMAL ); | ||||
|     const PixelBox &readrefpb = readbuffer->getCurrentLock();     | ||||
|     uchar *readrefdata = static_cast<uchar*>(readrefpb.data);         | ||||
| 
 | ||||
|     Image img; | ||||
|     img = img.loadDynamicImage (readrefdata, tex->getWidth(), | ||||
|         tex->getHeight(), tex->getFormat());     | ||||
|     img.save("./" + filename); | ||||
| 
 | ||||
|     readbuffer->unlock(); | ||||
| } | ||||
| 
 | ||||
| std::string LocalMap::coordStr(const int x, const int y) | ||||
| { | ||||
|     return StringConverter::toString(x) + "_" + StringConverter::toString(y); | ||||
| } | ||||
| 
 | ||||
| void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     if (!mInterior) | ||||
|     { | ||||
|         /*saveTexture("Cell_"+coordStr(mCellX, mCellY)+"_fog",
 | ||||
|             "Cell_"+coordStr(mCellX, mCellY)+"_fog.png");*/ | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); | ||||
|         Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); | ||||
|         /// \todo why is this workaround needed?
 | ||||
|         min *= 1.3; | ||||
|         max *= 1.3; | ||||
|         Vector2 length = max-min; | ||||
|          | ||||
|         // divide into segments
 | ||||
|         const int segsX = std::ceil( length.x / sSize ); | ||||
|         const int segsY = std::ceil( length.y / sSize ); | ||||
| 
 | ||||
|         for (int x=0; x<segsX; ++x) | ||||
|         { | ||||
|             for (int y=0; y<segsY; ++y) | ||||
|             { | ||||
|                 /*saveTexture(
 | ||||
|                     mInteriorName + "_" + coordStr(x,y) + "_fog", | ||||
|                     mInteriorName + "_" + coordStr(x,y) + "_fog.png");*/ | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     mInterior = false; | ||||
| 
 | ||||
|     std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY); | ||||
| 
 | ||||
|     int x = cell->cell->data.gridX; | ||||
|     int y = cell->cell->data.gridY; | ||||
| 
 | ||||
|     render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); | ||||
| } | ||||
| 
 | ||||
| void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, | ||||
|                             AxisAlignedBox bounds) | ||||
| { | ||||
|     mInterior = true; | ||||
|     mBounds = bounds; | ||||
|      | ||||
|     Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y); | ||||
|     Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z); | ||||
|     Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z); | ||||
| 
 | ||||
|     /// \todo why is this workaround needed?
 | ||||
|     min *= 1.3; | ||||
|     max *= 1.3; | ||||
| 
 | ||||
|     Vector2 length = max-min; | ||||
|     Vector2 center(bounds.getCenter().x, bounds.getCenter().z); | ||||
| 
 | ||||
|     // divide into segments
 | ||||
|     const int segsX = std::ceil( length.x / sSize ); | ||||
|     const int segsY = std::ceil( length.y / sSize ); | ||||
| 
 | ||||
|     mInteriorName = cell->cell->name; | ||||
| 
 | ||||
|     for (int x=0; x<segsX; ++x) | ||||
|     { | ||||
|         for (int y=0; y<segsY; ++y) | ||||
|         { | ||||
|             Vector2 start = min + Vector2(sSize*x,sSize*y); | ||||
|             Vector2 newcenter = start + 4096; | ||||
| 
 | ||||
|             render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize, | ||||
|                 cell->cell->name + "_" + coordStr(x,y)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void LocalMap::render(const float x, const float y, | ||||
|                     const float zlow, const float zhigh, | ||||
|                     const float xw, const float yw, const std::string& texture) | ||||
| { | ||||
|     // disable fog
 | ||||
|     // changing FOG_MODE is not a solution when using shaders, thus we have to push linear start/end
 | ||||
|     const float fStart = mRendering->getScene()->getFogStart(); | ||||
|     const float fEnd = mRendering->getScene()->getFogEnd(); | ||||
|     const ColourValue& clr = mRendering->getScene()->getFogColour(); | ||||
|     mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, 1000000, 10000000); | ||||
| 
 | ||||
|     // make everything visible
 | ||||
|     mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); | ||||
| 
 | ||||
|     mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); | ||||
|     //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
 | ||||
|     mCellCamera->setFarClipDistance(0); // infinite
 | ||||
| 
 | ||||
|     mCellCamera->setOrthoWindow(xw, yw); | ||||
| 
 | ||||
|     TexturePtr tex; | ||||
|     // try loading from memory
 | ||||
|     tex = TextureManager::getSingleton().getByName(texture); | ||||
|     if (tex.isNull()) | ||||
|     { | ||||
|         // try loading from disk
 | ||||
|         //if (boost::filesystem::exists(texture+".jpg"))
 | ||||
|         //{
 | ||||
|             /// \todo
 | ||||
|         //}
 | ||||
|         //else
 | ||||
|         { | ||||
|             // render
 | ||||
|             tex = TextureManager::getSingleton().createManual( | ||||
|                             texture, | ||||
|                             ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, | ||||
|                             TEX_TYPE_2D, | ||||
|                             xw*sMapResolution/sSize, yw*sMapResolution/sSize,  | ||||
|                             0, | ||||
|                             PF_R8G8B8, | ||||
|                             TU_RENDERTARGET); | ||||
| 
 | ||||
|             RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); | ||||
|             rtt->setAutoUpdated(false); | ||||
|             Viewport* vp = rtt->addViewport(mCellCamera); | ||||
|             vp->setOverlaysEnabled(false); | ||||
|             vp->setShadowsEnabled(false); | ||||
|             vp->setBackgroundColour(ColourValue(0, 0, 0)); | ||||
|             //vp->setVisibilityMask( ... );
 | ||||
| 
 | ||||
|             rtt->update(); | ||||
| 
 | ||||
|             // create "fog of war" texture
 | ||||
|             TexturePtr tex2 = TextureManager::getSingleton().createManual( | ||||
|                             texture + "_fog", | ||||
|                             ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, | ||||
|                             TEX_TYPE_2D, | ||||
|                             xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize,  | ||||
|                             0, | ||||
|                             PF_A8R8G8B8, | ||||
|                             TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); | ||||
| 
 | ||||
|             // create a buffer to use for dynamic operations
 | ||||
|             uint32* buffer = new uint32[sFogOfWarResolution*sFogOfWarResolution]; | ||||
| 
 | ||||
|             // initialize to (0, 0, 0, 1)
 | ||||
|             uint32* pointer = buffer; | ||||
|             for (int p=0; p<sFogOfWarResolution*sFogOfWarResolution; ++p) | ||||
|             { | ||||
|                 *(pointer+p) = (255 << 24); | ||||
|             } | ||||
| 
 | ||||
|             memcpy(tex2->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4); | ||||
|             tex2->getBuffer()->unlock(); | ||||
| 
 | ||||
|             mBuffers[texture] = buffer; | ||||
| 
 | ||||
|             // save to cache for next time
 | ||||
|             //rtt->writeContentsToFile("./" + texture + ".jpg");
 | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     // re-enable fog
 | ||||
|     mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); | ||||
| } | ||||
| 
 | ||||
| void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction) | ||||
| { | ||||
|     if (sFogOfWarSkip != 0) | ||||
|     { | ||||
|         static int count=0; | ||||
|         if (++count % sFogOfWarSkip != 0) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     // retrieve the x,y grid coordinates the player is in 
 | ||||
|     int x,y; | ||||
|     Vector2 pos(position.x, position.z); | ||||
|     if (!mInterior) | ||||
|     { | ||||
|         x = std::ceil(pos.x / sSize)-1; | ||||
|         y = std::ceil(-pos.y / sSize)-1; | ||||
|         mCellX = x; | ||||
|         mCellY = y; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); | ||||
|         min *= 1.3; | ||||
|          | ||||
|         x = std::ceil((pos.x - min.x)/sSize)-1; | ||||
|         y = std::ceil((pos.y - min.y)/sSize)-1; | ||||
| 
 | ||||
|         mEnvironment->mWindowManager->setInteriorMapTexture(x,y); | ||||
|     } | ||||
| 
 | ||||
|     // convert from world coordinates to texture UV coordinates
 | ||||
|     float u,v; | ||||
|     std::string texName; | ||||
|     if (!mInterior) | ||||
|     { | ||||
|         u = std::abs((pos.x - (sSize*x))/sSize); | ||||
|         v = 1-std::abs((pos.y + (sSize*y))/sSize); | ||||
|         texName = "Cell_"+coordStr(x,y); | ||||
| 
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); | ||||
|         min *= 1.3; | ||||
| 
 | ||||
|         u = (pos.x - min.x - sSize*x)/sSize; | ||||
|         v = (pos.y - min.y - sSize*y)/sSize; | ||||
| 
 | ||||
|         texName = mInteriorName + "_" + coordStr(x,y); | ||||
|     } | ||||
|     mEnvironment->mWindowManager->setPlayerPos(u, v); | ||||
|     mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z); | ||||
| 
 | ||||
|     // explore radius (squared)
 | ||||
|     const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; | ||||
| 
 | ||||
|     // get the appropriate fog of war texture
 | ||||
|     TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); | ||||
|     if (!tex.isNull()) | ||||
|     { | ||||
|         // get its buffer
 | ||||
|         if (mBuffers.find(texName) == mBuffers.end()) return; | ||||
|         uint32* buffer = mBuffers[texName]; | ||||
|         uint32* pointer = buffer; | ||||
|         for (int texV = 0; texV<sFogOfWarResolution; ++texV) | ||||
|         { | ||||
|             for (int texU = 0; texU<sFogOfWarResolution; ++texU) | ||||
|             { | ||||
|                 float sqrDist = Math::Sqr(texU - u*sFogOfWarResolution) + Math::Sqr(texV - v*sFogOfWarResolution); | ||||
|                 uint32 clr = *pointer; | ||||
|                 uint8 alpha = (clr >> 24); | ||||
|                 alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); | ||||
|                 *((uint32*)pointer) = (alpha << 24); | ||||
| 
 | ||||
|                 // move to next texel
 | ||||
|                 ++pointer; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // copy to the texture
 | ||||
|         memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), buffer, sFogOfWarResolution*sFogOfWarResolution*4); | ||||
|         tex->getBuffer()->unlock(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										100
									
								
								apps/openmw/mwrender/localmap.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								apps/openmw/mwrender/localmap.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,100 @@ | |||
| #ifndef _GAME_RENDER_LOCALMAP_H | ||||
| #define _GAME_RENDER_LOCALMAP_H | ||||
| 
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| #include <openengine/ogre/renderer.hpp> | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     class Environment; | ||||
| } | ||||
| 
 | ||||
| namespace MWRender | ||||
| { | ||||
|     ///
 | ||||
|     /// \brief Local map rendering
 | ||||
|     ///
 | ||||
|     class LocalMap | ||||
|     { | ||||
|     public: | ||||
|         LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env); | ||||
|         ~LocalMap(); | ||||
| 
 | ||||
|         /**
 | ||||
|          * Request the local map for an exterior cell. | ||||
|          * @remarks It will either be loaded from a disk cache, | ||||
|          * or rendered if it is not already cached. | ||||
|          * @param exterior cell | ||||
|          */ | ||||
|         void requestMap (MWWorld::Ptr::CellStore* cell); | ||||
| 
 | ||||
|         /**
 | ||||
|          * Request the local map for an interior cell. | ||||
|          * @remarks It will either be loaded from a disk cache, | ||||
|          * or rendered if it is not already cached. | ||||
|          * @param interior cell | ||||
|          * @param bounding box of the cell | ||||
|          */ | ||||
|         void requestMap (MWWorld::Ptr::CellStore* cell, | ||||
|                         Ogre::AxisAlignedBox bounds); | ||||
| 
 | ||||
|         /**
 | ||||
|          * Set the position & direction of the player. | ||||
|          * @remarks This is used to draw a "fog of war" effect | ||||
|          * to hide areas on the map the player has not discovered yet. | ||||
|          * @param position (OGRE coordinates) | ||||
|          * @param view direction (OGRE coordinates) | ||||
|          */ | ||||
|         void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction); | ||||
| 
 | ||||
|         /**
 | ||||
|          * Save the fog of war for the current cell to disk. | ||||
|          * @remarks This should be called before loading a | ||||
|          * new cell, as well as when the game is quit. | ||||
|          * @param current cell | ||||
|          */ | ||||
|         void saveFogOfWar(MWWorld::Ptr::CellStore* cell); | ||||
| 
 | ||||
|     private: | ||||
|         OEngine::Render::OgreRenderer* mRendering; | ||||
|         MWWorld::Environment* mEnvironment; | ||||
| 
 | ||||
|         // 1024*1024 pixels for a cell
 | ||||
|         static const int sMapResolution = 1024; | ||||
| 
 | ||||
|         // the dynamic texture is a bottleneck, so don't set this too high
 | ||||
|         static const int sFogOfWarResolution = 32; | ||||
| 
 | ||||
|         // frames to skip before rendering fog of war
 | ||||
|         static const int sFogOfWarSkip = 2; | ||||
| 
 | ||||
|         // size of a map segment (for exteriors, 1 cell)
 | ||||
|         static const int sSize = 8192; | ||||
| 
 | ||||
|         Ogre::Camera* mCellCamera; | ||||
| 
 | ||||
|         void render(const float x, const float y, | ||||
|                     const float zlow, const float zhigh, | ||||
|                     const float xw, const float yw, | ||||
|                     const std::string& texture); | ||||
| 
 | ||||
|         void saveTexture(const std::string& texname, const std::string& filename); | ||||
| 
 | ||||
|         std::string coordStr(const int x, const int y); | ||||
| 
 | ||||
|         // a buffer for the "fog of war" texture of the current cell.
 | ||||
|         // interior cells could be divided into multiple textures,
 | ||||
|         // so we store in a map.
 | ||||
|         std::map <std::string, Ogre::uint32*> mBuffers; | ||||
| 
 | ||||
|         void deleteBuffers(); | ||||
| 
 | ||||
|         bool mInterior; | ||||
|         int mCellX, mCellY; | ||||
|         Ogre::AxisAlignedBox mBounds; | ||||
|         std::string mInteriorName; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
| #endif | ||||
|  | @ -109,6 +109,9 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) | |||
|             // If it is set too low:
 | ||||
|             //  - there will be too many batches.
 | ||||
|             sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); | ||||
| 
 | ||||
|             mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; | ||||
|             mBounds[ptr.getCell()].merge(ent->getBoundingBox()); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | @ -116,6 +119,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) | |||
|         } | ||||
| 
 | ||||
|         sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); | ||||
|         mBounds[ptr.getCell()].merge(insert->_getDerivedPosition()); | ||||
| 
 | ||||
|         mRenderer.getScene()->destroyEntity(ent); | ||||
|     } | ||||
|  | @ -202,6 +206,9 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store) | |||
|         mRenderer.getScene()->destroyStaticGeometry (sg); | ||||
|         sg = 0; | ||||
|     } | ||||
|      | ||||
|     if(mBounds.find(store) != mBounds.end()) | ||||
|         mBounds.erase(store); | ||||
| } | ||||
| 
 | ||||
| void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell) | ||||
|  | @ -212,3 +219,8 @@ void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell) | |||
|         sg->build(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     return mBounds[cell]; | ||||
| } | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ class Objects{ | |||
|     OEngine::Render::OgreRenderer &mRenderer; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry; | ||||
|     std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds; | ||||
|     Ogre::SceneNode* mMwRoot; | ||||
|     bool mIsStatic; | ||||
|     static int uniqueID; | ||||
|  | @ -42,6 +43,9 @@ public: | |||
|     void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); | ||||
|     void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius); | ||||
| 
 | ||||
|     Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*); | ||||
|     ///< get a bounding box that encloses all objects in the specified cell
 | ||||
| 
 | ||||
|     bool deleteObject (const MWWorld::Ptr& ptr); | ||||
|     ///< \return found?
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -55,6 +55,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
| 
 | ||||
|     mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); | ||||
|     mSun = 0; | ||||
| 
 | ||||
|     mLocalMap = new MWRender::LocalMap(&mRendering, &environment); | ||||
| } | ||||
| 
 | ||||
| RenderingManager::~RenderingManager () | ||||
|  | @ -62,6 +64,7 @@ RenderingManager::~RenderingManager () | |||
|     //TODO: destroy mSun?
 | ||||
|     delete mPlayer; | ||||
|     delete mSkyManager; | ||||
|     delete mLocalMap; | ||||
| } | ||||
| 
 | ||||
| MWRender::SkyManager* RenderingManager::getSkyManager() | ||||
|  | @ -137,6 +140,8 @@ void RenderingManager::update (float duration){ | |||
|     mSkyManager->update(duration); | ||||
|      | ||||
|     mRendering.update(duration); | ||||
| 
 | ||||
|     mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() ); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::skyEnable () | ||||
|  | @ -327,4 +332,17 @@ void RenderingManager::setGlare(bool glare) | |||
|     mSkyManager->setGlare(glare); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::requestMap(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     if (!(cell->cell->data.flags & ESM::Cell::Interior)) | ||||
|         mLocalMap->requestMap(cell); | ||||
|     else | ||||
|         mLocalMap->requestMap(cell, mObjects.getDimensions(cell)); | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) | ||||
| { | ||||
|     mLocalMap->saveFogOfWar(cell); | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ | |||
| #include "objects.hpp" | ||||
| #include "actors.hpp" | ||||
| #include "player.hpp" | ||||
| #include "localmap.hpp" | ||||
| 
 | ||||
| namespace Ogre | ||||
| { | ||||
|  | @ -75,6 +76,9 @@ class RenderingManager: private RenderingInterface { | |||
|     /// when rebatching is needed and update automatically at the end of each frame.
 | ||||
|     void cellAdded (MWWorld::Ptr::CellStore *store); | ||||
| 
 | ||||
|     void preCellChange (MWWorld::Ptr::CellStore* store); | ||||
|     ///< this event is fired immediately before changing cell
 | ||||
| 
 | ||||
|     void addObject (const MWWorld::Ptr& ptr); | ||||
|     void removeObject (const MWWorld::Ptr& ptr); | ||||
| 
 | ||||
|  | @ -102,6 +106,9 @@ class RenderingManager: private RenderingInterface { | |||
|     int skyGetSecundaPhase() const; | ||||
|     void skySetMoonColour (bool red); | ||||
|     void configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell); | ||||
| 
 | ||||
|     void requestMap (MWWorld::Ptr::CellStore* cell); | ||||
|     ///< request the local map for a cell
 | ||||
|      | ||||
|     /// configure fog according to cell
 | ||||
|     void configureFog(ESMS::CellStore<MWWorld::RefData> &mCell); | ||||
|  | @ -148,6 +155,8 @@ class RenderingManager: private RenderingInterface { | |||
| 
 | ||||
|     MWRender::Player *mPlayer; | ||||
|     MWRender::Debugging mDebugging; | ||||
| 
 | ||||
|     MWRender::LocalMap* mLocalMap; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| 
 | ||||
| #include "../mwsound/soundmanager.hpp" | ||||
| 
 | ||||
| #include "../mwgui/window_manager.hpp" | ||||
| 
 | ||||
| #include "ptr.hpp" | ||||
| #include "environment.hpp" | ||||
| #include "player.hpp" | ||||
|  | @ -101,7 +103,8 @@ namespace MWWorld | |||
|               insertCell(*cell, mEnvironment); | ||||
|                mRendering.cellAdded (cell); | ||||
|                mRendering.configureAmbient(*cell); | ||||
| 
 | ||||
|                mRendering.requestMap(cell); | ||||
|                mRendering.configureAmbient(*cell); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -117,10 +120,14 @@ namespace MWWorld | |||
|         // TODO orientation
 | ||||
|         mEnvironment.mMechanicsManager->addActor (mWorld->getPlayer().getPlayer()); | ||||
|         mEnvironment.mMechanicsManager->watchActor (mWorld->getPlayer().getPlayer()); | ||||
| 
 | ||||
|         mEnvironment.mWindowManager->changeCell( mCurrentCell ); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) | ||||
|     { | ||||
|         mRendering.preCellChange(mCurrentCell); | ||||
| 
 | ||||
|         // remove active
 | ||||
|         mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY) | |||
| configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw_mainmenu_skin.xml" "${DDIR}/openmw_mainmenu_skin.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw_map_window_layout.xml" "${DDIR}/openmw_map_window_layout.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw_map_window_skin.xml" "${DDIR}/openmw_map_window_skin.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw.pointer.xml" "${DDIR}/openmw.pointer.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw_progress.skin.xml" "${DDIR}/openmw_progress.skin.xml" COPYONLY) | ||||
| configure_file("${SDIR}/openmw_stats_window_layout.xml" "${DDIR}/openmw_stats_window_layout.xml" COPYONLY) | ||||
|  |  | |||
|  | @ -14,4 +14,7 @@ | |||
|         <BasisSkin type="MainSkin" offset = "0 0 16 16"/> | ||||
|     </Skin> | ||||
| 
 | ||||
|     <Skin name = "RotatingSkin" size = "16 16"> | ||||
|         <BasisSkin type="RotatingSkin" offset="0 0 16 16" align="Stretch"/> | ||||
|     </Skin> | ||||
| </MyGUI> | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
|             <List file="openmw_mainmenu_skin.xml" group="General"/> | ||||
|             <List file="openmw_console.skin.xml" group="General"/> | ||||
|             <List file="openmw_journal_skin.xml" group="General"/> | ||||
|             <List file="openmw_map_window_skin.xml" group="General"/> | ||||
|             <List file="openmw_dialogue_window_skin.xml" group="General"/> | ||||
|             <List file="openmw_settings.xml" group="General"/> | ||||
|       </MyGUI> | ||||
|  |  | |||
|  | @ -38,10 +38,48 @@ | |||
|         <!-- Map box --> | ||||
|         <Widget type="Widget" skin="HUD_Box" position="223 123 65 65" | ||||
|             align="Right Bottom"> | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="2 2 61 61" align="Left Bottom" | ||||
|                 name="MiniMap"/> | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="17 18 32 32" align="Left Bottom" | ||||
|                 name="Compass"/> | ||||
| 
 | ||||
|             <Widget type="ScrollView" skin="MW_MapView" position="2 2 61 61" align="Left Bottom" name="MiniMap"> | ||||
|                 <Property key="CanvasSize" value="1536 1536"/> | ||||
|                <!-- 3x3 maps, 1024x1024 each, but we will downsample to 512 to antialias them --> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_0"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_0_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="512 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_0"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_0_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="1024 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_0"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_0_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_1"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_1_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="512 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_1"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_1_fog"> | ||||
|                         <Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="Left Bottom" name="Compass"/> | ||||
|                     </Widget> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="1024 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_1"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_1_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_2"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_2_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="512 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_2"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_2_fog"/> | ||||
|                 </Widget> | ||||
| 
 | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="1024 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_2"> | ||||
|                     <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_2_fog"/> | ||||
|                 </Widget> | ||||
|             </Widget> | ||||
|         </Widget> | ||||
| 
 | ||||
|         <!-- Crosshair --> | ||||
|  |  | |||
|  | @ -197,7 +197,7 @@ | |||
|         <Child type="ScrollBar" skin="MW_VScroll" offset = "498 3 14 509" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "VScroll"> | ||||
|         </Child> | ||||
| 
 | ||||
|         <Child type="Widget" skin="ClientDefaultSkin" offset = "3 3 493 509" align = "ALIGN_STRETCH" name = "Client"> | ||||
|         <Child type="Widget" skin="" offset = "3 3 493 509" align = "ALIGN_STRETCH" name = "Client"> | ||||
|         </Child> | ||||
| 
 | ||||
|         <Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/> | ||||
|  | @ -233,7 +233,7 @@ | |||
| 
 | ||||
|         <Property key="SkinList" value = "MW_MultiSubList" /> | ||||
| 
 | ||||
|         <Child type="Widget" skin="ClientDefaultSkin" offset = "3 3 516 516" align = "ALIGN_STRETCH" name = "Client"> | ||||
|         <Child type="Widget" skin="" offset = "3 3 516 516" align = "ALIGN_STRETCH" name = "Client"> | ||||
|         </Child> | ||||
| 
 | ||||
|         <Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/> | ||||
|  |  | |||
|  | @ -2,8 +2,60 @@ | |||
| 
 | ||||
| <MyGUI type="Layout"> | ||||
|     <Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 300 300" name="_Main"> | ||||
|         <Widget type="ImageBox" skin="ImageBox" position="0 0 284 264" align="ALIGN_STRETCH" name="Map"/> | ||||
|         <Widget type="ImageBox" skin="ImageBox" position="126 116 32 32" align="Center" name="Compass"/> | ||||
| 
 | ||||
|         <!-- Global map --> | ||||
|         <Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="GlobalMap"> | ||||
|         </Widget> | ||||
| 
 | ||||
|         <!-- Local map --> | ||||
|         <Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="ALIGN_STRETCH" name="LocalMap"> | ||||
|             <Property key="CanvasSize" value="1536 1536"/> | ||||
| 
 | ||||
|             <!-- 3x3 maps, 1024x1024 each, but we will downsample to 512 to antialias them --> | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_0"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_0_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="512 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_0"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_0_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="1024 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_0"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_0_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="0 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_1"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_1_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="512 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_1"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_1_fog"> | ||||
|                     <!-- Player arrow --> | ||||
|                     <Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="ALIGN_TOP ALIGN_LEFT" name="Compass"/> | ||||
|                 </Widget> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="1024 512 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_1"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_1_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="0 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_2"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_0_2_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="512 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_2"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_1_2_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="1024 1024 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_2"> | ||||
|                 <Widget type="ImageBox" skin="ImageBox" position="0 0 512 512" align="ALIGN_TOP ALIGN_LEFT" name="Map_2_2_fog"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|             <Widget type="Button" skin="" position="0 0 1536 1536" name="EventBox" align="ALIGN_STRETCH"/> | ||||
|         </Widget> | ||||
| 
 | ||||
|         <!-- World button --> | ||||
|         <Widget type="Button" skin="MW_Button" position="213 233 61 22" align="ALIGN_BOTTOM ALIGN_RIGHT" name="WorldButton"/> | ||||
| 
 | ||||
|     </Widget> | ||||
| </MyGUI> | ||||
|  |  | |||
							
								
								
									
										11
									
								
								files/mygui/openmw_map_window_skin.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								files/mygui/openmw_map_window_skin.xml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| 
 | ||||
| <MyGUI type="Skin"> | ||||
|     <Skin name="MW_MapView" size="516 516" texture="mwgui.png"> | ||||
|         <Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/> | ||||
| 
 | ||||
|         <!-- invisible scroll bars, needed for setting the view offset --> | ||||
|         <Child type="ScrollBar" skin="" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/> | ||||
|         <Child type="ScrollBar" skin="" offset="3 498 489 14" align="ALIGN_BOTTOM ALIGN_HSTRETCH" name="HScroll"/> | ||||
|     </Skin> | ||||
| </MyGUI> | ||||
		Loading…
	
		Reference in a new issue