Bläddra i källkod

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

Frank Zago 16 år sedan
förälder
incheckning
1c2ac579d5
4 ändrade filer med 71 tillägg och 45 borttagningar
  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