فهرست منبع

The size of the frame around the map depends on the screen size, so compute it.

Frank Zago 16 سال پیش
والد
کامیت
1c2ac579d5
4فایلهای تغییر یافته به همراه71 افزوده شده و 45 حذف شده
  1. 4 4
      client/CAdvmapInterface.cpp
  2. 9 9
      client/CPlayerInterface.cpp
  3. 40 20
      mapHandler.cpp
  4. 18 12
      mapHandler.h

+ 4 - 4
client/CAdvmapInterface.cpp

@@ -1461,16 +1461,16 @@ void CAdvMapInt::show(SDL_Surface *to)
 			|| SDL_GetKeyState(NULL)[SDLK_RCTRL]
 	)
 	{
-		if( (scrollingDir & LEFT)   &&  (position.x>-Woff) )
+		if( (scrollingDir & LEFT)   &&  (position.x>-CGI->mh->frame.left) )
 			position.x--;
 
-		if( (scrollingDir & RIGHT)  &&  (position.x   <   CGI->mh->map->width - terrain.tilesw + Woff) )
+		if( (scrollingDir & RIGHT)  &&  (position.x   <   CGI->mh->map->width - terrain.tilesw + CGI->mh->frame.right) )
 			position.x++;
 
-		if( (scrollingDir & UP)  &&  (position.y>-Hoff) )
+		if( (scrollingDir & UP)  &&  (position.y>-CGI->mh->frame.top) )
 			position.y--;
 
-		if( (scrollingDir & DOWN)  &&  (position.y  <  CGI->mh->map->height - terrain.tilesh + Hoff) )
+		if( (scrollingDir & DOWN)  &&  (position.y  <  CGI->mh->map->height - terrain.tilesh + CGI->mh->frame.bottom) )
 			position.y++;
 
 		if(scrollingDir)

+ 9 - 9
client/CPlayerInterface.cpp

@@ -1024,14 +1024,14 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 
 int3 CPlayerInterface::repairScreenPos(int3 pos)
 {
-	if(pos.x<=-Woff)
-		pos.x = -Woff+1;
-	if(pos.y<=-Hoff)
-		pos.y = -Hoff+1;
-	if(pos.x>CGI->mh->map->width - this->adventureInt->terrain.tilesw + Woff)
-		pos.x = CGI->mh->map->width - this->adventureInt->terrain.tilesw + Woff;
-	if(pos.y>CGI->mh->map->height - this->adventureInt->terrain.tilesh + Hoff)
-		pos.y = CGI->mh->map->height - this->adventureInt->terrain.tilesh + Hoff;
+	if(pos.x<=-CGI->mh->frame.left)
+		pos.x = -CGI->mh->frame.left+1;
+	if(pos.y<=-CGI->mh->frame.top)
+		pos.y = -CGI->mh->frame.top+1;
+	if(pos.x>CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frame.right)
+		pos.x = CGI->mh->map->width - this->adventureInt->terrain.tilesw + CGI->mh->frame.right;
+	if(pos.y>CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frame.bottom)
+		pos.y = CGI->mh->map->height - this->adventureInt->terrain.tilesh + CGI->mh->frame.bottom;
 	return pos;
 }
 void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val)
@@ -1736,4 +1736,4 @@ const CGHeroInstance * CPlayerInterface::getWHero( int pos )
 	if(pos < 0 || pos >= wanderingHeroes.size())
 		return NULL;
 	return wanderingHeroes[pos];
-}
+}

+ 40 - 20
mapHandler.cpp

@@ -15,6 +15,7 @@
 #include "hch/CObjectHandler.h"
 #include "lib/map.h"
 #include "hch/CDefHandler.h"
+#include "client/CConfigHandler.h"
 
 /*
  * mapHandler.cpp, part of VCMI engine
@@ -204,17 +205,20 @@ void CMapHandler::roadsRiverTerrainInit()
 	sizes.x = CGI->mh->map->width;
 	sizes.y = CGI->mh->map->height;
 	sizes.z = CGI->mh->map->twoLevel+1;
-	ttiles.resize(CGI->mh->map->width,Woff);
-	for (int i=0-Woff;i<ttiles.size()-Woff;i++)
+
+	// Create enough room for the whole map and its frame
+	ttiles.resize(CGI->mh->map->width, frame.left, frame.right);
+	for (int i=0-frame.left;i<ttiles.size()-frame.left;i++)
 	{
-		ttiles[i].resize(CGI->mh->map->height,Hoff);
+		ttiles[i].resize(CGI->mh->map->height, frame.top, frame.bottom);
 	}
-	for (int i=0-Woff;i<ttiles.size()-Woff;i++)
+	for (int i=0-frame.left;i<ttiles.size()-frame.left;i++)
 	{
-		for (int j=0-Hoff;j<(int)CGI->mh->map->height+Hoff;j++)
-			ttiles[i][j].resize(CGI->mh->map->twoLevel+1,0);
+		for (int j=0-frame.top;j<(int)CGI->mh->map->height+frame.bottom;j++)
+			ttiles[i][j].resize(CGI->mh->map->twoLevel+1, 0, 0);
 	}
 
+	// Draw the map
 	for (int i=0; i<map->width; i++) //jest po szeroko�ci
 	{
 		for (int j=0; j<map->height;j++) //po wysoko�ci
@@ -311,9 +315,9 @@ void CMapHandler::borderAndTerrainBitmapInit()
 		delete hlp;
 	}
 
-	for (int i=0-Woff; i<map->width+Woff; i++) //jest po szeroko�ci
+	for (int i=0-frame.left; i<map->width+frame.right; i++) //jest po szeroko�ci
 	{
-		for (int j=0-Hoff; j<map->height+Hoff;j++) //po wysoko�ci
+		for (int j=0-frame.top; j<map->height+frame.bottom;j++) //po wysoko�ci
 		{
 			for(int k=0; k<=map->twoLevel; ++k)
 			{
@@ -398,9 +402,9 @@ void CMapHandler::initObjectRects()
 					std::pair<CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(map->objects[f],cr);
 					
 					if(    (map->objects[f]->pos.x + fx - bitmap->w/32+1)  >=  0 
-						&& (map->objects[f]->pos.x + fx - bitmap->w/32+1)  <  ttiles.size() - Woff 
+						&& (map->objects[f]->pos.x + fx - bitmap->w/32+1)  <  ttiles.size() - frame.right 
 						&& (map->objects[f]->pos.y + fy - bitmap->h/32+1)  >=  0 
-						&& (map->objects[f]->pos.y + fy - bitmap->h/32+1)  <  ttiles[0].size() - Hoff
+						&& (map->objects[f]->pos.y + fy - bitmap->h/32+1)  <  ttiles[0].size() - frame.bottom
 					  )
 					{
 						//TerrainTile2 & curt =
@@ -414,9 +418,9 @@ void CMapHandler::initObjectRects()
 			} //for(int fx=0; fx<bitmap->w/32; ++fx)
 		}//if curd
 	} // for(int f=0; f<map->objects.size(); ++f)
-	for(int ix=0; ix<ttiles.size()-Woff; ++ix)
+	for(int ix=0; ix<ttiles.size()-frame.left; ++ix)
 	{
-		for(int iy=0; iy<ttiles[0].size()-Hoff; ++iy)
+		for(int iy=0; iy<ttiles[0].size()-frame.top; ++iy)
 		{
 			for(int iz=0; iz<ttiles[0][0].size(); ++iz)
 			{
@@ -473,6 +477,17 @@ void CMapHandler::init()
 	timeHandler th;
 	th.getDif();
 
+	// Size of the frame around the map. In extremes positions, the
+	// frame must not be on the center of the map, but right on the
+	// edge of the center tile. Consequently, frame.left + 1 +
+	// frame.right = size of the window map on the screen. Same for
+	// top/bottom. And the sizes will be different on opposite sides
+	// if the length of the window map is even.
+	frame.left = (conf.go()->ac.tilesW-1) / 2;
+	frame.right = (conf.go()->ac.tilesW) / 2;
+	frame.top = (conf.go()->ac.tilesH-1) / 2;
+	frame.bottom = (conf.go()->ac.tilesH) / 2;
+
 	std::ifstream ifs("config/townsDefs.txt");
 	int ccc;
 	ifs>>ccc;
@@ -531,9 +546,9 @@ void CMapHandler::init()
 SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, unsigned char anim, std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect, int moveX, int moveY, bool smooth)
 {
 	int srx, sry;
-
-        // Temporarily disable smoothing as it is source of crashes
-	smooth = false;
+
+	// Temporarily disable smoothing as it is source of crashes
+	smooth = false;
 
 	if(!otherHeroAnim)
 		heroAnim = anim; //the same, as it should be
@@ -551,12 +566,16 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
 	SDL_GetClipRect(su, &prevClip);
 	if(extRect) SDL_SetClipRect(su, extRect); //preventing blitting outside of that rect
 
-	if (((dx+x)>((map->width+Woff)) || (dy+y)>((map->height+Hoff))) || ((x<-Woff)||(y<-Hoff) ) )
-		throw std::string("terrainRect: out of range");
-
 	dx += smooth?1:0;
 	dy += smooth?1:0;
 
+	// Sanity check - TODO: fails if smooth mode
+	if (dx+x > map->width+frame.right ||
+		dy+y > map->height+frame.bottom ||
+		x<-frame.left ||
+		y<-frame.right)
+		throw std::string("terrainRect: out of range");
+
 	////printing terrain
 	srx = (moveX <= 0 ? 0 : -1) * 32;
 	if (smooth)
@@ -1234,7 +1253,7 @@ bool CMapHandler::printObject(const CGObjectInstance *obj)
 			cr.x = fx*32;
 			cr.y = fy*32;
 			std::pair<const CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj, cr);
-			if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-Woff && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-Hoff)
+			if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-frame.right && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-frame.bottom)
 			{
 				TerrainTile2 & curt = //TODO use me 
 					ttiles
@@ -1260,7 +1279,7 @@ bool CMapHandler::hideObject(const CGObjectInstance *obj)
 	{
 		for(int fy=0; fy<bitmap->h/32; ++fy)
 		{
-			if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-Woff && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-Hoff)
+			if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-frame.right && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-frame.bottom)
 			{
 				std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > & ctile = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z].objects;
 				for(size_t dd=0; dd < ctile.size(); ++dd)
@@ -1448,6 +1467,7 @@ CMapHandler::~CMapHandler()
 
 CMapHandler::CMapHandler()
 {
+	frame.left = frame.right = frame.top = frame.bottom = 0;
 	fullHide = NULL;
 	partialHide = NULL;
 }

+ 18 - 12
mapHandler.h

@@ -4,9 +4,6 @@
 #include <list>
 #include <set>
 
-const int Woff = 14; //width of map's frame
-const int Hoff = 10;
-
 /*
  * mapHandler.h, part of VCMI engine
  *
@@ -48,15 +45,15 @@ public:
 	int offset;
 	std::vector<T> inver;
 	PseudoV(){};
-	PseudoV(std::vector<T> &src, int rest, int Offset, const T& fill)
+	PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill)
 	{
-		inver.resize(Offset*2+rest);
-		offset=Offset;
-		for(int i=0; i<offset;i++)
+		inver.resize(before + rest + after);
+		offset=before;
+		for(int i=0; i<before;i++)
 			inver[i] = fill;
 		for(int i=0;i<src.size();i++)
 			inver[offset+i] = src[i];
-		for(int i=src.size(); i<src.size()+offset;i++)
+		for(int i=src.size(); i<src.size()+after;i++)
 			inver[offset+i] = fill;
 	}
 	inline T & operator[](const int & n)
@@ -67,10 +64,10 @@ public:
 	{
 		return inver[n+offset];
 	}
-	void resize(int rest,int Offset)
+	void resize(int rest, int before, int after)
 	{
-		inver.resize(Offset*2+rest);
-		offset=Offset;
+		inver.resize(before + rest + after);
+		offset=before;
 	}
 	int size() const
 	{
@@ -81,8 +78,17 @@ class CMapHandler
 {
 public:
 	PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles; //informations about map tiles
-	int3 sizes; //map size (x - width, y - height, z - number of levels)
+	int3 sizes; //map size (x = width, y = height, z = number of levels)
 	Mapa * map;
+
+	// size of each side of the frame around the whole map
+	struct {
+		int left;
+		int right;
+		int top;
+		int bottom;
+	} frame;
+
 	std::set<int> usedHeroes;
 	CDefHandler * fullHide; //for Fog of War
 	CDefHandler * partialHide; //for For of War