浏览代码

* a bit better screen scrolling for small resolutions
* a bit optimized terrainRect

mateuszb 15 年之前
父节点
当前提交
d1bfe4cbd6
共有 7 个文件被更改,包括 42 次插入48 次删除
  1. 5 36
      client/CMT.cpp
  2. 3 2
      client/CPlayerInterface.cpp
  3. 2 3
      client/CPreGame.cpp
  4. 18 0
      client/GUIBase.cpp
  5. 5 1
      client/GUIBase.h
  6. 8 5
      client/mapHandler.cpp
  7. 1 1
      client/mapHandler.h

+ 5 - 36
client/CMT.cpp

@@ -71,22 +71,10 @@ static CClient *client;
 SDL_Surface *screen = NULL, //main screen surface 
 	*screen2 = NULL,//and hlp surface (used to store not-active interfaces layer) 
 	*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
-int screenScrollingDir = 0; //used for displays smaller then selected resolution; 0 - no scrolling, & 1 - down, & 2 - up, & 4 - right, & 8 - left
 Point screenLT = Point(0, 0); //position of top left corner of the screen
+Point screenLTmax = Point(0, 0); //,maximal values for screenLT coordinates
 static boost::thread *mainGUIThread;
 
-void updateScreenLT(int maxW, int maxH)
-{
-	if (screenScrollingDir & 1) //down
-	{
-		screenLT.y = std::max<int>(screenLT.y - 5, screen->h - maxH);
-	}
-	else if (screenScrollingDir & 2) //up
-	{
-		screenLT.y = std::min<int>(screenLT.y + 5, 0);
-	}
-	GH.totalRedraw();
-}
 
 SystemOptions GDefaultOptions; 
 VCMIDirs GVCMIDirs;
@@ -589,7 +577,7 @@ static void listenForEvents()
 		{
 			boost::unique_lock<boost::recursive_mutex> lock(*LOCPLINT->pim);
 			bool full = !(screen->flags&SDL_FULLSCREEN);
-			setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,full);
+			setScreenRes(conf.cc.screenx, conf.cc.screeny, conf.cc.bpp, full);
 			GH.totalRedraw();
 			delete ev;
 			continue;
@@ -600,7 +588,7 @@ static void listenForEvents()
 			{
 			case 1:
 				tlog0 << "Changing resolution has been requested\n";
-				setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
+				setScreenRes(conf.cc.screenx, conf.cc.screeny, conf.cc.bpp, conf.cc.fullscreen);
 				break;
 
 			case 2:
@@ -623,26 +611,7 @@ static void listenForEvents()
 
 			delete ev;
 			continue;
-		} else if (ev->type == SDL_MOUSEMOTION)
-		{
-			if (conf.cc.resy > screen->h)
-			{
-				if (std::abs(ev->motion.y - screen->h) < 10 ) //scroll down
-				{
-					screenScrollingDir &= (~2);
-					screenScrollingDir |= 1;
-				}
-				else if (std::abs(ev->motion.y) < 10) //scroll up
-				{
-					screenScrollingDir &= (~1);
-					screenScrollingDir |= 2;
-				}
-				else //don't scroll vertically
-				{
-					screenScrollingDir &= (~3);
-				}
-			}
-		}
+		} 
 
 		//tlog0 << " pushing ";
 		eventsM.lock();
@@ -664,7 +633,7 @@ void startGame(StartInfo * options)
 		}
 	}
 
-	if(screen->w != conf.cc.resx   ||   screen->h != conf.cc.resy)
+	if(screen->w != conf.cc.screenx   ||   screen->h != conf.cc.screeny)
 	{
 		requestChangingResolution();
 

+ 3 - 2
client/CPlayerInterface.cpp

@@ -66,7 +66,8 @@ using namespace boost::assign;
 using namespace CSDL_Ext;
 
 void processCommand(const std::string &message, CClient *&client);
-void updateScreenLT(int maxW, int maxH);
+
+extern Point screenLTmax;
 
 extern std::queue<SDL_Event*> events;
 extern boost::mutex eventsM;
@@ -1332,7 +1333,7 @@ void CPlayerInterface::update()
 	CSDL_Ext::update(screen);
 	CGI->curh->draw2();
 
-	updateScreenLT(conf.cc.resx, conf.cc.resy);
+	screenLTmax = Point(conf.cc.resx - screen->w, conf.cc.resy - screen->h);
 
 	pim->unlock();
 

+ 2 - 3
client/CPreGame.cpp

@@ -53,14 +53,13 @@ namespace fs = boost::filesystem;
 using boost::bind;
 using boost::ref;
 
-void updateScreenLT(int maxW, int maxH);
-
 #if _MSC_VER >= 1600
 	#define bind boost::bind
 	#define ref boost::ref
 #endif
 
 void startGame(StartInfo * options);
+extern Point screenLTmax;
 
 CGPreGame * CGP;
 static const CMapInfo *curMap;
@@ -303,7 +302,7 @@ void CGPreGame::update()
 	CGI->curh->draw1();
 	SDL_Flip(screen);
 	CGI->curh->draw2();
-	updateScreenLT(800, 600);
+	screenLTmax = Point(800 - screen->w, 600 - screen->h);
 	GH.topInt()->show(screen);
 	GH.updateTime();
 	GH.handleEvents();

+ 18 - 0
client/GUIBase.cpp

@@ -21,6 +21,7 @@
 extern std::queue<SDL_Event*> events;
 extern boost::mutex eventsM;
 extern Point screenLT;
+extern Point screenLTmax;
 
 void KeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
 {
@@ -268,6 +269,23 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
 			else
 				(*i)->clickLeft(boost::logic::indeterminate, prev);
 		}
+
+		//screen drag-and-drop handling
+		if (screenLTmax != Point(0,0))
+		{
+			int diffX = sEvent->motion.x - lastClick.x,
+				diffY = sEvent->motion.y - lastClick.y;
+
+			screenLT.x += diffX;
+			amin(screenLT.x, 0);
+			amax(screenLT.x, -screenLTmax.x);
+
+			screenLT.y += diffY;
+			amin(screenLT.y, 0);
+			amax(screenLT.y, -screenLTmax.y);
+			totalRedraw();
+		}
+
 	}
 	else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_RIGHT))
 	{

+ 5 - 1
client/GUIBase.h

@@ -112,10 +112,14 @@ struct Point
 		y = t.y;
 		return *this;
 	}
-	template<typename T> bool operator==(const T &t)
+	template<typename T> bool operator==(const T &t) const
 	{
 		return x == t.x  &&  y == t.y;
 	}
+	template<typename T> bool operator!=(const T &t) const
+	{
+		return !(*this == t);
+	}
 };
 
 struct Rect : public SDL_Rect

+ 8 - 5
client/mapHandler.cpp

@@ -688,8 +688,11 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, const std::vect
 						pos.y < sizes.y &&
 						!(*visibilityMap)[pos.x][pos.y][top_tile.z])
 					{
-						SDL_Surface * hide = getVisBitmap(pos, *visibilityMap);
-						CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr);
+						std::pair<SDL_Surface *, bool> hide = getVisBitmap(pos, *visibilityMap);
+						if(hide.second)
+							CSDL_Ext::blit8bppAlphaTo24bpp(hide.first, &rtile, extSurf, &sr);
+						else
+							CSDL_Ext::blitSurface(hide.first, &rtile, extSurf, &sr);
 					}
 				}
 				
@@ -775,7 +778,7 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, const std::vect
 	SDL_SetClipRect(extSurf, &prevClip); //restoring clip_rect
 }
 
-SDL_Surface * CMapHandler::getVisBitmap( const int3 & pos, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap )
+std::pair<SDL_Surface *, bool> CMapHandler::getVisBitmap( const int3 & pos, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap )
 {
 	static const int visBitmaps[256] = {-1, 34, -1, 4, 22, 22, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, 3, 25, 12, 12, 3, 25, 12, 12,
 		9, 9, 6, 6, 9, 9, 6, 6, 35, 34, 4, 4, 22, 22, 4, 4, 36, 36, 38, 38, 47, 47, 38, 38, 26, 49, 28, 28, 26, 49, 28,
@@ -808,11 +811,11 @@ SDL_Surface * CMapHandler::getVisBitmap( const int3 & pos, const std::vector< st
 	
 	if (retBitmapID >= 0)
 	{
-		return graphics->FoWpartialHide->ourImages[retBitmapID].bitmap;
+		return std::make_pair(graphics->FoWpartialHide->ourImages[retBitmapID].bitmap, true);
 	}
 	else
 	{
-		return graphics->FoWfullHide->ourImages[-retBitmapID - 1].bitmap;
+		return std::make_pair(graphics->FoWfullHide->ourImages[-retBitmapID - 1].bitmap, false);
 	}
 }
 

+ 1 - 1
client/mapHandler.h

@@ -102,7 +102,7 @@ public:
 	CMapHandler(); //c-tor
 	~CMapHandler(); //d-tor
 
-	SDL_Surface * getVisBitmap(const int3 & pos, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap);
+	std::pair<SDL_Surface *, bool> getVisBitmap(const int3 & pos, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap); //returns appropriate bitmap and info if alpha blitting is necessary
 
 	std::vector< std::string > getObjDescriptions(int3 pos); //returns desriptions of objects blocking given position
 	void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear