]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
wip: dynamic font size loading stuff
authorClyne Sullivan <tullivan99@gmail.com>
Mon, 21 Mar 2016 08:22:09 +0000 (04:22 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Mon, 21 Mar 2016 08:22:09 +0000 (04:22 -0400)
Changelog
include/world.h
main.cpp
src/ui.cpp
src/world.cpp

index 05ac163e86f484b1f3ea995e899db350f6d99b9e..fbef63e088e9e38ab01b71f066587ac1cafe1490 100644 (file)
--- a/Changelog
+++ b/Changelog
        - 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
index 553cd8de145cdd93520f9cd8c2c0a6a690d4a9a0..3a2d44559bce117d080d571cfa43dbe89b1f746d 100644 (file)
@@ -511,4 +511,6 @@ World *loadWorldFromXML(std::string path);
 
 World *loadWorldFromXMLNoSave(std::string path);
 
+World *loadWorldFromPtr( World *ptr );
+
 #endif // WORLD_H
index 69aab76c8f11965c73a62f087237cade38f18508..acbc4f62ca6a338e82c47f0b6ff4b7eee6354719 100644 (file)
--- 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();
 
index f69bfe812984931fcaca7e53120e4e41b0714a3f..9ed941d23c757394d43652660415bb06d3f766d3 100644 (file)
@@ -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] &&
index dec9a64e849b654991bb30c244fa5933e0cc0e6f..2c7e06d85b83efe07b2b50839e233fe502ebaa3f 100644 (file)
@@ -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"));