From 3432a970912dac94d9ba527f10f0354dcc396bf4 Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <tullivan99@gmail.com>
Date: Mon, 21 Mar 2016 04:22:09 -0400
Subject: wip: dynamic font size loading stuff

---
 Changelog       |  10 +++
 include/world.h |   2 +
 main.cpp        |   8 +-
 src/ui.cpp      | 226 +++++++++++++++++++++++---------------------------------
 src/world.cpp   |  92 +++++++++++++++--------
 5 files changed, 172 insertions(+), 166 deletions(-)

diff --git a/Changelog b/Changelog
index 05ac163..fbef63e 100644
--- a/Changelog
+++ b/Changelog
@@ -779,3 +779,13 @@
 	- planned ahead
 
 	~ set finish date for game engine: 3/31
+
+3/17/2016:
+==========
+
+	- cleaned up ui stuff (more std::strings)
+	- worlds load adjacent worlds for faster loading
+	- fixed world fall-through error
+	- (WIP) made ui options dynamic (boxes can have 'infinite' options)
+	- can scroll through inventory with mouse wheel
+	- added text transparency support
diff --git a/include/world.h b/include/world.h
index 553cd8d..3a2d445 100644
--- a/include/world.h
+++ b/include/world.h
@@ -511,4 +511,6 @@ World *loadWorldFromXML(std::string path);
 
 World *loadWorldFromXMLNoSave(std::string path);
 
+World *loadWorldFromPtr( World *ptr );
+
 #endif // WORLD_H
diff --git a/main.cpp b/main.cpp
index 69aab76..acbc4f6 100644
--- a/main.cpp
+++ b/main.cpp
@@ -35,7 +35,7 @@ using namespace tinyxml2;
  * Defines how many milliseconds each game tick will take.
  */
 
-#define MSEC_PER_TICK (1000/TICKS_PER_SEC)
+#define MSEC_PER_TICK ( 1000 / TICKS_PER_SEC )
 
 /**
  * The window object returned by SDL when we create the main window.
@@ -69,7 +69,9 @@ float handAngle;
  * logic operations have to go access members of this object in order to work.
  */
 
-World  	*currentWorld = NULL;
+World *currentWorld        = NULL,
+	  *currentWorldToLeft  = NULL,
+	  *currentWorldToRight = NULL;
 
 /**
  * The player object.
@@ -415,7 +417,7 @@ int main(int argc, char *argv[]){
 	//currentWorld->mob.back()->followee = player;
 
 	gameRunning = true;
-	
+
 	while ( gameRunning )
 		mainLoop();
 
diff --git a/src/ui.cpp b/src/ui.cpp
index f69bfe8..9ed941d 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -39,9 +39,17 @@ extern unsigned int tickCount;
 static FT_Library   ftl;
 static FT_Face      ftf;
 static GLuint       ftex[93];
-static vec2			ftexwh[93];
+/*static vec2			ftexwh[93];
 static vec2			ftexbl[93];
-static vec2			ftexad[93];
+static vec2			ftexad[93];*/
+
+typedef struct {
+	vec2 wh;
+	vec2 bl;
+	vec2 ad;
+} FT_Info;
+
+static FT_Info ftdat[93];
 
 static unsigned char fontColor[3] = {255,255,255};
 
@@ -49,11 +57,10 @@ static unsigned char fontColor[3] = {255,255,255};
  *	Variables for dialog boxes / options.
 */
 
-static char			 dialogBoxText[512];
-static char			*dialogOptText[4];
+static std::string   dialogBoxText;
+static std::vector<std::pair<std::string,vec3>> dialogOptText;
 static float         merchAOptLoc[2][3];
 static float	 	 dialogOptLoc[4][3];
-static unsigned char dialogOptCount = 0;
 static bool			 typeOutDone = true;
 
 /*
@@ -194,7 +201,6 @@ namespace ui {
 
 	void setFontSize(unsigned int size){
 		unsigned int i,j;
-		unsigned char *buf;
 
 		fontSize=size;
 		FT_Set_Pixel_Sizes(ftf,0,fontSize);
@@ -234,26 +240,20 @@ namespace ui {
 			 *	making it white-on-black.
 			*/
 
-			buf = new unsigned char[ftf->glyph->bitmap.width * ftf->glyph->bitmap.rows * 4];
 
-			for(j=0;j<ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows;j++){
-				buf[j*4  ]=255;//fontColor[0];
-				buf[j*4+1]=255;//fontColor[1];
-				buf[j*4+2]=255;//fontColor[2];
-				buf[j*4+3]=ftf->glyph->bitmap.buffer[j] ? 255 : 0;
-				//buf[j*4+3]=ftf->glyph->bitmap.buffer[j];
-			}
+			std::vector<uint32_t> buf ( ftf->glyph->bitmap.width * ftf->glyph->bitmap.rows, 0 );
 
-			ftexwh[i-33].x=ftf->glyph->bitmap.width;
-			ftexwh[i-33].y=ftf->glyph->bitmap.rows;
-			ftexbl[i-33].x=ftf->glyph->bitmap_left;
-			ftexbl[i-33].y=ftf->glyph->bitmap_top;
-			ftexad[i-33].x=ftf->glyph->advance.x>>6;
-			ftexad[i-33].y=ftf->glyph->advance.y>>6;
+			for( j = 0; j < buf.size(); j++ )
+				buf[j] = 0x00FFFFFF | (ftf->glyph->bitmap.buffer[j] ? (0xFF << 24) : 0);
 
-			glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
+			ftdat[i-33].wh.x=ftf->glyph->bitmap.width;
+			ftdat[i-33].wh.y=ftf->glyph->bitmap.rows;
+			ftdat[i-33].bl.x=ftf->glyph->bitmap_left;
+			ftdat[i-33].bl.y=ftf->glyph->bitmap_top;
+			ftdat[i-33].ad.x=ftf->glyph->advance.x>>6;
+			ftdat[i-33].ad.y=ftf->glyph->advance.y>>6;
 
-			delete[] buf;	//free(buf);
+			glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf.data());
 		}
 	}
 
@@ -280,9 +280,9 @@ namespace ui {
 		 *	Get the width and height of the rendered character.
 		*/
 
-		c1={(float)floor(x)+ftexbl[c-33].x,
-		    (float)floor(y)+ftexbl[c-33].y};
-		c2=ftexwh[c-33];
+		c1={(float)floor(x)+ftdat[c-33].bl.x,
+		    (float)floor(y)+ftdat[c-33].bl.y};
+		c2=ftdat[c-33].wh;
 
 		/*
 		 *	Draw the character:
@@ -302,11 +302,8 @@ namespace ui {
 		glPopMatrix();
 		glDisable(GL_TEXTURE_2D);
 
-		/*
-		 * return the width.
-		*/
-
-		return ftexad[c-33];//(vec2){c2.x,ftexad[c-33].y};
+		// return the width.
+		return ftdat[c-33].ad;
 	}
 
 	/*
@@ -380,7 +377,7 @@ namespace ui {
 				width += fontSize / 2;
 				break;
 			default:
-				width += ftexwh[i].x + fontSize * 0.1f;
+				width += ftdat[i].wh.x + fontSize * 0.1f;
 				break;
 			}
 		} while(s[++i]);
@@ -395,7 +392,7 @@ namespace ui {
 	*/
 
 	std::string ret;
-	std::string typeOut(char *str){
+	std::string typeOut( std::string str ) {
 		static unsigned int sinc,	//	Acts as a delayer for the space between each character.
 							linc=0,	//	Contains the number of letters that should be drawn.
 							size=0;	//	Contains the full size of the current string.
@@ -404,9 +401,9 @@ namespace ui {
 		 *	Reset values if a new string is being passed.
 		*/
 
-		if(strncmp(ret.c_str(),str,linc-1)){
+		if(strncmp(ret.c_str(),str.c_str(),linc-1)){
 			ret.clear();			//	Zero the buffer
-			size=strlen(str);		//	Set the new target string size
+			size=str.size();		//	Set the new target string size
 			linc=0;					//	Reset the incrementers
 			sinc=1;
 			typeOutDone = false;
@@ -421,7 +418,7 @@ namespace ui {
 		else if(++sinc==2){
 			sinc=0;
 
-			ret.append( 1, *(str + linc) );
+			ret.append(str, linc, 1);
 
 			if(linc<size)
 				linc++;
@@ -436,92 +433,57 @@ namespace ui {
 	 *	Draw a formatted string to the specified coordinates.
 	*/
 
-	float putText(const float x,const float y,const char *str,...){
+	float putText( const float x, const float y, const char *str, ... ) {
 		va_list args;
-		char *buf;
-		float width;
+		std::unique_ptr<char[]> buf (new char[512]);
 
-		/*
-		 *	Create a wimpy buffer.
-		*/
-
-		buf = new char[512];	//(char *)calloc(128,sizeof(char));
-		memset(buf,0,512*sizeof(char));
+		// zero out the buffer
+		memset(buf.get(),0,512*sizeof(char));
 
 		/*
 		 *	Handle the formatted string, printing it to the buffer.
-		*/
+		 */
 
 		va_start(args,str);
-		vsnprintf(buf,512,str,args);
+		vsnprintf(buf.get(),512,str,args);
 		va_end(args);
 
-		/*
-		 *	Draw the string, free resources, return the width of the string.
-		*/
-
-		width=putString(x,y,buf);
-		delete[] buf;	//free(buf);
-
-		return width;
+		// draw the string and return the width
+		return putString( x, y, buf.get() );
 	}
-	void dialogBox(const char *name,const char *opt,bool passive,const char *text,...){
-		textWrapLimit = 110;
+
+	void dialogBox( const char *name, const char *opt, bool passive, const char *text, ... ) {
 		va_list dialogArgs;
-		unsigned int len;
-		char *sopt,*soptbuf;
+		std::unique_ptr<char[]> printfbuf (new char[512]);
 
+		textWrapLimit = 110;
 		dialogPassive = passive;
 
-		/*
-		 *	Set up the text buffer.
-		*/
-
-		memset(dialogBoxText,0,512);
-
-		/*
-		 *	Get the text ready for rendering.
-		*/
-
-		len=strlen(name);
-		strcpy(dialogBoxText    ,name);
-		strcpy(dialogBoxText+len,": ");
-		len+=2;
+		// reset & add speaker prefix
+		dialogBoxText.clear();
+		dialogBoxText = (std::string)name + ": ";
 
+		// handle the formatted string
 		va_start(dialogArgs,text);
-		vsnprintf(dialogBoxText+len,512-len,text,dialogArgs);
+		vsnprintf(printfbuf.get(),512,text,dialogArgs);
 		va_end(dialogArgs);
+		dialogBoxText += printfbuf.get();
 
-		/*
-		 *	Set up option text.
-		*/
+		// setup option text
+		dialogOptText.clear();
 
-		while(dialogOptCount){
-			if(dialogOptText[dialogOptCount]){
-				delete[] dialogOptText[dialogOptCount];	//free(dialogOptText[dialogOptCount]);
-				dialogOptText[dialogOptCount] = NULL;
-			}
-			dialogOptCount--;
-		};
-
-		dialogOptCount = 0;
 		dialogOptChosen = 0;
 		memset(&dialogOptLoc,0,sizeof(float)*12);
 
-		if(opt != NULL){
-
-			soptbuf = new char[strlen(opt)+1];
-			strcpy(soptbuf,opt);
+		if ( opt ) {
+			std::string soptbuf = opt;
+			char *sopt = strtok(&soptbuf[0], ":");
 
-			sopt=strtok(soptbuf,":");
-			while(sopt != NULL){
-				dialogOptText[dialogOptCount] = new char[strlen(sopt)+1];	//(char *)malloc(strlen(sopt));
-				strcpy(dialogOptText[dialogOptCount++],sopt);
-				sopt=strtok(NULL,":");
+			// cycle through options
+			while(sopt){
+				dialogOptText.push_back(std::make_pair((std::string)sopt, vec3 {0,0,0}) );
+				sopt = strtok(NULL,":");
 			}
-
-			delete[] soptbuf;
-
 		}
 
 		/*
@@ -536,9 +498,10 @@ namespace ui {
 
 
 	void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...){
-		std::cout << "Buying and selling on the bi-weekly!" << std::endl;
 		va_list dialogArgs;
-		size_t len;
+		std::unique_ptr<char[]> printfbuf (new char[512]);
+
+		std::cout << "Buying and selling on the bi-weekly!" << std::endl;
 
 		dialogPassive = passive;
 
@@ -547,40 +510,28 @@ namespace ui {
 		merchTrade = trade;
 
 		// clear the buffer
-		memset(dialogBoxText, '\0', 512);
-
-		// create the string
-		strcpy(dialogBoxText, name);
-		strcat(dialogBoxText, ": ");
+		dialogBoxText.clear();
+		dialogBoxText = (std::string)name + ": ";
 
-		len=strlen(dialogBoxText);
 		va_start(dialogArgs,text);
-		vsnprintf(dialogBoxText + len, 512 - len, text, dialogArgs);
+		vsnprintf(printfbuf.get(),512,text,dialogArgs);
 		va_end(dialogArgs);
+		dialogBoxText += printfbuf.get();
 
 		// free old option text
-		while(dialogOptCount){
-			if(dialogOptText[dialogOptCount]){
-				delete[] dialogOptText[dialogOptCount];
-				dialogOptText[dialogOptCount] = NULL;
-			}
-
-			dialogOptCount--;
-		};
+		dialogOptText.clear();
 
 		dialogOptChosen = 0;
 		memset(&dialogOptLoc, 0, sizeof(float) * 12);
 
 		// handle options if desired
 		if(opt){
-			//std::unique_ptr<char[]> soptbuf (new char[strlen(opt) + 1]);
-			char soptbuf[255];
-			strcpy(soptbuf, opt);
-			char *sopt = strtok(soptbuf, ":");
+			std::string soptbuf = opt;
+			char *sopt = strtok(&soptbuf[0], ":");
 
 			// cycle through options
 			while(sopt){
-				strcpy( (dialogOptText[dialogOptCount++] = new char[strlen(sopt) + 1]), sopt);
+				dialogOptText.push_back(std::make_pair((std::string)sopt, vec3 {0,0,0}) );
 				sopt = strtok(NULL,":");
 			}
 		}
@@ -622,29 +573,40 @@ namespace ui {
 	}
 	void importantText(const char *text,...){
 		va_list textArgs;
+		char *printfbuf;
 
 		//if(!player->ground)return;
 
-		memset(dialogBoxText,0,512);
+		//memset(dialogBoxText,0,512);
+		dialogBoxText.clear();
 
+		printfbuf = new char[ 512 ];
 		va_start(textArgs,text);
-		vsnprintf(dialogBoxText,512,text,textArgs);
+		vsnprintf(printfbuf,512,text,textArgs);
 		va_end(textArgs);
+		dialogBoxText = printfbuf;
+		delete[] printfbuf;
 
 		dialogBoxExists = true;
 		dialogImportant = true;
 		//toggleBlack();
 	}
+
 	void passiveImportantText(int duration, const char *text,...){
 		va_list textArgs;
+		char *printfbuf;
 
 		//if(!player->ground)return;
 
-		memset(dialogBoxText,0,512);
+		//memset(dialogBoxText,0,512);
+		dialogBoxText.clear();
 
+		printfbuf = new char[ 512 ];
 		va_start(textArgs,text);
-		vsnprintf(dialogBoxText,512,text,textArgs);
+		vsnprintf(printfbuf,512,text,textArgs);
 		va_end(textArgs);
+		dialogBoxText = printfbuf;
+		delete[] printfbuf;
 
 		dialogBoxExists = true;
 		dialogImportant = true;
@@ -689,9 +651,9 @@ namespace ui {
 					}
 				}
 				if(fadeIntensity == 255 || dialogPassive){
-					setFontSize(24);
+					//setFontSize(24);
 					putStringCentered(offset.x,offset.y,rtext.c_str());
-					setFontSize(16);
+					//setFontSize(16);
 				}
 			}else if(dialogMerchant){
 				//static int dispItem;
@@ -772,11 +734,11 @@ namespace ui {
 
 
 				// draw / handle dialog options if they exist
-				for(i = 0; i < dialogOptCount; i++){
+				for(i = 0; i < dialogOptText.size(); i++){
 					setFontColor(255, 255, 255);
 
 					// draw option
-					tmp = putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i]);
+					tmp = putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i].first);
 
 					// get coordinate information on option
 					dialogOptLoc[i][2] = offset.x + tmp;
@@ -787,7 +749,7 @@ namespace ui {
 					if(mouse.x > dialogOptLoc[i][0] && mouse.x < dialogOptLoc[i][2] &&
 					   mouse.y > dialogOptLoc[i][1] && mouse.y < dialogOptLoc[i][1] + 16 ){
 						  setFontColor(255, 255, 0);
-						  putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i]);
+						  putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i].first);
 					}
 				}
 
@@ -815,9 +777,9 @@ namespace ui {
 
 				putString(x+HLINE,y-fontSize-HLINE,rtext);
 
-				for(i=0;i<dialogOptCount;i++){
+				for(i=0;i<dialogOptText.size();i++){
 					setFontColor(255,255,255);
-					tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
+					tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i].first);
 					dialogOptLoc[i][2] = offset.x + tmp;
 					dialogOptLoc[i][0] = offset.x - tmp;
 					dialogOptLoc[i][1] = y - SCREEN_HEIGHT / 4 + (fontSize + HLINE) * (i + 1);
@@ -826,7 +788,7 @@ namespace ui {
 					   mouse.y > dialogOptLoc[i][1] &&
 					   mouse.y < dialogOptLoc[i][1] + 16 ){ // fontSize
 						  setFontColor(255,255,0);
-						  putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
+						  putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i].first);
 					}
 				}
 				setFontColor(255,255,255);
@@ -1224,7 +1186,7 @@ namespace ui {
 			return;
 		}
 
-		for(i=0;i<dialogOptCount;i++){
+		for(i=0;i<dialogOptText.size();i++){
 			if(mouse.x > dialogOptLoc[i][0] &&
 			   mouse.x < dialogOptLoc[i][2] &&
 			   mouse.y > dialogOptLoc[i][1] &&
diff --git a/src/world.cpp b/src/world.cpp
index dec9a64..2c7e06d 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -22,6 +22,8 @@ using namespace tinyxml2;
 
 extern Player *player;						// main.cpp?
 extern World  *currentWorld;				// main.cpp
+extern World  *currentWorldToLeft;			// main.cpp
+extern World  *currentWorldToRight;			// main.cpp
 extern int     commonAIFunc(NPC *);			// entities.cpp
 extern void    commonTriggerFunc(Mob *);	// gameplay.cpp
 extern void    commonPageFunc(Mob *);		// gameplay.cpp
@@ -748,54 +750,49 @@ singleDetect( Entity *e )
 		exit(0);
 	}
 
-	/*
-	 *	Handle only living entities.
-	*/
-
-	if(e->alive){
-
+	// handle only living entities
+	if ( e->alive ) {
 		if ( e->type == MOBT && Mobp(e)->subtype == MS_TRIGGER )
 			return;
 
 		/*
 		 *	Calculate the line that this entity is currently standing on.
-		*/
+		 */
 
 		l=(e->loc.x + e->width / 2 - worldStart) / HLINE;
-		if(l < 0) l=0;
+		if ( l < 0 )
+            l = 0;
 		i = l;
-		if(i > lineCount-1) i=lineCount-1;
+		if ( i > lineCount - 1 )
+            i = lineCount - 1;
 
 		/*
 		 *	If the entity is under the world/line, pop it back to the surface.
 		*/
 
 		if ( e->loc.y < worldData[i].groundHeight ) {
-
-      if ( worldData[i].groundHeight - e->loc.y > 30 ) {
-        int dir = e->vel.x > 0 ? -1 : 1;
-        e->loc.x += HLINE * 8 * dir;
-        e->loc.y = worldData[i + 8 * dir].groundHeight;
-      } else {
-        e->loc.y = worldData[i].groundHeight - .001 * deltaTime;
-			  e->ground = true;
-			  e->vel.y = 0;
-      }
+            int dir = e->vel.x > 0 ? -1 : 1;
+            if ( worldData[i].groundHeight - 30 > worldData[i + dir].groundHeight ) {
+                e->loc.x += HLINE * 8 * dir;
+                e->loc.y = worldData[i + 8 * dir].groundHeight;
+            } else {
+                e->loc.y = worldData[i].groundHeight - .001 * deltaTime;
+		        e->ground = true;
+		        e->vel.y = 0;
+            }
 
 		/*
 		 *	Handle gravity if the entity is above the line.
-		*/
+		 */
 
 		} else {
-
 			if(e->type == STRUCTURET && e->loc.y > 2000){
 				e->loc.y = worldData[i].groundHeight;
 				e->vel.y = 0;
 				e->ground = true;
 				return;
 			} else if ( e->vel.y > -2 )
-        e->vel.y -= .003 * deltaTime;
-
+                e->vel.y -= .003 * deltaTime;
 		}
 
 		/*
@@ -993,13 +990,13 @@ goWorldLeft( Player *p )
 {
 	World *tmp;
 
-  // check if player is at world edge
+    // check if player is at world edge
 	if( !toLeft.empty() && p->loc.x < worldStart + HLINE * 15.0f ) {
 
-    // load world (`toLeft` conditional confirms existance)
-		tmp = loadWorldFromXML(toLeft);
+        // load world (`toLeft` conditional confirms existance)
+	    tmp = loadWorldFromPtr( currentWorldToLeft );
 
-    // adjust player location
+        // adjust player location
 		p->loc.x = tmp->worldStart + HLINE * 20;
 		p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight;
 
@@ -1015,7 +1012,7 @@ goWorldRight( Player *p )
 	World *tmp;
 
 	if( !toRight.empty() && p->loc.x + p->width > -worldStart - HLINE * 15 ) {
-		tmp = loadWorldFromXML(toRight);
+		tmp = loadWorldFromPtr( currentWorldToRight );
 
 		p->loc.x = tmp->worldStart - HLINE * -15.0f;
 		p->loc.y = GROUND_HEIGHT_MINIMUM;
@@ -1352,6 +1349,11 @@ World *Arena::exitArena(Player *p){
 	}
 }
 
+
+
+static bool loadedLeft = false;
+static bool loadedRight = false;
+
 World *loadWorldFromXML(std::string path){
 	if ( !currentXML.empty() )
 		currentWorld->save();
@@ -1359,6 +1361,21 @@ World *loadWorldFromXML(std::string path){
 	return loadWorldFromXMLNoSave(path);
 }
 
+World *loadWorldFromPtr( World *ptr )
+{
+    World *tmp = ptr;
+
+    loadedLeft = true;
+    currentWorldToLeft = loadWorldFromXML( tmp->toLeft );
+    loadedLeft = false;
+
+    loadedRight = true;
+    currentWorldToRight = loadWorldFromXML( tmp->toRight );
+    loadedRight = false;
+
+    return tmp;
+}
+
 /**
  * Loads a world from the given XML file.
  */
@@ -1376,6 +1393,9 @@ loadWorldFromXMLNoSave( std::string path ) {
 	const char *ptr;
 	std::string name;
 
+    if ( path.empty() )
+        return NULL;
+
 	currentXML = (std::string)"xml/" + path;
 
 	xml.LoadFile(currentXML.c_str());
@@ -1397,11 +1417,21 @@ loadWorldFromXMLNoSave( std::string path ) {
 		name = wxml->Name();
 
 		if ( name == "link" ) {
-			if((ptr = wxml->Attribute("left")))
+			if ((ptr = wxml->Attribute("left"))) {
 				tmp->setToLeft(ptr);
-			else if((ptr = wxml->Attribute("right")))
+                if ( !loadedLeft ) {
+                    loadedLeft = true;
+                    currentWorldToLeft = loadWorldFromXMLNoSave( ptr );
+                    loadedLeft = false;
+                }
+			} else if ((ptr = wxml->Attribute("right"))) {
 				tmp->setToRight(ptr);
-			else
+                if ( !loadedRight ) {
+                    loadedRight = true;
+                    currentWorldToRight = loadWorldFromXMLNoSave( ptr );
+                    loadedRight = false;
+                }
+			} else
 				abort();
 		} else if ( name == "style" ) {
 			tmp->setStyle(wxml->StrAttribute("folder"));
-- 
cgit v1.2.3