From 7a0a63b606c81f8e5761773cb65afdde4614cf64 Mon Sep 17 00:00:00 2001
From: Cinder <cinder@sdf.org>
Date: Sun, 26 Jul 2015 15:41:12 -0600
Subject: [PATCH] Dump in opensim

---
 indra/CMakeLists.txt                         |   1 +
 indra/cmake/00-Common.cmake                  |   2 +-
 indra/llcommon/lluri.cpp                     |   8 +
 indra/llcommon/lluri.h                       |  29 ++--
 indra/llmessage/message_prehash.cpp          |   6 +
 indra/llmessage/message_prehash.h            |   7 +
 indra/llmessage/patch_code.cpp               |  24 ++-
 indra/llmessage/patch_code.h                 |   2 +-
 indra/llmessage/patch_dct.h                  |   2 +-
 indra/llrender/llimagegl.cpp                 |   2 +-
 indra/newview/CMakeLists.txt                 |   1 +
 indra/newview/app_settings/grids_default.xml |  34 ++++
 indra/newview/llagent.cpp                    |   9 +-
 indra/newview/llfloaterworldmap.cpp          |  26 ++-
 indra/newview/llglsandbox.cpp                |   2 +-
 indra/newview/llmanip.cpp                    |   3 +-
 indra/newview/llmanipscale.cpp               |   2 +-
 indra/newview/llnetmap.cpp                   |  15 +-
 indra/newview/llpatchvertexarray.cpp         |  24 +--
 indra/newview/llslurl.cpp                    |  10 +-
 indra/newview/llstartup.cpp                  |  18 +-
 indra/newview/llsurface.cpp                  | 163 +++++++++++++------
 indra/newview/llsurfacepatch.cpp             |  62 +++++--
 indra/newview/llviewermessage.cpp            |  16 ++
 indra/newview/llviewerobject.cpp             |   2 +-
 indra/newview/llviewerparcelmgr.cpp          |  19 ++-
 indra/newview/llviewerparcelmgr.h            |   1 +
 indra/newview/llviewerparceloverlay.cpp      |   4 +-
 indra/newview/llviewerparceloverlay.h        |   1 +
 indra/newview/llviewerregion.cpp             |  34 ++--
 indra/newview/llvlcomposition.cpp            |   2 +-
 indra/newview/llvlmanager.cpp                |  21 ++-
 indra/newview/llvlmanager.h                  |   2 +
 indra/newview/llvowater.cpp                  |   2 +-
 indra/newview/llwind.cpp                     |   4 +-
 indra/newview/llworld.cpp                    |  93 ++++++++---
 indra/newview/llworld.h                      |   6 +-
 indra/newview/llworldmap.cpp                 |  21 ++-
 indra/newview/llworldmap.h                   |  13 +-
 indra/newview/llworldmapmessage.cpp          |  14 +-
 indra/newview/tests/llslurl_test.cpp         |   6 +
 41 files changed, 524 insertions(+), 189 deletions(-)
 create mode 100644 indra/newview/app_settings/grids_default.xml

diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 3885ff759b..c00c3980b9 100755
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -22,6 +22,7 @@ if (NOT MSVC AND NOT LINUX)
   include(FindCXXThreadLocal)
 endif (NOT MSVC AND NOT LINUX)
 include(BuildVersion)
+include(FindCXXThreadLocal)
 
 if (NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 089e56307e..5deac06b4c 100755
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -211,7 +211,7 @@ if (LINUX OR DARWIN)
     set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder")
   elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
     set(UNIX_WARNINGS "-Wall -Wno-sign-compare ${UNIX_WARNINGS} ")
-    set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder")
+    set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder -Wno-unused-local-typedef")
   elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
     set(UNIX_WARNINGS "-w2 -diag-disable remark -wd68 -wd597 -wd780 -wd858 ${UNIX_WARNINGS} ")
     set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}")
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 9f12d49244..24e3592a5e 100755
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -504,6 +504,14 @@ std::string LLURI::hostName() const
 	return unescape(host);
 }
 
+std::string LLURI::hostNameAndPort() const
+{
+	std::string user, host, port;
+	findAuthorityParts(mEscapedAuthority, user, host, port);
+	return port.empty() ? unescape(host) : unescape(host + ":" + port);
+}
+
+
 std::string LLURI::userName() const
 {
 	std::string user, userPass, host, port;
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index c82a666e48..4919f21086 100755
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -93,20 +93,21 @@ public:
 	std::string scheme() const;		///< ex.: "http", note lack of colon
 	std::string opaque() const;		///< everything after the colon
   
-  // for schemes that follow path like syntax (http, https, ftp)
-  std::string authority() const;	// ex.: "host.com:80"
-  std::string hostName() const;	// ex.: "host.com"
-  std::string userName() const;
-  std::string password() const;
-  U16 hostPort() const;			// ex.: 80, will include implicit port
-  BOOL defaultPort() const;		// true if port is default for scheme
-  const std::string& escapedPath() const { return mEscapedPath; }
-  std::string path() const;		// ex.: "/abc/def", includes leading slash
-  LLSD pathArray() const;			// above decoded into an array of strings
-  std::string query() const;		// ex.: "x=34", section after "?"
-  const std::string& escapedQuery() const { return mEscapedQuery; }
-  LLSD queryMap() const;			// above decoded into a map
-  static LLSD queryMap(std::string escaped_query_string);
+	// for schemes that follow path like syntax (http, https, ftp)
+	std::string authority() const;	// ex.: "user:pass@host.com:80"
+	std::string hostName() const;	// ex.: "host.com"
+	std::string hostNameAndPort() const; // ex.: "host.com:80"
+	std::string userName() const;
+	std::string password() const;
+	U16 hostPort() const;			// ex.: 80, will include implicit port
+	BOOL defaultPort() const;		// true if port is default for scheme
+	const std::string& escapedPath() const { return mEscapedPath; }
+	std::string path() const;		// ex.: "/abc/def", includes leading slash
+	LLSD pathArray() const;			// above decoded into an array of strings
+	std::string query() const;		// ex.: "x=34", section after "?"
+	const std::string& escapedQuery() const { return mEscapedQuery; }
+	LLSD queryMap() const;			// above decoded into a map
+	static LLSD queryMap(std::string escaped_query_string);
 
 	/**
 	 * @brief given a name value map, return a serialized query string.
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5c6b3d5fab..e87118c374 100755
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1387,3 +1387,9 @@ char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()
 char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
 char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
 char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
+
+// Varregion support
+char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");
+char const* const _PREHASH_RegionSizeY = LLMessageStringTable::getInstance()->getString("RegionSizeY");
+char const* const _PREHASH_SizeX = LLMessageStringTable::getInstance()->getString("SizeX");
+char const* const _PREHASH_SizeY = LLMessageStringTable::getInstance()->getString("SizeY");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index e696c3b0ca..3afb71a763 100755
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1387,4 +1387,11 @@ extern char const* const _PREHASH_AppearanceHover;
 extern char const* const _PREHASH_HoverHeight;
 extern char const* const _PREHASH_Experience;
 extern char const* const _PREHASH_ExperienceID;
+
+// Varregion support
+extern char const* const _PREHASH_RegionSizeX;
+extern char const* const _PREHASH_RegionSizeY;
+extern char const* const _PREHASH_SizeX;
+extern char const* const _PREHASH_SizeY;
+
 #endif
diff --git a/indra/llmessage/patch_code.cpp b/indra/llmessage/patch_code.cpp
index 32f8d80782..4fd754c35b 100755
--- a/indra/llmessage/patch_code.cpp
+++ b/indra/llmessage/patch_code.cpp
@@ -229,7 +229,7 @@ void	decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
 	gPatchSize = gopp->patch_size; 
 }
 
-void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph)
+void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, bool b_large_patch)
 {
 	U8 retvalu8;
 
@@ -268,15 +268,25 @@ void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph)
 #endif
 	ph->range = retvalu16;
 
-	retvalu16 = 0;
+	retvalu32 = 0;
 #ifdef LL_BIG_ENDIAN
-	ret = (U8 *)&retvalu16;
-	bitpack.bitUnpack(&(ret[1]), 8);
-	bitpack.bitUnpack(&(ret[0]), 2);
+	ret = (U8*)&retvalu32;
+	if (b_large_patch)
+	{
+		bitpack.bitUnpack(&(ret[3]), 8);
+		bitpack.bitUnpack(&(ret[2]), 8);
+		bitpack.bitUnpack(&(ret[1]), 8);
+		bitpack.bitUnpack(&(ret[0]), 8);
+	}
+	else
+	{
+		bitpack.bitUnpack(&(ret[1]), 8);
+		bitpack.bitUnpack(&(ret[0]), 2);
+	}
 #else
-	bitpack.bitUnpack((U8 *)&retvalu16, 10);
+	bitpack.bitUnpack((U8*)&retvalu32, b_large_patch ? 32 : 10);
 #endif
-	ph->patchids = retvalu16;
+	ph->patchids = retvalu32;
 
 	gWordBits = (ph->quant_wbits & 0xf) + 2;
 }
diff --git a/indra/llmessage/patch_code.h b/indra/llmessage/patch_code.h
index 4c87c9808a..bdaabe70bd 100755
--- a/indra/llmessage/patch_code.h
+++ b/indra/llmessage/patch_code.h
@@ -40,7 +40,7 @@ void	end_patch_coding(LLBitPack &bitpack);
 
 void	init_patch_decoding(LLBitPack &bitpack);
 void	decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp);
-void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph);
+void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, bool b_large_patch = false);
 void	decode_patch(LLBitPack &bitpack, S32 *patches);
 
 #endif
diff --git a/indra/llmessage/patch_dct.h b/indra/llmessage/patch_dct.h
index 101231ec84..e1d219d9c9 100755
--- a/indra/llmessage/patch_dct.h
+++ b/indra/llmessage/patch_dct.h
@@ -73,7 +73,7 @@ public:
 	F32	dc_offset;		// 4 bytes
 	U16	range;			// 2 = 7 ((S16) FP range (breaks if we need > 32K meters in 1 patch)
 	U8	quant_wbits;	// 1 = 8 (upper 4 bits is quant - 2, lower 4 bits is word bits - 2)
-	U16	patchids;		// 2 = 10 (actually only uses 10 bits, 5 for each)
+	U32	patchids;
 };
 
 // Compression routines
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 7b0d8a6c40..028358c263 100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -494,7 +494,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
 		// Check if dimensions are a power of two!
 		if (!checkSize(width,height))
 		{
-			LL_ERRS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
+			LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
 		}
 		
 		if (mTexName)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 40236a52c4..ded47875ad 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1649,6 +1649,7 @@ set(viewer_APPSETTINGS_FILES
     app_settings/cmd_line.xml
     app_settings/commands.xml
     app_settings/grass.xml
+    app_settings/grids_default.xml
     app_settings/high_graphics.xml
     app_settings/ignorable_dialogs.xml
     app_settings/keys.xml
diff --git a/indra/newview/app_settings/grids_default.xml b/indra/newview/app_settings/grids_default.xml
new file mode 100644
index 0000000000..7120f69d85
--- /dev/null
+++ b/indra/newview/app_settings/grids_default.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="llsd.xsd">
+<map>
+  <key>YrGrid</key>
+  <map>
+    <key>keyname</key>
+    <string>YrGrid</string>
+    <key>label</key>
+    <string>YrGrid</string>
+    <key>grid_login_id</key>
+    <string>YrGrid</string>
+    <key>login_uri</key>
+      <array>
+        <string>http://login.yrgrid.com:8002/</string>
+      </array>
+    <key>update_query_url_base</key>
+    <string />
+    <key>helper_uri</key>
+    <string>http://grid.yrgrid.com/helpers/helper/</string>
+    <key>login_page</key>
+    <string>http://www.yrgrid.com/splash/</string>
+    <key>login_identifier_types</key>
+      <array>
+        <string>agent</string>
+        <string>account</string>
+      </array>
+    <key>slurl_base</key>
+    <string>secondlife://%s/secondlife/</string>
+    <key>app_slurl_base</key>
+    <string>secondlife:///app</string>
+  </map>
+</map>
+</llsd>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 85f6462a08..c343a30144 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2354,7 +2354,7 @@ void LLAgent::setStartPosition( U32 location_id )
     // this simulator.  Clamp it to the region the agent is
     // in, a little bit in on each side.
     const F32 INSET = 0.5f; //meters
-    const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters();
+    const F32 REGION_WIDTH = getRegion()->getWidth();
 
     LLVector3 agent_pos = getPositionAgent();
 
@@ -4095,7 +4095,7 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
 			(F32)(pos_global.mdV[VX] - region_origin.mdV[VX]),
 			(F32)(pos_global.mdV[VY] - region_origin.mdV[VY]),
 			(F32)(pos_global.mdV[VZ]));
-		teleportRequest(handle, pos_local);
+		teleportRequest(info->getHandle(), pos_local);
 	}
 	else if(regionp && 
 		teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
@@ -4142,6 +4142,11 @@ void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
 	}
 
 	U64 region_handle = to_region_handle(pos_global);
+	LLSimInfo* simInfo = LLWorldMap::instance().simInfoFromHandle(region_handle);
+	if (simInfo)
+	{
+		region_handle = simInfo->getHandle();
+	}
 	LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle));
 	teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt());
 }
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 5e3c8820c5..01214d53ef 100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -661,8 +661,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
 	}
 	
 	std::string sim_name = sim_info->getName();
-	F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
-	F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
+	U32 locX, locY;
+	from_region_handle(sim_info->getHandle(), &locX, &locY);
+	F32 region_x = pos_global.mdV[VX] - locX;
+	F32 region_y = pos_global.mdV[VY] - locY;
 	std::string full_name = llformat("%s (%d, %d, %d)", 
 									 sim_name.c_str(), 
 									 ll_round(region_x), 
@@ -702,10 +704,20 @@ void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos )
 	F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS );
 	F32 region_local_z = (F32)llclamp( pos.mdV[VZ], 0.0, (F64)REGION_HEIGHT_METERS );
 
-	// write in the values
-	childSetValue("teleport_coordinate_x", region_local_x );
-	childSetValue("teleport_coordinate_y", region_local_y );
-	childSetValue("teleport_coordinate_z", region_local_z );
+	LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos);
+	if (sim_info)
+	{
+		U32 locX, locY;
+		from_region_handle(sim_info->getHandle(), &locX, &locY);
+		region_local_x = pos.mdV[VX] - locX;
+		region_local_y = pos.mdV[VY] - locY;
+		region_local_z = (F32)pos.mdV[VZ];
+
+		// write in the values
+		childSetValue("teleport_coordinate_x", region_local_x );
+		childSetValue("teleport_coordinate_y", region_local_y );
+		childSetValue("teleport_coordinate_z", region_local_z );
+	}
 }
 
 void LLFloaterWorldMap::updateLocation()
@@ -740,7 +752,7 @@ void LLFloaterWorldMap::updateLocation()
 				
 				// Figure out where user is
 				// Set the current SLURL
-				mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal());
+				mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionAgent());
 			}
 		}
 		
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 27e6378c04..715217c257 100755
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -249,7 +249,7 @@ void LLWind::renderVectors()
 	S32 i,j;
 	F32 x,y;
 
-	F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
+	F32 region_width_meters = gAgent.getRegion()->getWidth();
 
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.pushMatrix();
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index ae4d5b31bc..fde619922e 100755
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -47,6 +47,7 @@
 #include "llviewercamera.h"
 #include "llviewerjoint.h"
 #include "llviewerobject.h"
+#include "llviewerregion.h"	// getRegion()
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llworld.h"		// for LLWorld::getInstance()
@@ -390,7 +391,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 		grid_rot.getAngleAxis(&angle_radians, &x, &y, &z);
 		gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
 
-		F32 region_size = LLWorld::getInstance()->getRegionWidthInMeters();
+		F32 region_size = object->getRegion()->getWidth();
 
 		const F32 LINE_ALPHA = 0.33f;
 
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 66e7892852..94862c2a54 100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -1303,7 +1303,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
 
 	guideline_end -= guideline_start;
 	guideline_end.normalize();
-	guideline_end *= LLWorld::getInstance()->getRegionWidthInMeters();
+	guideline_end *= gAgent.getRegion()->getWidth();
 	guideline_end += guideline_start;
 
 	{
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 870c17d9c7..0c0681d1d1 100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -129,7 +129,7 @@ void LLNetMap::setScale( F32 scale )
 		F32 height = (F32)(getRect().getHeight());
 		F32 diameter = sqrt(width * width + height * height);
 		F32 region_widths = diameter / mScale;
-		F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters();
+		F32 meters = region_widths * REGION_WIDTH_METERS;
 		F32 num_pixels = (F32)mObjectImagep->getWidth();
 		mObjectMapTPM = num_pixels / meters;
 		mObjectMapPixels = diameter;
@@ -222,7 +222,7 @@ void LLNetMap::draw()
 		}
 
 		// figure out where agent is
-		S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+		S32 region_width = REGION_WIDTH_UNITS;
 
 		LLWorld::region_list_t::const_iterator end_it = LLWorld::getInstance()->getRegionList().cend();
 		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
@@ -234,12 +234,13 @@ void LLNetMap::draw()
 			LLVector3 rel_region_pos = origin_agent - agentpos;
 			F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
 			F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+			const F32 real_width(regionp->getWidth());
 
 			// background region rectangle
 			F32 bottom =	relative_y;
 			F32 left =		relative_x;
-			F32 top =		bottom + mScale ;
-			F32 right =		left + mScale ;
+			F32 top =		bottom + (real_width / REGION_WIDTH_METERS) * mScale ;
+			F32 right =		left + (real_width / REGION_WIDTH_METERS) * mScale ;
 
 			if (regionp == curregionp)
 			{
@@ -482,7 +483,7 @@ void LLNetMap::draw()
 		}
 
 		// Draw frustum
-		F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();
+		F32 meters_to_pixels = mScale/ REGION_WIDTH_METERS;
 
 		F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
 		F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -568,6 +569,8 @@ LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos)
 	LLVector3 pos_local;
 	pos_local.setVec(relative_pos_global);  // convert to floats from doubles
 
+	mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
+
 	pos_local.mV[VX] *= mPixelsPerMeter;
 	pos_local.mV[VY] *= mPixelsPerMeter;
 	// leave Z component in meters
@@ -628,7 +631,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
 		pos_local.rotVec( rot );
 	}
 
-	pos_local *= ( LLWorld::getInstance()->getRegionWidthInMeters() / mScale );
+	pos_local *= ( REGION_WIDTH_METERS / mScale );
 	
 	LLVector3d pos_global;
 	pos_global.setVec( pos_local );
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 6e3e375488..a978c2e6fe 100755
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -76,7 +76,8 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
 		surface_order += 1;
 	}
 
-	if (power_of_two == (surface_width-1))
+	if (power_of_two != (surface_width-1))
+		surface_width = power_of_two + 1;
 	{
 		mSurfaceWidth = surface_width;
 
@@ -93,16 +94,11 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
 				power_of_two *= 2;
 				patch_order += 1;
 			}
-			if (power_of_two == patch_width)
-			{
-				mPatchWidth = patch_width;
-				mPatchOrder = patch_order;
-			}
-			else // patch_width is not a power of two...
-			{
-				mPatchWidth = 0;
-				mPatchOrder = 0;
-			}
+			if (power_of_two != patch_width)
+				patch_width = power_of_two;
+
+			mPatchWidth = patch_width;
+			mPatchOrder = patch_order;
 		}
 		else // patch_width is not a factor of (surface_width - 1)...
 		{
@@ -110,12 +106,6 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
 			mPatchOrder = 0;
 		}
 	}
-	else // surface_width is not a power of two...
-	{
-		mSurfaceWidth = 0;
-		mPatchWidth = 0;
-		mPatchOrder = 0;
-	}
 
 	// PART 2 -- Allocate memory for the render level table
 	if (mPatchWidth > 0) 
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index 728fc69723..08c50691ff 100755
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -280,11 +280,11 @@ LLSLURL::LLSLURL(const std::string& slurl)
 			  
 			  mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
 			  if((F32(mPosition[VX]) < 0.f) || 
-                             (mPosition[VX] > REGION_WIDTH_METERS) ||
+                             (mPosition[VX] > 8192.f) ||
 			     (F32(mPosition[VY]) < 0.f) || 
-                             (mPosition[VY] > REGION_WIDTH_METERS) ||
+                             (mPosition[VY] > 8192.f) ||
 			     (F32(mPosition[VZ]) < 0.f) || 
-                             (mPosition[VZ] > REGION_HEIGHT_METERS))
+                             (mPosition[VZ] > 8192.f))
 			    {
 			      mType = INVALID;
 			      return;
@@ -323,8 +323,8 @@ LLSLURL::LLSLURL(const std::string& grid,
 {
 	mGrid = grid;
 	mRegion = region;
-	S32 x = ll_round( (F32)fmod( position[VX], (F32)REGION_WIDTH_METERS ) );
-	S32 y = ll_round( (F32)fmod( position[VY], (F32)REGION_WIDTH_METERS ) );
+	S32 x = ll_round( (F32)position[VX] );
+	S32 y = ll_round( (F32)position[VY] );
 	S32 z = ll_round( (F32)position[VZ] );
 	mType = LOCATION;
 	mPosition = LLVector3(x, y, z);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 646fe2f886..c56733ca78 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -277,7 +277,7 @@ LLSD transform_cert_args(LLPointer<LLCertificate> cert);
 void general_cert_done(const LLSD& notification, const LLSD& response);
 void trust_cert_done(const LLSD& notification, const LLSD& response);
 void apply_udp_blacklist(const std::string& csv);
-bool process_login_success_response();
+bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y);
 void transition_back_to_login_panel(const std::string& emsg);
 
 void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group)
@@ -342,6 +342,9 @@ bool idle_startup()
 	static std::string auth_desc;
 	static std::string auth_message;
 
+	static U32 first_sim_size_x = 256;
+	static U32 first_sim_size_y = 256;
+
 	static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
 	static LLVector3 agent_start_position_region(10.f, 10.f, 10.f);		// default for when no space server
 
@@ -1213,7 +1216,7 @@ bool idle_startup()
 		}
 		else if(LLLoginInstance::getInstance()->authSuccess())
 		{
-			if(process_login_success_response())
+			if(process_login_success_response(first_sim_size_x, first_sim_size_y))
 			{
 				// Pass the user information to the voice chat server interface.
 				LLVoiceClient::getInstance()->userAuthorized(gUserCredential->userID(), gAgentID);
@@ -1311,6 +1314,7 @@ bool idle_startup()
 		gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
 		display_startup();
 
+		LLWorld::getInstance()->setRegionSize(first_sim_size_x, first_sim_size_y);
 		LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
 		display_startup();
 
@@ -3221,7 +3225,7 @@ void apply_udp_blacklist(const std::string& csv)
 	
 }
 
-bool process_login_success_response()
+bool process_login_success_response(U32& first_sim_size_x, U32& first_sim_size_y)
 {
 	LLSD response = LLLoginInstance::getInstance()->getResponse();
 
@@ -3340,7 +3344,13 @@ bool process_login_success_response()
 		U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
 		gFirstSimHandle = to_region_handle(region_x, region_y);
 	}
-	
+
+	text = response["region_size_x"].asString();
+	if (!text.empty()) LLViewerParcelMgr::getInstance()->init(first_sim_size_x = atoi(text.c_str()));
+	//region Y size is currently unused, major refactoring required. - Patrick Sapinski (2/10/2011)
+	text = response["region_size_y"].asString();
+	if (!text.empty()) first_sim_size_y = atoi(text.c_str());
+
 	const std::string look_at_str = response["look_at"];
 	if (!look_at_str.empty())
 	{
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 503dd6747d..b61cd6c840 100755
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -169,6 +169,7 @@ void LLSurface::create(const S32 grids_per_edge,
 	mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge;
 	mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1));
 	mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1);
+	sTextureSize = width;
 
 	mOriginGlobal.setVec(origin_global);
 
@@ -293,7 +294,7 @@ void LLSurface::initTextures()
 		mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
 		gPipeline.createObject(mWaterObjp);
 		LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
-		water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);		// region doesn't have a valid water height yet
+		water_pos_global += LLVector3d(mRegionp->getWidth()/2, mRegionp->getWidth()/2, DEFAULT_WATER_HEIGHT);
 		mWaterObjp->setPositionGlobal(water_pos_global);
 	}
 }
@@ -323,8 +324,8 @@ void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
 	// Hack!
 	if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull())
 	{
-		const F64 x = origin_global.mdV[VX] + 128.0;
-		const F64 y = origin_global.mdV[VY] + 128.0;
+		const F64 x = origin_global.mdV[VX] + (F64)mRegionp->getWidth() / 2;
+		const F64 y = origin_global.mdV[VY] + (F64)mRegionp->getWidth() / 2;
 		const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ];
 
 		LLVector3d water_origin_global(x, y, z);
@@ -362,15 +363,48 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 {
 	S32 i;
 	LLSurfacePatch *patchp, *neighbor_patchp;
+	S32 neighborPatchesPerEdge = neighborp->mPatchesPerEdge;
 
 	mNeighbors[direction] = neighborp;
 	neighborp->mNeighbors[gDirOpposite[direction]] = this;
 
+	S32 ppe[2];
+	S32 own_offset[2] = {0, 0};
+	S32 neighbor_offset[2] = {0, 0};
+	U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos;
+
+	ppe[0] = (mPatchesPerEdge < neighborPatchesPerEdge) ? mPatchesPerEdge : neighborPatchesPerEdge; // used for x
+	ppe[1] = ppe[0]; // used for y
+
+	from_region_handle(mRegionp->getHandle(), &own_xpos, &own_ypos);
+	from_region_handle(neighborp->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos);
+
+	if(own_ypos >= neighbor_ypos)
+	{
+		neighbor_offset[1] = (own_ypos - neighbor_ypos) / mGridsPerPatchEdge;
+		ppe[1] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[1]);
+	}
+	else
+	{
+		own_offset[1] = (neighbor_ypos - own_ypos) / mGridsPerPatchEdge;
+		ppe[1] = llmin(mPatchesPerEdge-own_offset[1], neighborPatchesPerEdge);
+	}
+
+	if(own_xpos >= neighbor_xpos)
+	{
+		neighbor_offset[0] = (own_xpos - neighbor_xpos) / mGridsPerPatchEdge;
+		ppe[0] = llmin(mPatchesPerEdge, neighborPatchesPerEdge-neighbor_offset[0]);
+	}
+	else
+	{
+		own_offset[0] = (neighbor_xpos - own_xpos) / mGridsPerPatchEdge;
+		ppe[0] = llmin(mPatchesPerEdge-own_offset[0], neighborPatchesPerEdge);
+	}
 	// Connect patches
 	if (NORTHEAST == direction)
 	{
 		patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
-		neighbor_patchp = neighborp->getPatch(0, 0);
+		neighbor_patchp = neighborp->getPatch(neighbor_offset[0], neighbor_offset[1]);
 
 		patchp->connectNeighbor(neighbor_patchp, direction);
 		neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -380,8 +414,14 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	}
 	else if (NORTHWEST == direction)
 	{
+		S32 off = mPatchesPerEdge + neighbor_offset[1] - own_offset[1];
 		patchp = getPatch(0, mPatchesPerEdge - 1);
-		neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0);
+		neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, off); //neighborPatchesPerEdge - 1
+		if (!neighbor_patchp)
+		{
+			mNeighbors[direction] = NULL;
+			return;
+		}
 
 		patchp->connectNeighbor(neighbor_patchp, direction);
 		neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -389,18 +429,29 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	else if (SOUTHWEST == direction)
 	{
 		patchp = getPatch(0, 0);
-		neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
+		neighbor_patchp = neighborp->getPatch(neighbor_offset[0] - 1, neighbor_offset[1] - 1);
+		if (!neighbor_patchp)
+		{
+			mNeighbors[direction] = NULL;
+			return;
+		}
 
 		patchp->connectNeighbor(neighbor_patchp, direction);
 		neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
 
-		neighbor_patchp->updateNorthEdge(); // Only update one of north or east.
+		neighbor_patchp->updateEastEdge(); // Only update one of north or east.
 		neighbor_patchp->dirtyZ();
 	}
 	else if (SOUTHEAST == direction)
 	{
+		S32 off = mPatchesPerEdge + neighbor_offset[0] - own_offset[0];
 		patchp = getPatch(mPatchesPerEdge - 1, 0);
-		neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1);
+		neighbor_patchp = neighborp->getPatch(off, neighbor_offset[1] - 1); //0
+		if (!neighbor_patchp)
+		{
+			mNeighbors[direction] = NULL;
+			return;
+		}
 
 		patchp->connectNeighbor(neighbor_patchp, direction);
 		neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -408,10 +459,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	else if (EAST == direction)
 	{
 		// Do east/west connections, first
-		for (i = 0; i < (S32)mPatchesPerEdge; i++)
+		for (i = 0; i < ppe[1]; i++)
 		{
-			patchp = getPatch(mPatchesPerEdge - 1, i);
-			neighbor_patchp = neighborp->getPatch(0, i);
+			patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(0, i + neighbor_offset[1]);
 
 			patchp->connectNeighbor(neighbor_patchp, direction);
 			neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -421,19 +472,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 		}
 
 		// Now do northeast/southwest connections
-		for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
+		for (i = 0; i < ppe[1] - 1; i++)
 		{
-			patchp = getPatch(mPatchesPerEdge - 1, i);
-			neighbor_patchp = neighborp->getPatch(0, i+1);
+			patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(0, i+1 + neighbor_offset[1]);
 
 			patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
 			neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
 		}
 		// Now do southeast/northwest connections
-		for (i = 1; i < (S32)mPatchesPerEdge; i++)
+		for (i = 1; i < ppe[1]; i++)
 		{
-			patchp = getPatch(mPatchesPerEdge - 1, i);
-			neighbor_patchp = neighborp->getPatch(0, i-1);
+			patchp = getPatch(mPatchesPerEdge - 1, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(0, i-1 + neighbor_offset[1]);
 
 			patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
 			neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
@@ -442,10 +493,10 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	else if (NORTH == direction)
 	{
 		// Do north/south connections, first
-		for (i = 0; i < (S32)mPatchesPerEdge; i++)
+		for (i = 0; i < ppe[0]; i++)
 		{
-			patchp = getPatch(i, mPatchesPerEdge - 1);
-			neighbor_patchp = neighborp->getPatch(i, 0);
+			patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
+			neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], 0);
 
 			patchp->connectNeighbor(neighbor_patchp, direction);
 			neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -455,19 +506,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 		}
 
 		// Do northeast/southwest connections
-		for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
+		for (i = 0; i < ppe[0] - 1; i++)
 		{
-			patchp = getPatch(i, mPatchesPerEdge - 1);
-			neighbor_patchp = neighborp->getPatch(i+1, 0);
+			patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
+			neighbor_patchp = neighborp->getPatch(i+1 + neighbor_offset[0], 0);
 
 			patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
 			neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
 		}
 		// Do southeast/northwest connections
-		for (i = 1; i < (S32)mPatchesPerEdge; i++)
+		for (i = 1; i < ppe[0]; i++)
 		{
-			patchp = getPatch(i, mPatchesPerEdge - 1);
-			neighbor_patchp = neighborp->getPatch(i-1, 0);
+			patchp = getPatch(i + own_offset[0], mPatchesPerEdge - 1);
+			neighbor_patchp = neighborp->getPatch(i-1 + neighbor_offset[0], 0);
 
 			patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
 			neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
@@ -476,10 +527,11 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	else if (WEST == direction)
 	{
 		// Do east/west connections, first
-		for (i = 0; i < mPatchesPerEdge; i++)
+		for (i = 0; i < ppe[1]; i++)
 		{
-			patchp = getPatch(0, i);
-			neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i);
+			patchp = getPatch(0, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + neighbor_offset[1]);
+			if (!neighbor_patchp) continue;
 
 			patchp->connectNeighbor(neighbor_patchp, direction);
 			neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -489,20 +541,22 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 		}
 
 		// Now do northeast/southwest connections
-		for (i = 1; i < mPatchesPerEdge; i++)
+		for (i = 1; i < ppe[1]; i++)
 		{
-			patchp = getPatch(0, i);
-			neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1);
+			patchp = getPatch(0, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i - 1 + neighbor_offset[1]);
+			if (!neighbor_patchp) continue;
 
 			patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
 			neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
 		}
 
 		// Now do northwest/southeast connections
-		for (i = 0; i < mPatchesPerEdge - 1; i++)
+		for (i = 0; i < ppe[1] - 1; i++)
 		{
-			patchp = getPatch(0, i);
-			neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1);
+			patchp = getPatch(0, i + own_offset[1]);
+			neighbor_patchp = neighborp->getPatch(neighborPatchesPerEdge - 1, i + 1 + neighbor_offset[1]);
+			if (!neighbor_patchp) continue;
 
 			patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
 			neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
@@ -511,10 +565,11 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 	else if (SOUTH == direction)
 	{
 		// Do north/south connections, first
-		for (i = 0; i < mPatchesPerEdge; i++)
+		for (i = 0; i < ppe[0]; i++)
 		{
-			patchp = getPatch(i, 0);
-			neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1);
+			patchp = getPatch(i + own_offset[0], 0);
+			neighbor_patchp = neighborp->getPatch(i + neighbor_offset[0], neighborPatchesPerEdge - 1);
+			if (!neighbor_patchp) continue;
 
 			patchp->connectNeighbor(neighbor_patchp, direction);
 			neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
@@ -524,19 +579,19 @@ void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
 		}
 
 		// Now do northeast/southwest connections
-		for (i = 1; i < mPatchesPerEdge; i++)
+		for (i = 1; i < ppe[0]; i++)
 		{
-			patchp = getPatch(i, 0);
-			neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1);
+			patchp = getPatch(i + own_offset[0], 0);
+			neighbor_patchp = neighborp->getPatch(i - 1 + neighbor_offset[0], neighborPatchesPerEdge - 1);
 
 			patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
 			neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
 		}
 		// Now do northeast/southwest connections
-		for (i = 0; i < mPatchesPerEdge - 1; i++)
+		for (i = 0; i < ppe[0] - 1; i++)
 		{
-			patchp = getPatch(i, 0);
-			neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1);
+			patchp = getPatch(i + own_offset[0], 0);
+			neighbor_patchp = neighborp->getPatch(i + 1 + neighbor_offset[0], neighborPatchesPerEdge - 1);
 
 			patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
 			neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
@@ -698,14 +753,22 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL
 
 	while (1)
 	{
-		decode_patch_header(bitpack, &ph);
+		decode_patch_header(bitpack, &ph, b_large_patch);
 		if (ph.quant_wbits == END_OF_PATCHES)
 		{
 			break;
 		}
 
-		i = ph.patchids >> 5;
-		j = ph.patchids & 0x1F;
+		if (b_large_patch)
+		{
+			i = ph.patchids >> 16; //x
+			j = ph.patchids & 0xFFFF; //y
+		}
+		else
+		{
+			i = ph.patchids >> 5; //x
+			j = ph.patchids & 0x1F; //y
+		}
 
 		if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge))
 		{
@@ -1150,12 +1213,12 @@ LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const
 {
 	if ((x < 0) || (x >= mPatchesPerEdge))
 	{
-		LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
+		LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL;
 		return NULL;
 	}
 	if ((y < 0) || (y >= mPatchesPerEdge))
 	{
-		LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
+		LL_WARNS() << "Asking for patch out of bounds" << LL_ENDL;
 		return NULL;
 	}
 
@@ -1227,7 +1290,7 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
 	LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
 	U8 *rawp = raw->getData();
 
-	F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width;
+	F32 scale = getRegion()->getWidth() * getMetersPerGrid() / (F32)tex_width;
 	F32 scale_inv = 1.f / scale;
 
 	S32 x_begin, y_begin, x_end, y_end;
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 897b0409c2..3064203c34 100755
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -28,6 +28,7 @@
 
 #include "llsurfacepatch.h"
 #include "llpatchvertexarray.h"
+#include "llregionhandle.h"
 #include "llviewerobjectlist.h"
 #include "llvosurfacepatch.h"
 #include "llsurface.h"
@@ -248,18 +249,22 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 
 	const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
 
-	S32 poffsets[2][2][2];
+	S32 poffsets[2][2][3];
 	poffsets[0][0][0] = x - stride;
 	poffsets[0][0][1] = y - stride;
+	poffsets[0][0][2] = surface_stride;
 
 	poffsets[0][1][0] = x - stride;
 	poffsets[0][1][1] = y + stride;
+	poffsets[0][1][2] = surface_stride;
 
 	poffsets[1][0][0] = x + stride;
 	poffsets[1][0][1] = y - stride;
+	poffsets[1][0][2] = surface_stride;
 
 	poffsets[1][1][0] = x + stride;
 	poffsets[1][1][1] = y + stride;
+	poffsets[1][1][2] = surface_stride;
 
 	const LLSurfacePatch *ppatches[2][2];
 
@@ -283,8 +288,9 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 				}
 				else
 				{
-					poffsets[i][j][0] += patch_width;
 					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
+					poffsets[i][j][0] += patch_width;
+					poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
 				}
 			}
 			if (poffsets[i][j][1] < 0)
@@ -295,8 +301,9 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 				}
 				else
 				{
-					poffsets[i][j][1] += patch_width;
 					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
+					poffsets[i][j][1] += patch_width;
+					poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
 				}
 			}
 			if (poffsets[i][j][0] >= (S32)patch_width)
@@ -307,8 +314,9 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 				}
 				else
 				{
-					poffsets[i][j][0] -= patch_width;
 					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
+					poffsets[i][j][0] -= patch_width;
+					poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
 				}
 			}
 			if (poffsets[i][j][1] >= (S32)patch_width)
@@ -319,8 +327,9 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 				}
 				else
 				{
-					poffsets[i][j][1] -= patch_width;
 					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
+					poffsets[i][j][1] -= patch_width;
+					poffsets[i][j][2] = ppatches[i][j]->getSurface()->getGridsPerEdge();
 				}
 			}
 		}
@@ -329,19 +338,19 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
 	LLVector3 p00(-mpg,-mpg,
 				  *(ppatches[0][0]->mDataZ
 				  + poffsets[0][0][0]
-				  + poffsets[0][0][1]*surface_stride));
+				  + poffsets[0][0][1]*poffsets[0][0][2]));
 	LLVector3 p01(-mpg,+mpg,
 				  *(ppatches[0][1]->mDataZ
 				  + poffsets[0][1][0]
-				  + poffsets[0][1][1]*surface_stride));
+				  + poffsets[0][1][1]*poffsets[0][1][2]));
 	LLVector3 p10(+mpg,-mpg,
 				  *(ppatches[1][0]->mDataZ
 				  + poffsets[1][0][0]
-				  + poffsets[1][0][1]*surface_stride));
+				  + poffsets[1][0][1]*poffsets[1][0][2]));
 	LLVector3 p11(+mpg,+mpg,
 				  *(ppatches[1][1]->mDataZ
 				  + poffsets[1][1][0]
-				  + poffsets[1][1][1]*surface_stride));
+				  + poffsets[1][1][1]*poffsets[1][1][2]));
 
 	LLVector3 c1 = p11 - p00;
 	LLVector3 c2 = p01 - p10;
@@ -492,6 +501,11 @@ void LLSurfacePatch::updateNormals()
 	// update the west edge
 	if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST])
 	{
+		if (!getNeighborPatch(NORTH) && getNeighborPatch(NORTHWEST) && getNeighborPatch(NORTHWEST)->getHasReceivedData())
+		{
+			*(mDataZ + grids_per_patch_edge*grids_per_edge) = *(getNeighborPatch(NORTHWEST)->mDataZ + grids_per_patch_edge);
+		}
+
 		for (j = 0; j < grids_per_patch_edge; j++)
 		{
 			calcNormal(0, j, 2);
@@ -503,6 +517,11 @@ void LLSurfacePatch::updateNormals()
 	// update the south edge
 	if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST])
 	{
+		if (!getNeighborPatch(EAST) && getNeighborPatch(SOUTHEAST) && getNeighborPatch(SOUTHEAST)->getHasReceivedData())
+		{
+			*(mDataZ + grids_per_patch_edge) = *(getNeighborPatch(SOUTHEAST)->mDataZ + grids_per_patch_edge * getNeighborPatch(SOUTHEAST)->getSurface()->getGridsPerEdge());
+		}
+
 		for (i = 0; i < grids_per_patch_edge; i++)
 		{
 			calcNormal(i, 0, 2);
@@ -531,7 +550,8 @@ void LLSurfacePatch::updateNormals()
 					{
 						// East, but not north.  Pull from your east neighbor's northwest point.
 						*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
-							*(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge);
+							*(getNeighborPatch(EAST)->mDataZ + (getNeighborPatch(EAST)->getSurface()->getGridsPerPatchEdge() - 1)
+							*getNeighborPatch(EAST)->getSurface()->getGridsPerEdge());
 					}
 					else
 					{
@@ -556,7 +576,7 @@ void LLSurfacePatch::updateNormals()
 					{
 						// North, but not east.  Pull from your north neighbor's southeast corner.
 						*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
-							*(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1));
+							*(getNeighborPatch(NORTH)->mDataZ + (getNeighborPatch(NORTH)->getSurface()->getGridsPerPatchEdge() - 1));
 					}
 					else
 					{
@@ -573,8 +593,17 @@ void LLSurfacePatch::updateNormals()
 				&&
 				(!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep)))
 			{
+				U32 own_xpos, own_ypos, neighbor_xpos, neighbor_ypos;
+				S32 own_offset = 0, neighbor_offset = 0;
+				from_region_handle(mSurfacep->getRegion()->getHandle(), &own_xpos, &own_ypos);
+				from_region_handle(getNeighborPatch(NORTHEAST)->mSurfacep->getRegion()->getHandle(), &neighbor_xpos, &neighbor_ypos);
+				if (own_ypos >= neighbor_ypos)
+					neighbor_offset = own_ypos - neighbor_ypos;
+				else
+					own_offset = neighbor_ypos - own_ypos;
+
 				*(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
-										*(getNeighborPatch(NORTHEAST)->mDataZ);
+					*(getNeighborPatch(NORTHEAST)->mDataZ + (grids_per_edge + neighbor_offset - own_offset - 1) * getNeighborPatch(NORTHEAST)->getSurface()->getGridsPerEdge());
 			}
 		}
 		else
@@ -618,7 +647,9 @@ void LLSurfacePatch::updateEastEdge()
 	U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
 	U32 grids_per_edge = mSurfacep->getGridsPerEdge();
 
-	U32 j, k;
+	U32 grids_per_edge_east = grids_per_edge;
+
+	U32 j, k, h;
 	F32 *west_surface, *east_surface;
 
 	if (!getNeighborPatch(EAST))
@@ -630,6 +661,7 @@ void LLSurfacePatch::updateEastEdge()
 	{
 		west_surface = mDataZ + grids_per_patch_edge;
 		east_surface = getNeighborPatch(EAST)->mDataZ;
+		grids_per_edge_east = getNeighborPatch(EAST)->getSurface()->getGridsPerEdge();
 	}
 	else
 	{
@@ -641,7 +673,8 @@ void LLSurfacePatch::updateEastEdge()
 	for (j=0; j < grids_per_patch_edge; j++)
 	{
 		k = j * grids_per_edge;
-		*(west_surface + k) = *(east_surface + k);	// update buffer Z
+		h = j * grids_per_edge_east;
+		*(west_surface + k) = *(east_surface + h);	// update buffer Z
 	}
 }
 
@@ -816,6 +849,7 @@ void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
 void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction)
 {
 	llassert(neighbor_patchp);
+	if (!neighbor_patchp) return;
 	mNormalsInvalid[direction] = TRUE;
 	neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 1acd2647ac..d75e9a4c39 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4160,6 +4160,14 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 
 	// Viewer trusts the simulator.
 	gMessageSystem->enableCircuit(sim_host, TRUE);
+	/*if (!gHippoGridManager->getConnectedGrid()->isSecondLife())
+	{
+		U32 region_size_x = 256;
+		msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeX, region_size_x);
+		U32 region_size_y = 256;
+		msg->getU32Fast(_PREHASH_Info, _PREHASH_RegionSizeY, region_size_y);
+		LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y);
+	}*/
 	LLViewerRegion* regionp =  LLWorld::getInstance()->addRegion(region_handle, sim_host);
 
 /*
@@ -4439,6 +4447,14 @@ void process_crossed_region(LLMessageSystem* msg, void**)
 
 	send_complete_agent_movement(sim_host);
 
+	/*if (!gHippoGridManager->getConnectedGrid()->isSecondLife())
+	{
+		U32 region_size_x = 256;
+		msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeX, region_size_x);
+		U32 region_size_y = 256;
+		msg->getU32(_PREHASH_RegionData, _PREHASH_RegionSizeY, region_size_y);
+		LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y);
+	}*/
 	LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
 
 	LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from process_crossed_region(). Seed cap == "
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1305f7984f..b104344325 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -1130,7 +1130,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 	U16 valswizzle[4];
 #endif
 	U16	*val;
-	const F32 size = LLWorld::getInstance()->getRegionWidthInMeters();	
+	const F32 size = mRegionp->getWidth();
 	const F32 MAX_HEIGHT = LLWorld::getInstance()->getRegionMaxHeight();
 	const F32 MIN_HEIGHT = LLWorld::getInstance()->getRegionMinHeight();
 	S32 length;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index cbf346b291..73e2262242 100755
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -133,7 +133,7 @@ LLViewerParcelMgr::LLViewerParcelMgr()
 	mHoverParcel = new LLParcel();
 	mCollisionParcel = new LLParcel();
 
-	mParcelsPerEdge = S32(	REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
+	mParcelsPerEdge = S32(8192.f / PARCEL_GRID_STEP_METERS); // 8192 is the maximum region size on Aurora
 	mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
 	resetSegments(mHighlightSegments);
 
@@ -156,9 +156,14 @@ LLViewerParcelMgr::LLViewerParcelMgr()
 		mAgentParcelOverlay[i] = 0;
 	}
 
+	mParcelsPerEdge = S32(REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS);
 	mTeleportInProgress = TRUE; // the initial parcel update is treated like teleport
 }
 
+void LLViewerParcelMgr::init(F32 region_size)
+{
+	mParcelsPerEdge = S32(region_size / PARCEL_GRID_STEP_METERS);
+}
 
 LLViewerParcelMgr::~LLViewerParcelMgr()
 {
@@ -438,9 +443,9 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle()
 void LLViewerParcelMgr::selectCollisionParcel()
 {
 	// BUG: Claim to be in the agent's region
-	mWestSouth = gAgent.getRegion()->getOriginGlobal();
+	mWestSouth = getSelectionRegion()->getOriginGlobal();
 	mEastNorth = mWestSouth;
-	mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0);
+	mEastNorth += LLVector3d(getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, getSelectionRegion()->getWidth()/REGION_WIDTH_METERS * PARCEL_GRID_STEP_METERS, 0.0);
 
 	// BUG: must be in the sim you are in
 	LLMessageSystem *msg = gMessageSystem;
@@ -1393,8 +1398,7 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
 		return;
 	}
 
-	S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge;
-	S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
+	S32 expected_size = 1024;
 	if (packed_overlay_size != expected_size)
 	{
 		LL_WARNS() << "Got parcel overlay size " << packed_overlay_size
@@ -1457,6 +1461,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 	S32		other_clean_time = 0;
 
 	LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
+	LLViewerRegion* msg_region = LLWorld::getInstance()->getRegion(msg->getSender());
+	if(msg_region)
+		parcel_mgr.mParcelsPerEdge = S32(msg_region->getWidth() / PARCEL_GRID_STEP_METERS);
+	else
+		parcel_mgr.mParcelsPerEdge = S32(gAgent.getRegion()->getWidth() / PARCEL_GRID_STEP_METERS);
 
 	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
 	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index bb6bbf3308..b8ff1b02c7 100755
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -85,6 +85,7 @@ public:
 	LLViewerParcelMgr();
 	~LLViewerParcelMgr();
 
+	void init(F32 region_size);
 	static void cleanupGlobals();
 
 	BOOL	selectionEmpty() const;
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 52e7596d9f..7a35df839b 100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -55,6 +55,7 @@ const U8  OVERLAY_IMG_COMPONENTS = 4;
 LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters)
 :	mRegion( region ),
 	mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ),
+	mRegionSize(S32(region_width_meters)),
 	mDirty( FALSE ),
 	mTimeSinceLastUpdate(),
 	mOverlayTextureIdx(-1),
@@ -409,7 +410,8 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay)
 {
 	// Unpack the message data into the ownership array
 	S32	size	= mParcelGridsPerEdge * mParcelGridsPerEdge;
-	S32 chunk_size = size / PARCEL_OVERLAY_CHUNKS;
+	S32 mParcelOverLayChunks = mRegionSize * mRegionSize / (128 * 128);
+	S32 chunk_size = size / mParcelOverLayChunks;
 
 	memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size);		/*Flawfinder: ignore*/
 
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 14a2af5354..0fd3efe73b 100755
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -102,6 +102,7 @@ private:
 	LLViewerRegion*	mRegion;
 
 	S32				mParcelGridsPerEdge;
+	S32				mRegionSize;
 
 	LLPointer<LLViewerTexture> mTexture;
 	LLPointer<LLImageRaw> mImageRaw;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 4652c1bd9b..4f5fa9025d 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -65,6 +65,7 @@
 #include "lltrans.h"
 #include "llurldispatcher.h"
 #include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
 #include "llviewerparceloverlay.h"
 #include "llviewerstatsrecorder.h"
 #include "llvlmanager.h"
@@ -432,9 +433,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mDead(FALSE),
 	mLastVisitedEntry(NULL),
 	mInvisibilityCheckHistory(-1),
-	mPaused(FALSE)
+	mPaused(FALSE),
+	mWidth(region_width_meters)
 {
-	mWidth = region_width_meters;
 	mImpl->mOriginGlobal = from_region_handle(handle); 
 	updateRenderMatrix();
 
@@ -444,7 +445,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mImpl->mCompositionp =
 		new LLVLComposition(mImpl->mLandp,
 							grids_per_region_edge,
-							region_width_meters / grids_per_region_edge);
+							mWidth / grids_per_region_edge);
 	mImpl->mCompositionp->setSurface(mImpl->mLandp);
 
 	// Create the surfaces
@@ -454,7 +455,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 					mImpl->mOriginGlobal,
 					mWidth);
 
-	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
+	mParcelOverlay = new LLViewerParcelOverlay(this, mWidth);
+	LLViewerParcelMgr::getInstance()->init(mWidth);
 
 	setOriginGlobal(from_region_handle(handle));
 	calculateCenterGlobal();
@@ -1632,11 +1634,11 @@ LLVLComposition * LLViewerRegion::getComposition() const
 
 F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 {
-	if (x >= 256)
+	if (x >= mWidth)
 	{
-		if (y >= 256)
+		if (y >= mWidth)
 		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
+			LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, mWidth, 0.f);
 			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
 			if (regionp)
 			{
@@ -1645,8 +1647,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 				// If we're attempting to blend, then we want to make the fractional part of
 				// this region match the fractional of the adjacent.  For now, just minimize
 				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255, 255);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
+				F32 our_comp = getComposition()->getValueScaled(mWidth-1.f, mWidth-1.f);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - regionp->getWidth(), y - regionp->getWidth());
 				while (llabs(our_comp - adj_comp) >= 1.f)
 				{
 					if (our_comp > adj_comp)
@@ -1663,7 +1665,7 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 		}
 		else
 		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
+			LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, 0.f, 0.f);
 			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
 			if (regionp)
 			{
@@ -1672,8 +1674,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 				// If we're attempting to blend, then we want to make the fractional part of
 				// this region match the fractional of the adjacent.  For now, just minimize
 				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
+				F32 our_comp = getComposition()->getValueScaled(mWidth-1.f, (F32)y);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - regionp->getWidth(), (F32)y);
 				while (llabs(our_comp - adj_comp) >= 1.f)
 				{
 					if (our_comp > adj_comp)
@@ -1689,9 +1691,9 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 			}
 		}
 	}
-	else if (y >= 256)
+	else if (y >= mWidth)
 	{
-		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
+		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, mWidth, 0.f);
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
 		if (regionp)
 		{
@@ -1700,8 +1702,8 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
 			// If we're attempting to blend, then we want to make the fractional part of
 			// this region match the fractional of the adjacent.  For now, just minimize
 			// the delta.
-			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
-			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
+			F32 our_comp = getComposition()->getValueScaled((F32)x, mWidth-1.f);
+			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - regionp->getWidth());
 			while (llabs(our_comp - adj_comp) >= 1.f)
 			{
 				if (our_comp > adj_comp)
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index c4430f4308..5db17bf151 100755
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -154,7 +154,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
 	const F32 xyScaleInv = (1.f / xyScale);
 	const F32 zScaleInv = (1.f / zScale);
 
-	const F32 inv_width = 1.f/mWidth;
+	const F32 inv_width = 1.f / (F32)mWidth;
 
 	// OK, for now, just have the composition value equal the height at the point.
 	for (S32 j = y_begin; j < y_end; j++)
diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp
index 895ceed880..8a9d34a5e9 100755
--- a/indra/newview/llvlmanager.cpp
+++ b/indra/newview/llvlmanager.cpp
@@ -37,9 +37,15 @@
 #include "llbitpack.h"
 
 const	char	LAND_LAYER_CODE					= 'L';
+const	char	WATER_LAYER_CODE				= 'W';
 const	char	WIND_LAYER_CODE					= '7';
 const	char	CLOUD_LAYER_CODE				= '8';
 
+const	char	AURORA_LAND_LAYER_CODE			= 'M';
+const	char	AURORA_WATER_LAYER_CODE			= 'X';
+const	char	AURORA_WIND_LAYER_CODE			= '9';
+const	char	AURORA_CLOUD_LAYER_CODE			= ':';
+
 LLVLManager gVLManager;
 
 LLVLManager::~LLVLManager()
@@ -54,15 +60,19 @@ LLVLManager::~LLVLManager()
 
 void LLVLManager::addLayerData(LLVLData *vl_datap, const S32Bytes mesg_size)
 {
-	if (LAND_LAYER_CODE == vl_datap->mType)
+	if (LAND_LAYER_CODE == vl_datap->mType || AURORA_LAND_LAYER_CODE == vl_datap->mType)
 	{
 		mLandBits += mesg_size;
 	}
-	else if (WIND_LAYER_CODE == vl_datap->mType)
+	else if (WATER_LAYER_CODE == vl_datap->mType || AURORA_WATER_LAYER_CODE == vl_datap->mType)
+	{
+		mWaterBits += mesg_size;
+	}
+	else if (WIND_LAYER_CODE == vl_datap->mType || AURORA_WIND_LAYER_CODE == vl_datap->mType)
 	{
 		mWindBits += mesg_size;
 	}
-	else if (CLOUD_LAYER_CODE == vl_datap->mType)
+	else if (CLOUD_LAYER_CODE == vl_datap->mType || AURORA_CLOUD_LAYER_CODE == vl_datap->mType)
 	{
 		mCloudBits += mesg_size;
 	}
@@ -130,6 +140,11 @@ U32Bits LLVLManager::getCloudBits() const
 	return mCloudBits;
 }
 
+U32Bits LLVLManager::getWaterBits() const
+{
+	return mWaterBits;
+}
+
 S32Bytes LLVLManager::getTotalBytes() const
 {
 	return mLandBits + mWindBits + mCloudBits;
diff --git a/indra/newview/llvlmanager.h b/indra/newview/llvlmanager.h
index 5e7fadc522..338befc1c9 100755
--- a/indra/newview/llvlmanager.h
+++ b/indra/newview/llvlmanager.h
@@ -48,6 +48,7 @@ public:
 	U32Bits getLandBits() const;
 	U32Bits getWindBits() const;
 	U32Bits getCloudBits() const;
+	U32Bits getWaterBits() const;
 
 	void resetBitCounts();
 
@@ -58,6 +59,7 @@ protected:
 	U32Bits mLandBits;
 	U32Bits mWindBits;
 	U32Bits mCloudBits;
+	U32Bits mWaterBits;
 };
 
 class LLVLData
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 9ce16a1674..bec8d945bd 100755
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -58,7 +58,7 @@ LLVOWater::LLVOWater(const LLUUID &id,
 {
 	// Terrain must draw during selection passes so it can block objects behind it.
 	mbCanSelect = FALSE;
-	setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility.
+	setScale(LLVector3(mRegionp->getWidth(), mRegionp->getWidth(), 0.f)); // Hack for setting scale for bounding boxes/visibility.
 
 	mUseTexture = TRUE;
 	mIsEdgePatch = FALSE;
diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp
index 4c39fb5b74..77e3df711a 100755
--- a/indra/newview/llwind.cpp
+++ b/indra/newview/llwind.cpp
@@ -43,7 +43,9 @@
 // viewer
 #include "noise.h"
 #include "v4color.h"
+#include "llagent.h"	// for gAgent
 #include "llworld.h"
+#include "llviewerregion.h"	// for getRegion()
 
 
 //////////////////////////////////////////////////////////////////////
@@ -210,7 +212,7 @@ LLVector3 LLWind::getVelocity(const LLVector3 &pos_region)
 
 	LLVector3 pos_clamped_region(pos_region);
 	
-	F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
+	F32 region_width_meters = gAgent.getRegion()->getWidth();
 
 	if (pos_clamped_region.mV[VX] < 0.f)
 	{
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index b688dd47a8..d10472e72d 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -74,12 +74,13 @@ const S32 WORLD_PATCH_SIZE = 16;
 
 extern LLColor4U MAX_WATER_COLOR;
 
-const U32 LLWorld::mWidth = 256;
+U32 LLWorld::mWidth = 256;
+U32 LLWorld::mLength = 256;
 
 // meters/point, therefore mWidth * mScale = meters per edge
 const F32 LLWorld::mScale = 1.f;
 
-const F32 LLWorld::mWidthInMeters = mWidth * mScale;
+F32 LLWorld::mWidthInMeters = mWidth * mScale;
 
 //
 // Functions
@@ -137,6 +138,12 @@ void LLWorld::destroyClass()
 	LLSceneMonitor::deleteSingleton();
 }
 
+void LLWorld::setRegionSize(const U32& width, const U32& length)
+{
+	mWidth = width ? width : 256; // Width of 0 is really 256
+	mLength = length ? length : 256; // Length of 0 is really 256
+	mWidthInMeters = mWidth * mScale;
+}
 
 LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 {
@@ -180,8 +187,8 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 	U32 iindex = 0;
 	U32 jindex = 0;
 	from_region_handle(region_handle, &iindex, &jindex);
-	S32 x = (S32)(iindex/mWidth);
-	S32 y = (S32)(jindex/mWidth);
+	S32 x = (S32)(iindex/256);
+	S32 y = (S32)(jindex/256);
 	LL_INFOS() << "Adding new region (" << x << ":" << y << ")" 
 		<< " on host: " << host << LL_ENDL;
 
@@ -229,13 +236,43 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 	{
 		adj_x = region_x + width * gDirAxes[dir][0];
 		adj_y = region_y + width * gDirAxes[dir][1];
-		to_region_handle(adj_x, adj_y, &adj_handle);
 
-		neighborp = getRegionFromHandle(adj_handle);
-		if (neighborp)
+		if (mWidth == 256 && mLength == 256)
 		{
-			//LL_INFOS() << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << LL_ENDL;
-			regionp->connectNeighbor(neighborp, dir);
+			to_region_handle(adj_x, adj_y, &adj_handle);
+			neighborp = getRegionFromHandle(adj_handle);
+			if (neighborp)
+			{
+				//LL_INFOS() << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << LL_ENDL;
+				regionp->connectNeighbor(neighborp, dir);
+			}
+		}
+		else // Unconventional region size
+		{
+			LLViewerRegion* last_neighborp = NULL;
+			if(gDirAxes[dir][0] < 0) adj_x = region_x - WORLD_PATCH_SIZE;
+			if(gDirAxes[dir][1] < 0) adj_y = region_y - WORLD_PATCH_SIZE;
+
+			for (S32 offset = 0; offset < width; offset += WORLD_PATCH_SIZE)
+			{
+				to_region_handle(adj_x, adj_y, &adj_handle);
+				neighborp = getRegionFromHandle(adj_handle);
+
+				if (neighborp && last_neighborp != neighborp)
+				{
+					//LL_INFOS() << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << LL_ENDL;
+					regionp->connectNeighbor(neighborp, dir);
+					last_neighborp = neighborp;
+				}
+
+				if (dir == NORTH || dir == SOUTH)
+					adj_x += WORLD_PATCH_SIZE;
+				else if (dir == EAST || dir == WEST)
+					adj_y += WORLD_PATCH_SIZE;
+				else if (dir == NORTHEAST || dir == NORTHWEST || dir == SOUTHWEST || dir == SOUTHEAST)
+					break;
+
+			}
 		}
 	}
 
@@ -408,11 +445,19 @@ LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVe
 
 LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
 {
-	for (region_list_t::iterator iter = mRegionList.begin();
-		 iter != mRegionList.end(); ++iter)
+	U32 x, y;
+	from_region_handle(handle, &x, &y);
+
+	for (region_list_t::iterator iter = mRegionList.begin(), iter_end(mRegionList.end());
+		 iter != iter_end; ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
-		if (regionp->getHandle() == handle)
+		U32 checkRegionX, checkRegionY;
+		F32 checkRegionWidth = regionp->getWidth();
+		from_region_handle(regionp->getHandle(), &checkRegionX, &checkRegionY);
+
+		if (x >= checkRegionX && x < (checkRegionX + checkRegionWidth) &&
+			y >= checkRegionY && y < (checkRegionY + checkRegionWidth))
 		{
 			return regionp;
 		}
@@ -422,8 +467,8 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
 
 LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id)
 {
-	for (region_list_t::iterator iter = mRegionList.begin();
-		 iter != mRegionList.end(); ++iter)
+	for (region_list_t::iterator iter = mRegionList.begin(), iter_end(mRegionList.end());
+		 iter != iter_end; ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
 		if (regionp->getRegionID() == region_id)
@@ -449,8 +494,8 @@ void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
 
 BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)
 {
-	for (region_list_t::iterator iter = mRegionList.begin();
-		 iter != mRegionList.end(); ++iter)
+	for (region_list_t::iterator iter = mRegionList.begin(), iter_end(mRegionList.end());
+		 iter != iter_end; ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
 		if (regionp->pointInRegionGlobal(pos_global))
@@ -846,7 +891,7 @@ F32 LLWorld::getLandFarClip() const
 
 void LLWorld::setLandFarClip(const F32 far_clip)
 {
-	static S32 const rwidth = (S32)REGION_WIDTH_U32;
+	S32 const rwidth = (S32)getRegionWidthInMeters();
 	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
 	S32 const n2 = (llceil(far_clip) - 1) / rwidth;
 	bool need_water_objects_update = n1 != n2;
@@ -892,12 +937,14 @@ void LLWorld::updateWaterObjects()
 	S32 max_y = 0;
 	U32 region_x, region_y;
 
-	S32 rwidth = 256;
+	LLViewerRegion const* regionp = gAgent.getRegion();
+
+	// Region width in meters.
+	S32 const rwidth = (S32)regionp->getWidth();
 
 	// We only want to fill in water for stuff that's near us, say, within 256 or 512m
 	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
 
-	LLViewerRegion* regionp = gAgent.getRegion();
 	from_region_handle(regionp->getHandle(), &region_x, &region_y);
 
 	min_x = (S32)region_x - range;
@@ -1116,6 +1163,14 @@ void process_enable_simulator(LLMessageSystem *msg, void **user_data)
 
 	// Viewer trusts the simulator.
 	msg->enableCircuit(sim, TRUE);
+	/*if (!gHippoGridManager->getConnectedGrid()->isSecondLife())
+	{
+		U32 region_size_x = 256;
+		msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeX, region_size_x);
+		U32 region_size_y = 256;
+		msg->getU32Fast(_PREHASH_SimulatorInfo, _PREHASH_RegionSizeY, region_size_y);
+		LLWorld::getInstance()->setRegionSize(region_size_x, region_size_y);
+	}*/
 	LLWorld::getInstance()->addRegion(handle, sim);
 
 	// give the simulator a message it can use to get ip and port
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 8fc59a1db9..d7b082f761 100755
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -108,6 +108,7 @@ public:
 	LLSurfacePatch *		resolveLandPatchGlobal(const LLVector3d &position);
 	LLVector3				resolveLandNormalGlobal(const LLVector3d &position);		// absolute frame
 
+	void						setRegionSize(const U32& width = 0, const U32& length = 0);
 	U32						getRegionWidthInPoints() const	{ return mWidth; }
 	F32						getRegionScale() const			{ return mScale; }
 
@@ -182,12 +183,13 @@ private:
 	region_remove_signal_t mRegionRemovedSignal;
 
 	// Number of points on edge
-	static const U32 mWidth;
+	static U32 mWidth;
+	static U32 mLength;
 
 	// meters/point, therefore mWidth * mScale = meters per edge
 	static const F32 mScale;
 
-	static const F32 mWidthInMeters;
+	static F32 mWidthInMeters;
 
 	F32 mLandFarClip;					// Far clip distance for land.
 	LLPatchVertexArray		mLandPatch;
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 5291541ae7..ef70c4d925 100755
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -67,7 +67,9 @@ LLSimInfo::LLSimInfo(U64 handle)
 	mAgentsUpdateTime(0),
 	mAccess(0x0),
 	mRegionFlags(0x0),
-	mFirstAgentRequest(true)
+	mFirstAgentRequest(true),
+	mSizeX(REGION_WIDTH_UNITS),
+	mSizeY(REGION_WIDTH_UNITS)
 //	mWaterHeight(0.f)
 {
 }
@@ -330,6 +332,20 @@ LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle)
 	{
 		return it->second;
 	}
+	U32 x = 0, y = 0;
+	from_region_handle(handle, &x, &y);
+	for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
+	{
+		U32 checkRegionX, checkRegionY;
+		from_region_handle((*it).first, &checkRegionX, &checkRegionY);
+
+		LLSimInfo* info = (*it).second;
+		if (x >= checkRegionX && x < (checkRegionX + info->getSizeX()) &&
+			y >= checkRegionY && y < (checkRegionY + info->getSizeY()))
+		{
+			return info;
+		}
+	}
 	return NULL;
 }
 
@@ -390,7 +406,7 @@ void LLWorldMap::reloadItems(bool force)
 // static public
 // Insert a region in the region map
 // returns true if region inserted, false otherwise
-bool LLWorldMap::insertRegion(U32 x_world, U32 y_world, std::string& name, LLUUID& image_id, U32 accesscode, U32 region_flags)
+bool LLWorldMap::insertRegion(U32 x_world, U32 y_world, U16 x_size, U16 y_size, std::string& name, LLUUID& image_id, U32 accesscode, U64 region_flags)
 {
 	// This region doesn't exist
 	if (accesscode == 255)
@@ -419,6 +435,7 @@ bool LLWorldMap::insertRegion(U32 x_world, U32 y_world, std::string& name, LLUUI
 		siminfo->setRegionFlags(region_flags);
 	//	siminfo->setWaterHeight((F32) water_height);
 		siminfo->setLandForSaleImage(image_id);
+		siminfo->setSize(x_size, y_size);
 
 		// Handle the location tracking (for teleport, UI feedback and info display)
 		if (LLWorldMap::getInstance()->isTrackingInRectangle( x_world, y_world, x_world + REGION_WIDTH_UNITS, y_world + REGION_WIDTH_UNITS))
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index abfcf3aea7..8453f3d573 100755
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -114,6 +114,7 @@ public:
 
 	// Setters
 	void setName(std::string& name) { mName = name; }
+	void setSize(U16 sizeX, U16 sizeY) { mSizeX = sizeX; mSizeY = sizeY; }
 	void setAccess (U32 accesscode) { mAccess = accesscode; }
 	void setRegionFlags (U32 region_flags) { mRegionFlags = region_flags; }
 	void setLandForSaleImage (LLUUID image_id);
@@ -129,6 +130,10 @@ public:
 	const S32 getAgentCount() const;				// Compute the total agents count
 	LLPointer<LLViewerFetchedTexture> getLandForSaleImage();	// Get the overlay image, fetch it if necessary
 
+	const U64& getHandle() const { return mHandle; }
+	const U16 getSizeX() const { return mSizeX; }
+	const U16 getSizeY() const { return mSizeY; }
+
 	bool isName(const std::string& name) const;
 	bool isDown() { return (mAccess == SIM_ACCESS_DOWN); }
 	bool isPG() { return (mAccess <= SIM_ACCESS_PG); }
@@ -161,6 +166,8 @@ public:
 
 private:
 	U64 mHandle;				// This is a hash of the X and Y world coordinates of the SW corner of the sim
+	U16 mSizeX;
+	U16 mSizeY;
 	std::string mName;			// Region name
 
 	F64 mAgentsUpdateTime;		// Time stamp giving the last time the agents information was requested for that region
@@ -189,8 +196,8 @@ private:
 
 // We request region data on the world by "blocks" of (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) regions
 // This is to reduce the number of requests to the asset DB and get things in big "blocks"
-const S32 MAP_MAX_SIZE = 2048;
-const S32 MAP_BLOCK_SIZE = 4;
+const S32 MAP_MAX_SIZE = 16384;
+const S32 MAP_BLOCK_SIZE = 16;
 const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE);
 
 class LLWorldMap : public LLSingleton<LLWorldMap>
@@ -213,7 +220,7 @@ public:
 
 	// Insert a region and items in the map global instance
 	// Note: x_world and y_world in world coordinates (meters)
-	static bool insertRegion(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 accesscode, U32 region_flags);
+	static bool insertRegion(U32 x_world, U32 y_world, U16 x_size, U16 y_size, std::string& name, LLUUID& uuid, U32 accesscode, U64 region_flags);
 	static bool insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID& uuid, U32 type, S32 extra, S32 extra2);
 
 	// Get info on sims (region) : note that those methods only search the range of loaded sims (the one that are being browsed)
diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp
index 865292fa90..fef2fb6e29 100755
--- a/indra/newview/llworldmapmessage.cpp
+++ b/indra/newview/llworldmapmessage.cpp
@@ -169,6 +169,8 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
 	{
 		U16 x_regions;
 		U16 y_regions;
+		U16 x_size = 256;
+		U16 y_size = 256;
 		std::string name;
 		U8 accesscode;
 		U32 region_flags;
@@ -183,6 +185,16 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
 //		msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block);
 //		msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block);
 		msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block);
+		if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0)
+		{
+			msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block);
+			msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block);
+		}
+		if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0)
+		{
+			x_size = 256;
+			y_size = 256;
+		}
 
 		U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS;
 		U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS;
@@ -191,7 +203,7 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)
 		llassert(!name.empty());
 
 		// Insert that region in the world map, if failure, flag it as a "null_sim"
-		if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, name, image_id, (U32)accesscode, region_flags)))
+		if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, x_size, y_size, name, image_id, (U32)accesscode, region_flags)))
 		{
 			found_null_sim = true;
 		}
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index 2bc0d5a086..923afb992c 100755
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -316,5 +316,11 @@ namespace tut
 		ensure_equals("region", slurl.getRegion(), "my region");
 		ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
 
+		slurl = LLSLURL("http://my.grid.com:8002/region/my%20region/1/2/3");
+		ensure_equals("login string", slurl.getLoginString(), "uri:my region&amp;1&amp;2&amp;3");
+		ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3");
+		ensure_equals("grid", slurl.getGrid(), "my.grid.com");
+		ensure_equals("region", slurl.getRegion(), "my region");
+		ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
 	}
 }
-- 
GitLab