Cycles: add location/rotate/scale and XYZ mapping options for all texture nodes,
[blender.git] / source / blender / blenloader / intern / readfile.c
index d461f5e7471febe8997e96d612d412c8f6b7ef2b..1c96cd2e05af59619dc0e6915c95c2d3306ab0ec 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -85,6 +83,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_smoke_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_space_types.h"
 #include "DNA_vfont_types.h"
 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
 #include "BKE_sound.h"
 
+#include "NOD_socket.h"
+
 //XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
 //XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie
 //XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
@@ -237,6 +238,7 @@ typedef struct OldNewMap {
 /* local prototypes */
 static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
 static void direct_link_modifiers(FileData *fd, ListBase *lb);
+static void convert_tface_mt(FileData *fd, Main *main);
 
 static OldNewMap *oldnewmap_new(void) 
 {
@@ -514,7 +516,7 @@ static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *filepat
        BLI_addtail(mainlist, m);
 
        lib= alloc_libblock(&m->library, ID_LI, "lib");
-       strncpy(lib->name, filepath, sizeof(lib->name)-1);
+       BLI_strncpy(lib->name, filepath, sizeof(lib->name));
        BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
        
        m->curlib= lib;
@@ -1046,7 +1048,7 @@ void blo_freefiledata(FileData *fd)
 
 /* ************ DIV ****************** */
 
-int BLO_has_bfile_extension(char *str)
+int BLO_has_bfile_extension(const char *str)
 {
        return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend") || BLI_testextensie(str, ".blend.gz"));
 }
@@ -2053,10 +2055,115 @@ static void lib_link_nodetree(FileData *fd, Main *main)
        }
 }
 
+static void ntree_tmp_cycles_emission_version_patch(FileData *fd, Library *lib, bNodeTree *ntree)
+{
+       bNode *node;
+       bNodeSocket *sock;
+       bNodeSocketValueFloat *valfloat;
+
+       for(node=ntree->nodes.first; node; node=node->next) {
+               if(node->type == SH_NODE_EMISSION) {
+                       for(sock=node->inputs.first; sock; sock=sock->next) {
+                               if(strcmp(sock->name, "Strength") == 0) {
+                                       valfloat= sock->default_value;
+                                       valfloat->value /= M_PI;
+                               }
+                       }
+               }
+               else if(node->type == NODE_GROUP) {
+                       bNodeTree *ntree= newlibadr(fd, lib, node->id);
+
+                       if(ntree)
+                               ntree_tmp_cycles_emission_version_patch(fd, lib, ntree);
+               }
+       }
+}
+
+static void ntree_tmp_cycles_version_patch(bNodeTree *ntree)
+{
+       bNode *node;
+       bNodeSocket *sock;
+
+       for(node=ntree->nodes.first; node; node=node->next) {
+               if(node->type == SH_NODE_FRESNEL) {
+
+                       for(sock=node->inputs.first; sock; sock=sock->next) {
+                               if(strcmp(sock->name, "Fresnel") == 0) {
+                                       bNodeSocket *osock;
+
+                                       node->type = SH_NODE_BLEND_WEIGHT;
+                                       strcpy(sock->name, "Blend");
+
+                                       for(osock=node->outputs.first; osock; osock=osock->next)
+                                               if(strcmp(osock->name, "Fac") == 0)
+                                                       strcpy(osock->name, "Fresnel");
+                               }
+                       }
+               }
+               else {
+                       for(sock=node->inputs.first; sock; sock=sock->next) {
+                               if(strcmp(sock->name, "Closure1") == 0)
+                                       strcpy(sock->name, "Shader1");
+                               if(strcmp(sock->name, "Closure2") == 0)
+                                       strcpy(sock->name, "Shader2");
+
+                               if(strcmp(sock->name, "Color1") == 0)
+                                       strcpy(sock->name, "Color");
+                               if(strcmp(sock->name, "Color2") == 0)
+                                       strcpy(sock->name, "Color");
+
+                               if(strcmp(sock->name, "Vector1") == 0)
+                                       strcpy(sock->name, "Vector");
+                               if(strcmp(sock->name, "Vector2") == 0)
+                                       strcpy(sock->name, "Vector");
+
+                               if(strcmp(sock->name, "Value1") == 0)
+                                       strcpy(sock->name, "Value");
+                               if(strcmp(sock->name, "Value2") == 0)
+                                       strcpy(sock->name, "Value");
+
+                               if(strcmp(sock->name, "Shader1") == 0)
+                                       strcpy(sock->name, "Shader");
+                               if(strcmp(sock->name, "Shader2") == 0)
+                                       strcpy(sock->name, "Shader");
+
+                               if(node->type == SH_NODE_OUTPUT_MATERIAL ||
+                                  node->type == SH_NODE_OUTPUT_WORLD ||
+                                  node->type == SH_NODE_OUTPUT_LAMP) {
+                                       if(strcmp(sock->name, "Shader") == 0)
+                                               strcpy(sock->name, "Surface");
+                               }
+
+                               if(strcmp(sock->name, "Fresnel") == 0) {
+                                       strcpy(sock->name, "IOR");
+                                       sock->ns.vec[0] = 1.0f/MAX2(1.0f - sock->ns.vec[0], 1e-5f);
+                               }
+                       }
+
+                       for(sock=node->outputs.first; sock; sock=sock->next)
+                               if(strcmp(sock->name, "Closure") == 0)
+                                       strcpy(sock->name, "Shader");
+               }
+       }
+}
+
+static void lib_nodetree_init_types_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       bNode *node;
+
+       ntree_tmp_cycles_version_patch(ntree);
+       
+       ntreeInitTypes(ntree);
+       
+       /* XXX could be replaced by do_versions for new nodes */
+       for (node=ntree->nodes.first; node; node=node->next)
+               node_verify_socket_templates(ntree, node);
+}
+
 /* updates group node socket own_index so that
  * external links to/from the group node are preserved.
  */
-static void lib_node_do_versions_group(bNode *gnode)
+static void lib_node_do_versions_group_indices(bNode *gnode)
 {
        bNodeTree *ngroup= (bNodeTree*)gnode->id;
        bNode *intnode;
@@ -2089,104 +2196,102 @@ static void lib_node_do_versions_group(bNode *gnode)
 }
 
 /* updates external links for all group nodes in a tree */
-static void lib_nodetree_do_versions_group(bNodeTree *ntree)
+static void lib_nodetree_do_versions_group_indices_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
 {
        bNode *node;
        
        for (node=ntree->nodes.first; node; node=node->next) {
                if (node->type==NODE_GROUP) {
                        bNodeTree *ngroup= (bNodeTree*)node->id;
-                       if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS))
-                               lib_node_do_versions_group(node);
+                       if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE))
+                               lib_node_do_versions_group_indices(node);
                }
        }
 }
 
+/* make an update call for the tree */
+static void lib_nodetree_do_versions_update_cb(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       if (ntree->update)
+               ntreeUpdateTree(ntree);
+}
+
 /* verify types for nodes and groups, all data has to be read */
 /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
 * typedefs*/
 static void lib_verify_nodetree(Main *main, int UNUSED(open))
 {
-       Scene *sce;
-       Material *ma;
-       Lamp *la;
-       World *wrld;
-       Tex *tx;
        bNodeTree *ntree;
-       
+       int i;
+       bNodeTreeType *ntreetype;
+
        /* this crashes blender on undo/redo
                if(open==1) {
                        reinit_nodesystem();
                }*/
        
-       /* now create the own typeinfo structs an verify nodes */
-       /* here we still assume no groups in groups */
-       for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
-               ntreeVerifyTypes(ntree);                /* internal nodes, no groups! */
+       /* set node->typeinfo pointers */
+       for (i=0; i < NUM_NTREE_TYPES; ++i) {
+               ntreetype= ntreeGetType(i);
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, NULL, lib_nodetree_init_types_cb);
        }
+       for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+               lib_nodetree_init_types_cb(NULL, NULL, ntree);
        
        {
-               /*int has_old_groups=0;*/ /*UNUSED*/
+               int has_old_groups=0;
                /* XXX this should actually be part of do_versions, but since we need
                 * finished library linking, it is not possible there. Instead in do_versions
                 * we have set the NTREE_DO_VERSIONS flag, so at this point we can do the
                 * actual group node updates.
                 */
                for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
-                       if (ntree->flag & NTREE_DO_VERSIONS) {
+                       if (ntree->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE) {
                                /* this adds copies and links from all unlinked internal sockets to group inputs/outputs. */
-                               nodeGroupExposeAllSockets(ntree);
-                               /*has_old_groups = 1;*/ /*UNUSED*/
+                               node_group_expose_all_sockets(ntree);
+                               has_old_groups = 1;
                        }
                }
-               /* now verify all types in material trees, groups are set OK now */
-               for(ma= main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->nodetree)
-                               lib_nodetree_do_versions_group(ma->nodetree);
-               }
-               /* and scene trees */
-               for(sce= main->scene.first; sce; sce= sce->id.next) {
-                       if(sce->nodetree)
-                               lib_nodetree_do_versions_group(sce->nodetree);
-               }
-               /* and texture trees */
-               for(tx= main->tex.first; tx; tx= tx->id.next) {
-                       if(tx->nodetree)
-                               lib_nodetree_do_versions_group(tx->nodetree);
+               
+               if (has_old_groups) {
+                       for (i=0; i < NUM_NTREE_TYPES; ++i) {
+                               ntreetype= ntreeGetType(i);
+                               if (ntreetype && ntreetype->foreach_nodetree)
+                                       ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_group_indices_cb);
+                       }
                }
                
                for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
-                       ntree->flag &= ~NTREE_DO_VERSIONS;
-       }
-
-       /* now verify all types in material trees, groups are set OK now */
-       for(ma= main->mat.first; ma; ma= ma->id.next) {
-               if(ma->nodetree)
-                       ntreeVerifyTypes(ma->nodetree);
-       }
-       /* and world trees */
-       for(wrld= main->world.first; wrld; wrld= wrld->id.next) {
-               if(wrld->nodetree)
-                       ntreeVerifyTypes(wrld->nodetree);
-       }
-       /* and lamp trees */
-       for(la= main->lamp.first; la; la= la->id.next) {
-               if(la->nodetree)
-                       ntreeVerifyTypes(la->nodetree);
+                       ntree->flag &= ~NTREE_DO_VERSIONS_GROUP_EXPOSE;
        }
-       /* and scene trees */
-       for(sce= main->scene.first; sce; sce= sce->id.next) {
-               if(sce->nodetree)
-                       ntreeVerifyTypes(sce->nodetree);
+       
+       /* verify all group user nodes */
+       for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) {
+               ntreeVerifyNodes(main, &ntree->id);
        }
-       /* and texture trees */
-       for(tx= main->tex.first; tx; tx= tx->id.next) {
-               if(tx->nodetree)
-                       ntreeVerifyTypes(tx->nodetree);
+       
+       /* make update calls where necessary */
+       {
+               for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next)
+                       if (ntree->update)
+                               ntreeUpdateTree(ntree);
+
+               for (i=0; i < NUM_NTREE_TYPES; ++i) {
+                       ntreetype= ntreeGetType(i);
+                       if (ntreetype && ntreetype->foreach_nodetree)
+                               ntreetype->foreach_nodetree(main, NULL, lib_nodetree_do_versions_update_cb);
+               }
        }
 }
 
-
+static void direct_link_node_socket(FileData *fd, bNodeSocket *sock)
+{
+       sock->link= newdataadr(fd, sock->link);
+       sock->storage= newdataadr(fd, sock->storage);
+       sock->default_value= newdataadr(fd, sock->default_value);
+       sock->cache= NULL;
+}
 
 /* ntree itself has been read! */
 static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
@@ -2198,6 +2303,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        
        ntree->init= 0;         /* to set callbacks and force setting types */
        ntree->progress= NULL;
+       ntree->execdata= NULL;
        
        ntree->adt= newdataadr(fd, ntree->adt);
        direct_link_animdata(fd, ntree->adt);
@@ -2207,12 +2313,15 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                if(node->type == NODE_DYNAMIC) {
                        node->custom1= 0;
                        node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED);
-                       node->typeinfo= NULL;
                }
+
+               node->typeinfo= NULL;
+               
+               link_list(fd, &node->inputs);
+               link_list(fd, &node->outputs);
                
                node->storage= newdataadr(fd, node->storage);
                if(node->storage) {
-                       
                        /* could be handlerized at some point */
                        if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
                                direct_link_curvemapping(fd, node->storage);
@@ -2229,8 +2338,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
                                        ((ImageUser *)node->storage)->ok= 1;
                        }
                }
-               link_list(fd, &node->inputs);
-               link_list(fd, &node->outputs);
        }
        link_list(fd, &ntree->links);
        
@@ -2240,15 +2347,19 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
        
        /* and we connect the rest */
        for(node= ntree->nodes.first; node; node= node->next) {
+               node->parent = newdataadr(fd, node->parent);
                node->preview= newimaadr(fd, node->preview);
                node->lasty= 0;
+               
                for(sock= node->inputs.first; sock; sock= sock->next)
-                       sock->link= newdataadr(fd, sock->link);
+                       direct_link_node_socket(fd, sock);
                for(sock= node->outputs.first; sock; sock= sock->next)
-                       sock->ns.data= NULL;
+                       direct_link_node_socket(fd, sock);
        }
+       for(sock= ntree->inputs.first; sock; sock= sock->next)
+               direct_link_node_socket(fd, sock);
        for(sock= ntree->outputs.first; sock; sock= sock->next)
-               sock->link= newdataadr(fd, sock->link);
+               direct_link_node_socket(fd, sock);
        
        for(link= ntree->links.first; link; link= link->next) {
                link->fromnode= newdataadr(fd, link->fromnode);
@@ -3008,6 +3119,9 @@ static void direct_link_texture(FileData *fd, Tex *tex)
        if(tex->vd) {
                tex->vd->dataset = NULL;
                tex->vd->ok = 0;
+       } else {
+               if(tex->type == TEX_VOXELDATA)
+                       tex->vd= MEM_callocN(sizeof(VoxelData), "direct_link_texture VoxelData");
        }
        
        tex->nodetree= newdataadr(fd, tex->nodetree);
@@ -3108,7 +3222,7 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache)
                                pm->data[i] = newdataadr(fd, pm->data[i]);
                                
                                /* the cache saves non-struct data without DNA */
-                               if(pm->data[i] && strcmp(ptcache_data_struct[i], "")==0 && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
+                               if(pm->data[i] && ptcache_data_struct[i][0]=='\0' && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
                                        int j, tot= (BKE_ptcache_data_size (i) * pm->totpoint)/4; /* data_size returns bytes */
                                        int *poin= pm->data[i];
                                        
@@ -3424,6 +3538,9 @@ static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
        MTFace *tf= mtface;
        int i;
 
+       /* Add pseudo-references (not fake users!) to images used by texface. A
+          little bogus; it would be better if each mesh consistently added one ref
+          to each image it used. - z0r */
        for (i=0; i<totface; i++, tf++) {
                tf->tpage= newlibadr(fd, me->id.lib, tf->tpage);
                if(tf->tpage && tf->tpage->id.us==0)
@@ -3478,6 +3595,9 @@ static void lib_link_mesh(FileData *fd, Main *main)
                }
                me= me->id.next;
        }
+
+       /* convert texface options to material */
+       convert_tface_mt(fd, main);
 }
 
 static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
@@ -3896,6 +4016,11 @@ static void lib_link_object(FileData *fd, Main *main)
                                        arma->target= newlibadr(fd, ob->id.lib, arma->target);
                                        arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget);
                                }
+                               else if(act->type==ACT_STEERING) {
+                                       bSteeringActuator *steeringa = act->data; 
+                                       steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target);
+                                       steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh);
+                               }
                                act= act->next;
                        }
                        
@@ -3962,7 +4087,6 @@ static void direct_link_pose(FileData *fd, bPose *pose)
                        direct_link_motionpath(fd, pchan->mpath);
                
                pchan->iktree.first= pchan->iktree.last= NULL;
-               pchan->path= NULL;
                
                /* incase this value changes in future, clamp else we get undefined behavior */
                CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
@@ -4024,8 +4148,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
                        
                        fluidmd->fss= newdataadr(fd, fluidmd->fss);
-                       fluidmd->fss->fmd= fluidmd;
-                       fluidmd->fss->meshVelocities = NULL;
+                       if(fluidmd->fss) {
+                               fluidmd->fss->fmd= fluidmd;
+                               fluidmd->fss->meshVelocities = NULL;
+                       }
                }
                else if (md->type==eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData*) md;
@@ -4186,6 +4312,13 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        if(tmd->curfalloff)
                                direct_link_curvemapping(fd, tmd->curfalloff);
                }
+               else if (md->type==eModifierType_WeightVGEdit) {
+                       WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
+
+                       wmd->cmap_curve = newdataadr(fd, wmd->cmap_curve);
+                       if(wmd->cmap_curve)
+                               direct_link_curvemapping(fd, wmd->cmap_curve);
+               }
        }
 }
 
@@ -4474,7 +4607,9 @@ static void lib_link_scene(FileData *fd, Main *main)
                                seq->scene_sound = NULL;
                                if(seq->scene) {
                                        seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
-                                       seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+                                       if(seq->scene) {
+                                               seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+                                       }
                                }
                                if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera);
                                if(seq->sound) {
@@ -4501,7 +4636,7 @@ static void lib_link_scene(FileData *fd, Main *main)
 #endif
 
                        if(sce->ed)
-                               seq_update_muting(sce, sce->ed);
+                               seq_update_muting(sce->ed);
                        
                        if(sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
@@ -4904,15 +5039,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                sfile->folders_prev= NULL;
                                                sfile->folders_next= NULL;
                                        }
-                                       else if(sl->spacetype==SPACE_IMASEL) {
-                                               SpaceImaSel *simasel= (SpaceImaSel *)sl;
-
-                                               simasel->files = NULL;                                          
-                                               simasel->returnfunc= NULL;
-                                               simasel->menup= NULL;
-                                               simasel->pupmenu= NULL;
-                                               simasel->img= NULL;
-                                       }
                                        else if(sl->spacetype==SPACE_ACTION) {
                                                SpaceAction *saction= (SpaceAction *)sl;
                                                bDopeSheet *ads= &saction->ads;
@@ -4976,28 +5102,30 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        }
                                                }
                                        }
-                                       else if(sl->spacetype==SPACE_SOUND) {
-                                               SpaceSound *ssound= (SpaceSound *)sl;
-
-                                               ssound->sound= newlibadr_us(fd, sc->id.lib, ssound->sound);
-                                       }
                                        else if(sl->spacetype==SPACE_NODE) {
                                                SpaceNode *snode= (SpaceNode *)sl;
                                                
                                                snode->id= newlibadr(fd, sc->id.lib, snode->id);
+                                               snode->edittree= NULL;
                                                
-                                               /* internal data, a bit patchy */
-                                               if(snode->id) {
-                                                       if(GS(snode->id->name)==ID_MA)
-                                                               snode->nodetree= ((Material *)snode->id)->nodetree;
-                                                       else if(GS(snode->id->name)==ID_WO)
-                                                               snode->nodetree= ((World *)snode->id)->nodetree;
-                                                       else if(GS(snode->id->name)==ID_LA)
-                                                               snode->nodetree= ((Lamp *)snode->id)->nodetree;
-                                                       else if(GS(snode->id->name)==ID_SCE)
-                                                               snode->nodetree= ((Scene *)snode->id)->nodetree;
-                                                       else if(GS(snode->id->name)==ID_TE)
-                                                               snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                               if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) {
+                                                       /* internal data, a bit patchy */
+                                                       snode->nodetree= NULL;
+                                                       if(snode->id) {
+                                                               if(GS(snode->id->name)==ID_MA)
+                                                                       snode->nodetree= ((Material *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_WO)
+                                                                       snode->nodetree= ((World *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_LA)
+                                                                       snode->nodetree= ((Lamp *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_SCE)
+                                                                       snode->nodetree= ((Scene *)snode->id)->nodetree;
+                                                               else if(GS(snode->id->name)==ID_TE)
+                                                                       snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                                       }
+                                               }
+                                               else {
+                                                       snode->nodetree= newlibadr_us(fd, sc->id.lib, snode->nodetree);
                                                }
                                                
                                                snode->linkdrag.first = snode->linkdrag.last = NULL;
@@ -5144,12 +5272,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                        SpaceFile *sfile= (SpaceFile *)sl;
                                        sfile->op= NULL;
                                }
-                               else if(sl->spacetype==SPACE_IMASEL) {
-                                       SpaceImaSel *simasel= (SpaceImaSel *)sl;
-                                       if (simasel->files) {
-                                               //XXX BIF_filelist_freelib(simasel->files);
-                                       }
-                               }
                                else if(sl->spacetype==SPACE_ACTION) {
                                        SpaceAction *saction= (SpaceAction *)sl;
                                        
@@ -5216,30 +5338,25 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                                }
                                        }
                                }
-                               else if(sl->spacetype==SPACE_SOUND) {
-                                       SpaceSound *ssound= (SpaceSound *)sl;
-
-                                       ssound->sound= restore_pointer_by_name(newmain, (ID *)ssound->sound, 1);
-                               }
                                else if(sl->spacetype==SPACE_NODE) {
                                        SpaceNode *snode= (SpaceNode *)sl;
                                        
                                        snode->id= restore_pointer_by_name(newmain, snode->id, 1);
                                        snode->edittree= NULL;
                                        
-                                       if(snode->id==NULL)
+                                       if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) {
                                                snode->nodetree= NULL;
+                                               if(snode->id) {
+                                                       if(GS(snode->id->name)==ID_MA)
+                                                               snode->nodetree= ((Material *)snode->id)->nodetree;
+                                                       else if(GS(snode->id->name)==ID_SCE)
+                                                               snode->nodetree= ((Scene *)snode->id)->nodetree;
+                                                       else if(GS(snode->id->name)==ID_TE)
+                                                               snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                               }
+                                       }
                                        else {
-                                               if(GS(snode->id->name)==ID_MA)
-                                                       snode->nodetree= ((Material *)snode->id)->nodetree;
-                                               else if(GS(snode->id->name)==ID_WO)
-                                                       snode->nodetree= ((World *)snode->id)->nodetree;
-                                               else if(GS(snode->id->name)==ID_LA)
-                                                       snode->nodetree= ((Lamp *)snode->id)->nodetree;
-                                               else if(GS(snode->id->name)==ID_SCE)
-                                                       snode->nodetree= ((Scene *)snode->id)->nodetree;
-                                               else if(GS(snode->id->name)==ID_TE)
-                                                       snode->nodetree= ((Tex *)snode->id)->nodetree;
+                                               snode->nodetree= restore_pointer_by_name(newmain, &snode->nodetree->id, 1);
                                        }
                                }
                        }
@@ -5304,8 +5421,8 @@ static void view3d_split_250(View3D *v3d, ListBase *regions)
                        rv3d->persp= v3d->persp;
                        rv3d->view= v3d->view;
                        rv3d->dist= v3d->dist;
-                       VECCOPY(rv3d->ofs, v3d->ofs);
-                       QUATCOPY(rv3d->viewquat, v3d->viewquat);
+                       copy_v3_v3(rv3d->ofs, v3d->ofs);
+                       copy_qt_qt(rv3d->viewquat, v3d->viewquat);
                }
        }
 
@@ -5413,6 +5530,10 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                v3d->afterdraw_xray.first= v3d->afterdraw_xray.last= NULL;
                                v3d->afterdraw_xraytransp.first= v3d->afterdraw_xraytransp.last= NULL;
                                v3d->properties_storage= NULL;
+
+                               /* render can be quite heavy, set to wire on load */
+                               if(v3d->drawtype == OB_RENDER)
+                                       v3d->drawtype = OB_WIRE;
                                
                                view3d_split_250(v3d, &sl->regionbase);
                        }
@@ -5469,7 +5590,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        snode->gpd= newdataadr(fd, snode->gpd);
                                        direct_link_gpencil(fd, snode->gpd);
                                }
-                               snode->nodetree= snode->edittree= NULL;
                        }
                        else if(sl->spacetype==SPACE_TIME) {
                                SpaceTime *stime= (SpaceTime *)sl;
@@ -5604,7 +5724,7 @@ static void fix_relpaths_library(const char *basepath, Main *main)
                         * link into an unsaved blend file. See [#27405].
                         * The remap relative option will make it relative again on save - campbell */
                        if (strncmp(lib->name, "//", 2)==0) {
-                               strncpy(lib->name, lib->filepath, sizeof(lib->name));
+                               BLI_strncpy(lib->name, lib->filepath, sizeof(lib->name));
                        }
                }
        }
@@ -5613,19 +5733,58 @@ static void fix_relpaths_library(const char *basepath, Main *main)
                        /* Libraries store both relative and abs paths, recreate relative paths,
                         * relative to the blend file since indirectly linked libs will be relative to their direct linked library */
                        if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */
-                               strncpy(lib->name, lib->filepath, sizeof(lib->name));
+                               BLI_strncpy(lib->name, lib->filepath, sizeof(lib->name));
                                BLI_path_rel(lib->name, basepath);
                        }
                }
        }
 }
 
+/* ************ READ SPEAKER ***************** */
+
+static void lib_link_speaker(FileData *fd, Main *main)
+{
+       Speaker *spk;
+
+       spk= main->speaker.first;
+       while(spk) {
+               if(spk->id.flag & LIB_NEEDLINK) {
+                       if (spk->adt) lib_link_animdata(fd, &spk->id, spk->adt);
+
+                       spk->sound= newlibadr(fd, spk->id.lib, spk->sound);
+                       if (spk->sound) {
+                               spk->sound->id.us++;
+                       }
+
+                       spk->id.flag -= LIB_NEEDLINK;
+               }
+               spk= spk->id.next;
+       }
+}
+
+static void direct_link_speaker(FileData *fd, Speaker *spk)
+{
+       spk->adt= newdataadr(fd, spk->adt);
+       direct_link_animdata(fd, spk->adt);
+
+       /*spk->sound= newdataadr(fd, spk->sound);
+       direct_link_sound(fd, spk->sound);*/
+}
+
 /* ************** READ SOUND ******************* */
 
 static void direct_link_sound(FileData *fd, bSound *sound)
 {
        sound->handle = NULL;
        sound->playback_handle = NULL;
+       sound->waveform = NULL;
+
+       // versioning stuff, if there was a cache, then we enable caching:
+       if(sound->cache)
+       {
+               sound->flags |= SOUND_FLAGS_CACHING;
+               sound->cache = NULL;
+       }
 
        sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
        sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
@@ -5642,9 +5801,6 @@ static void lib_link_sound(FileData *fd, Main *main)
                        sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
                        
                        sound_load(main, sound);
-
-                       if(sound->cache)
-                               sound_cache(sound, 1);
                }
                sound= sound->id.next;
        }
@@ -5715,6 +5871,7 @@ static const char *dataname(short id_code)
                case ID_SCR: return "Data from SCR";
                case ID_VF: return "Data from VF";
                case ID_TXT     : return "Data from TXT";
+               case ID_SPK: return "Data from SPK";
                case ID_SO: return "Data from SO";
                case ID_NT: return "Data from NT";
                case ID_BR: return "Data from BR";
@@ -5859,6 +6016,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                case ID_CA:
                        direct_link_camera(fd, (Camera *)id);
                        break;
+               case ID_SPK:
+                       direct_link_speaker(fd, (Speaker *)id);
+                       break;
                case ID_SO:
                        direct_link_sound(fd, (bSound *)id);
                        break;
@@ -6315,7 +6475,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
        /* if we do, set alpha sort if the game engine did it before */
        for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
                if(mf->mat_nr < me->totcol) {
-                       ma= newlibadr(fd, lib, me->mat[(int)mf->mat_nr]);
+                       ma= newlibadr(fd, lib, me->mat[mf->mat_nr]);
                        texalpha = 0;
 
                        /* we can't read from this if it comes from a library,
@@ -6571,16 +6731,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                //ar->v2d.flag |= V2D_IS_INITIALISED;
                                break;
                        }
-                       case SPACE_SOUND:
-                       {
-                               SpaceSound *ssound= (SpaceSound *)sl;
-                               memcpy(&ar->v2d, &ssound->v2d, sizeof(View2D));
-                               
-                               ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
-                               ar->v2d.scroll |= (V2D_SCROLL_LEFT);
-                               //ar->v2d.flag |= V2D_IS_INITIALISED;
-                               break;
-                       }
                        case SPACE_NLA:
                        {
                                SpaceNla *snla= (SpaceNla *)sl;
@@ -6696,11 +6846,17 @@ static void do_versions_windowmanager_2_50(bScreen *screen)
                
                area_add_window_regions(sa, sa->spacedata.first, &sa->regionbase);
                
-               /* space imageselect is depricated */
+               /* space imageselect is deprecated */
                for(sl= sa->spacedata.first; sl; sl= sl->next) {
                        if(sl->spacetype==SPACE_IMASEL)
-                               sl->spacetype= SPACE_INFO;      /* spacedata then matches */
-               }               
+                               sl->spacetype= SPACE_EMPTY;     /* spacedata then matches */
+               }
+               
+               /* space sound is deprecated */
+               for(sl= sa->spacedata.first; sl; sl= sl->next) {
+                       if(sl->spacetype==SPACE_SOUND)
+                               sl->spacetype= SPACE_EMPTY;     /* spacedata then matches */
+               }
                
                /* it seems to be possible in 2.5 to have this saved, filewindow probably */
                sa->butspacetype= sa->spacetype;
@@ -6939,6 +7095,157 @@ static void do_version_bone_roll_256(Bone *bone)
                do_version_bone_roll_256(child);
 }
 
+static void do_versions_socket_default_value(bNodeSocket *sock)
+{
+       bNodeSocketValueFloat *valfloat;
+       bNodeSocketValueVector *valvector;
+       bNodeSocketValueRGBA *valrgba;
+       
+       if (sock->default_value)
+               return;
+       
+       switch (sock->type) {
+       case SOCK_FLOAT:
+               valfloat = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueFloat), "default socket value");
+               valfloat->value = sock->ns.vec[0];
+               valfloat->min = sock->ns.min;
+               valfloat->max = sock->ns.max;
+               valfloat->subtype = PROP_NONE;
+               break;
+       case SOCK_VECTOR:
+               valvector = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueVector), "default socket value");
+               copy_v3_v3(valvector->value, sock->ns.vec);
+               valvector->min = sock->ns.min;
+               valvector->max = sock->ns.max;
+               valvector->subtype = PROP_NONE;
+               break;
+       case SOCK_RGBA:
+               valrgba = sock->default_value = MEM_callocN(sizeof(bNodeSocketValueRGBA), "default socket value");
+               copy_v4_v4(valrgba->value, sock->ns.vec);
+               break;
+       }
+}
+
+static void do_versions_nodetree_default_value(bNodeTree *ntree)
+{
+       bNode *node;
+       bNodeSocket *sock;
+       for (node=ntree->nodes.first; node; node=node->next) {
+               for (sock=node->inputs.first; sock; sock=sock->next)
+                       do_versions_socket_default_value(sock);
+               for (sock=node->outputs.first; sock; sock=sock->next)
+                       do_versions_socket_default_value(sock);
+       }
+       for (sock=ntree->inputs.first; sock; sock=sock->next)
+               do_versions_socket_default_value(sock);
+       for (sock=ntree->outputs.first; sock; sock=sock->next)
+               do_versions_socket_default_value(sock);
+}
+
+static void do_versions_nodetree_clear_dynamic_sockets(bNodeTree *ntree)
+{
+       /* conflict with cycles flag .. */
+       bNodeSocket *sock;
+
+       for (sock=ntree->inputs.first; sock; sock=sock->next) {
+               if (sock->flag & SOCK_DYNAMIC) {
+                       sock->flag &= ~SOCK_DYNAMIC;
+                       sock->flag |= SOCK_COLLAPSED;
+               }
+       }
+       for (sock=ntree->outputs.first; sock; sock=sock->next) {
+               if (sock->flag & SOCK_DYNAMIC) {
+                       sock->flag &= ~SOCK_DYNAMIC;
+                       sock->flag |= SOCK_COLLAPSED;
+               }
+       }
+}
+
+static void do_versions_nodetree_dynamic_sockets(bNodeTree *ntree)
+{
+       bNodeSocket *sock;
+       for (sock=ntree->inputs.first; sock; sock=sock->next) {
+               if(sock->flag & SOCK_DYNAMIC)
+                       sock->flag |= SOCK_COLLAPSED;
+               else
+                       sock->flag |= SOCK_DYNAMIC;
+       }
+       for (sock=ntree->outputs.first; sock; sock=sock->next) {
+               if(sock->flag & SOCK_DYNAMIC)
+                       sock->flag |= SOCK_COLLAPSED;
+               else
+                       sock->flag |= SOCK_DYNAMIC;
+       }
+}
+
+void convert_tface_mt(FileData *fd, Main *main)
+{
+       Main *gmain;
+
+       /* this is a delayed do_version (so it can create new materials) */
+       if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) {
+
+               //XXX hack, material.c uses G.main all over the place, instead of main
+               // temporarily set G.main to the current main
+               gmain = G.main;
+               G.main = main;
+
+               if(!(do_version_tface(main, 1))) {
+                       BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem. Error in console");
+               }
+
+               //XXX hack, material.c uses G.main allover the place, instead of main
+               G.main = gmain;
+       }
+}
+
+static void do_versions_nodetree_image_default_alpha_output(bNodeTree *ntree)
+{
+       bNode *node;
+       bNodeSocket *sock;
+       for (node=ntree->nodes.first; node; node=node->next) {
+               if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) {
+                       /* default Image output value should have 0 alpha */
+                       sock = node->outputs.first;
+                       ((bNodeSocketValueRGBA*)sock->default_value)->value[3] = 0.0f;
+               }
+       }
+}
+
+static void do_version_ntree_tex_mapping_260(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       bNode *node;
+
+       for(node=ntree->nodes.first; node; node=node->next) {
+               TexMapping *tex_mapping= NULL;
+               ColorMapping *color_mapping= NULL;
+
+               if(node->type == SH_NODE_MAPPING) {
+                       tex_mapping= node->storage;
+                       tex_mapping->projx= PROJ_X;
+                       tex_mapping->projy= PROJ_Y;
+                       tex_mapping->projz= PROJ_Z;
+               }
+               else if(ELEM7(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_NOISE, SH_NODE_TEX_SKY,
+                       SH_NODE_TEX_BLEND, SH_NODE_TEX_VORONOI, SH_NODE_TEX_MAGIC, SH_NODE_TEX_MARBLE) ||
+                       ELEM6(node->type, SH_NODE_TEX_CLOUDS, SH_NODE_TEX_WOOD, SH_NODE_TEX_MUSGRAVE,
+                       SH_NODE_TEX_STUCCI, SH_NODE_TEX_DISTNOISE, SH_NODE_TEX_ENVIRONMENT)) {
+                       NodeTexBase *base= node->storage;
+
+                       if(node->type == SH_NODE_TEX_NOISE)
+                               node->storage= MEM_callocN(sizeof(NodeTexNoise), "NodeTexNoise");
+
+                       tex_mapping= &base->tex_mapping;
+                       color_mapping= &base->color_mapping;
+
+                       if(is_zero_v3(tex_mapping->size)) {
+                               default_tex_mapping(tex_mapping);
+                               default_color_mapping(color_mapping);
+                       }
+               }
+       }
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -8519,7 +8826,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                
                for (wo = main->world.first; wo; wo= wo->id.next) {
                        /* Migrate to Bullet for games, except for the NaN versions */
-                       /* People can still explicitely choose for Sumo (after 2.42 is out) */
+                       /* People can still explicitly choose for Sumo (after 2.42 is out) */
                        if(main->versionfile > 225)
                                wo->physicsEngine = WOPHY_BULLET;
                        if(WO_AODIST == wo->aomode)
@@ -9010,7 +9317,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
        if(main->versionfile <= 245) {
                Scene *sce;
-               bScreen *sc;
                Object *ob;
                Image *ima;
                Lamp *la;
@@ -9100,49 +9406,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        for(ima= main->image.first; ima; ima= ima->id.next) {
                                ima->preview = NULL;
                        }
-                       
-                       /* repair imasel space - completely reworked */
-                       for(sc= main->screen.first; sc; sc= sc->id.next) {
-                               ScrArea *sa;
-                               sa= sc->areabase.first;
-                               while(sa) {
-                                       SpaceLink *sl;
-                                       
-                                       for (sl= sa->spacedata.first; sl; sl= sl->next) {
-                                               if(sl->spacetype==SPACE_IMASEL) {
-                                                       SpaceImaSel *simasel= (SpaceImaSel*) sl;
-                                                       simasel->blockscale= 0.7f;
-                                                       /* view 2D */
-                                                       simasel->v2d.tot.xmin=  -10.0f;
-                                                       simasel->v2d.tot.ymin=  -10.0f;
-                                                       simasel->v2d.tot.xmax= (float)sa->winx + 10.0f;
-                                                       simasel->v2d.tot.ymax= (float)sa->winy + 10.0f;                                         
-                                                       simasel->v2d.cur.xmin=  0.0f;
-                                                       simasel->v2d.cur.ymin=  0.0f;
-                                                       simasel->v2d.cur.xmax= (float)sa->winx;
-                                                       simasel->v2d.cur.ymax= (float)sa->winy;                                         
-                                                       simasel->v2d.min[0]= 1.0;
-                                                       simasel->v2d.min[1]= 1.0;                                               
-                                                       simasel->v2d.max[0]= 32000.0f;
-                                                       simasel->v2d.max[1]= 32000.0f;                                          
-                                                       simasel->v2d.minzoom= 0.5f;
-                                                       simasel->v2d.maxzoom= 1.21f;                                            
-                                                       simasel->v2d.scroll= 0;
-                                                       simasel->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
-                                                       simasel->v2d.keeptot= 0;
-                                                       simasel->prv_h = 96;
-                                                       simasel->prv_w = 96;
-                                                       simasel->flag = 7; /* ??? elubie */
-                                                       strcpy (simasel->dir,  U.textudir);     /* TON */
-                                                       strcpy (simasel->file, "");
-                                                       
-                                                       simasel->returnfunc     =  NULL;
-                                                       simasel->title[0]       =  0;
-                                               }
-                                       }
-                                       sa = sa->next;
-                               }
-                       }
                }
 
                /* add point caches */
@@ -9356,7 +9619,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
                                                                
                                                                ct->tar = data->tar;
-                                                               strcpy(ct->subtarget, data->subtarget);
+                                                               BLI_strncpy(ct->subtarget, data->subtarget, sizeof(ct->subtarget));
                                                                ct->space = con->tarspace;
                                                                
                                                                BLI_addtail(&data->targets, ct);
@@ -9364,7 +9627,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                                
                                                                /* clear old targets to avoid problems */
                                                                data->tar = NULL;
-                                                               strcpy(data->subtarget, "");
+                                                               data->subtarget[0]= '\0';
                                                        }
                                                }
                                                else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
@@ -9386,7 +9649,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
                                                
                                                ct->tar = data->tar;
-                                               strcpy(ct->subtarget, data->subtarget);
+                                               BLI_strncpy(ct->subtarget, data->subtarget, sizeof(ct->subtarget));
                                                ct->space = con->tarspace;
                                                
                                                BLI_addtail(&data->targets, ct);
@@ -9394,7 +9657,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                
                                                /* clear old targets to avoid problems */
                                                data->tar = NULL;
-                                               strcpy(data->subtarget, "");
+                                               data->subtarget[0]= '\0';
                                        }
                                }
                                else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
@@ -9858,7 +10121,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        sce->toolsettings->skgen_resolution = 250;
                        sce->toolsettings->skgen_threshold_internal     = 0.1f;
                        sce->toolsettings->skgen_threshold_external     = 0.1f;
-                       sce->toolsettings->skgen_angle_limit                    = 30.0f;
+                       sce->toolsettings->skgen_angle_limit                    = 30.0f;
                        sce->toolsettings->skgen_length_ratio                   = 1.3f;
                        sce->toolsettings->skgen_length_limit                   = 1.5f;
                        sce->toolsettings->skgen_correlation_limit              = 0.98f;
@@ -10000,12 +10263,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        if(ed) {
                                SEQP_BEGIN(ed, seq) {
                                        if (seq->strip && seq->strip->proxy){
-                                               if (sce->r.size != 100.0) {
-                                                       seq->strip->proxy->size
-                                                               = sce->r.size;
-                                               } else {
-                                                       seq->strip->proxy->size = 25;
-                                               }
                                                seq->strip->proxy->quality =90;
                                        }
                                }
@@ -10079,8 +10336,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                {
                        if(scene->ed && scene->ed->seqbasep)
                        {
-                               for(seq = scene->ed->seqbasep->first; seq; seq = seq->next)
-                               {
+                               SEQ_BEGIN(scene->ed, seq) {
                                        if(seq->type == SEQ_HD_SOUND)
                                        {
                                                char str[FILE_MAX];
@@ -10095,11 +10351,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                           !(seq->flag & SEQ_USE_PROXY_CUSTOM_DIR))
                                        {
                                                
-                                               snprintf(seq->strip->proxy->dir, 
+                                               BLI_snprintf(seq->strip->proxy->dir, 
                                                         FILE_MAXDIR, "%s/BL_proxy", 
                                                         seq->strip->dir);
                                        }
                                }
+                               SEQ_END
                        }
                }
 
@@ -10112,7 +10369,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                 * to have them show in RNA viewer and accessible otherwise.
                 */
                for(ma= main->mat.first; ma; ma= ma->id.next) {
-                       if(ma->nodetree && strlen(ma->nodetree->id.name)==0)
+                       if(ma->nodetree && ma->nodetree->id.name[0] == '\0')
                                strcpy(ma->nodetree->id.name, "NTShader Nodetree");
                        
                        /* which_output 0 is now "not specified" */
@@ -10126,7 +10383,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
                /* and composit trees */
                for(sce= main->scene.first; sce; sce= sce->id.next) {
-                       if(sce->nodetree && strlen(sce->nodetree->id.name)==0)
+                       if(sce->nodetree && sce->nodetree->id.name[0] == '\0')
                                strcpy(sce->nodetree->id.name, "NTCompositing Nodetree");
 
                        /* move to cameras */
@@ -10148,7 +10405,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        bNode *node;
 
                        if(tx->nodetree) {
-                               if(strlen(tx->nodetree->id.name)==0)
+                               if(tx->nodetree->id.name[0] == '\0')
                                        strcpy(tx->nodetree->id.name, "NTTexture Nodetree");
 
                                /* which_output 0 is now "not specified" */
@@ -10263,7 +10520,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                ma->mode |= MA_TRANSP;
                        }
                        else {
-                               ma->mode |= MA_ZTRANSP;
+                               /* ma->mode |= MA_ZTRANSP; */ /* leave ztransp as is even if its not used [#28113] */
                                ma->mode &= ~MA_TRANSP;
                        }
 
@@ -11528,6 +11785,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
        
+       // init facing axis property of steering actuators
+       {                                       
+               Object *ob;
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       bActuator *act;
+                       for(act= ob->actuators.first; act; act= act->next) {
+                               if(act->type==ACT_STEERING) {
+                                       bSteeringActuator* stact = act->data;
+                                       if (stact->facingaxis==0)
+                                       {
+                                               stact->facingaxis=1;
+                                       }                                               
+                               }
+                       }
+               }
+       }
+       
        if (main->versionfile < 256) {
                bScreen *sc;
                ScrArea *sa;
@@ -11596,7 +11870,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                         * is done in lib_verify_nodetree, because at this point the internal
                         * nodes may not be up-to-date! (missing lib-link)
                         */
-                       ntree->flag |= NTREE_DO_VERSIONS;
+                       ntree->flag |= NTREE_DO_VERSIONS_GROUP_EXPOSE;
                }
        }
 
@@ -11617,7 +11891,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        if(!mat->mtex[tex_nr]) continue;
                                        if(mat->mtex[tex_nr]->mapto & MAP_ALPHA) transp_tex= 1;
                                }
-                               
+
+                               /* weak! material alpha could be animated */
                                if(mat->alpha < 1.0f || mat->fresnel_tra > 0.0f || transp_tex){
                                        mat->mode |= MA_TRANSP;
                                        mat->mode &= ~(MA_ZTRANSP|MA_RAYTRANSP);
@@ -11721,10 +11996,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                if(tex->pd) {
                                        if (tex->pd->falloff_speed_scale == 0.0f)
                                                tex->pd->falloff_speed_scale = 100.0f;
-
+                                       
                                        if (!tex->pd->falloff_curve) {
                                                tex->pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1);
-
+                                               
                                                tex->pd->falloff_curve->preset = CURVE_PRESET_LINE;
                                                tex->pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
                                                curvemap_reset(tex->pd->falloff_curve->cm, &tex->pd->falloff_curve->clipr, tex->pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
@@ -11757,13 +12032,361 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
-       
-       /* put compatibility code here until next subversion bump */
 
+       if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 1)){
+               {
+                       Scene *scene;
+                       Sequence *seq;
+
+                       for (scene=main->scene.first; scene; scene=scene->id.next)
+                       {
+                               scene->r.ffcodecdata.audio_channels = 2;
+                               scene->audio.volume = 1.0f;
+                               SEQ_BEGIN(scene->ed, seq) {
+                                       seq->pitch = 1.0f;
+                               }
+                               SEQ_END
+                       }
+               }
+               {
+                       bScreen *screen;
+                       for(screen= main->screen.first; screen; screen= screen->id.next) {
+                               ScrArea *sa;
+                               /* add regions */
+                               for(sa= screen->areabase.first; sa; sa= sa->next) {
+                                       SpaceLink *sl= sa->spacedata.first;
+                                       if(sl->spacetype==SPACE_SEQ) {
+                                               ARegion *ar;
+                                               for (ar=sa->regionbase.first; ar; ar= ar->next) {
+                                                       if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                                               if(ar->v2d.min[1] == 4.0f)
+                                                                       ar->v2d.min[1]= 0.5f;
+                                                       }
+                                               }
+                                       }
+                                       for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                               if(sl->spacetype==SPACE_SEQ) {
+                                                       ARegion *ar;
+                                                       for (ar=sl->regionbase.first; ar; ar= ar->next) {
+                                                               if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                                                       if(ar->v2d.min[1] == 4.0f)
+                                                                               ar->v2d.min[1]= 0.5f;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               {
+                       /* Make "auto-clamped" handles a per-keyframe setting instead of per-FCurve 
+                        *
+                        * We're only patching F-Curves in Actions here, since it is assumed that most
+                        * drivers out there won't be using this (and if they are, they're in the minority).
+                        * While we should aim to fix everything ideally, in practice it's far too hard
+                        * to get to every animdata block, not to mention the performance hit that'd have
+                        */
+                       bAction *act;
+                       FCurve *fcu;
+                       
+                       for (act = main->action.first; act; act = act->id.next) {
+                               for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+                                       BezTriple *bezt;
+                                       unsigned int i = 0;
+                                       
+                                       /* only need to touch curves that had this flag set */
+                                       if ((fcu->flag & FCURVE_AUTO_HANDLES) == 0)
+                                               continue;
+                                       if ((fcu->totvert == 0) || (fcu->bezt == NULL))
+                                               continue;
+                                               
+                                       /* only change auto-handles to auto-clamped */
+                                       for (bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+                                               if (bezt->h1 == HD_AUTO) bezt->h1 = HD_AUTO_ANIM;
+                                               if (bezt->h2 == HD_AUTO) bezt->h2 = HD_AUTO_ANIM;
+                                       }
+                                       
+                                       fcu->flag &= ~FCURVE_AUTO_HANDLES;
+                               }
+                       }
+               }
+               {
+                       /* convert fcurve and shape action actuators to action actuators */
+                       Object *ob;
+                       bActuator *act;
+                       bIpoActuator *ia;
+                       bActionActuator *aa;
+
+                       for (ob= main->object.first; ob; ob= ob->id.next) {
+                               for (act= ob->actuators.first; act; act= act->next) {
+                                       if (act->type == ACT_IPO) {
+                                               // Create the new actuator
+                                               ia= act->data;
+                                               aa= MEM_callocN(sizeof(bActionActuator), "fcurve -> action actuator do_version");
+
+                                               // Copy values
+                                               aa->type = ia->type;
+                                               aa->flag = ia->flag;
+                                               aa->sta = ia->sta;
+                                               aa->end = ia->end;
+                                               BLI_strncpy(aa->name, ia->name, sizeof(aa->name));
+                                               BLI_strncpy(aa->frameProp, ia->frameProp, sizeof(aa->frameProp));
+                                               if (ob->adt)
+                                                       aa->act = ob->adt->action;
+
+                                               // Get rid of the old actuator
+                                               MEM_freeN(ia);
+
+                                               // Assign the new actuator
+                                               act->data = aa;
+                                               act->type= act->otype= ACT_ACTION;
+                                               
+                                       }
+                                       else if (act->type == ACT_SHAPEACTION)  {
+                                               act->type = act->otype = ACT_ACTION;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 2)){
+               {
+                       /* Convert default socket values from bNodeStack */
+                       Scene *sce;
+                       Material *mat;
+                       Lamp *la;
+                       Tex *tex;
+                       bNodeTree *ntree;
+                       World *wo;
+
+                       for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
+                               do_versions_nodetree_default_value(ntree);
+                               ntree->update |= NTREE_UPDATE;
+                       }
+                       for (sce=main->scene.first; sce; sce=sce->id.next)
+                               if (sce->nodetree) {
+                               do_versions_nodetree_clear_dynamic_sockets(sce->nodetree);
+                               do_versions_nodetree_default_value(sce->nodetree);
+                               sce->nodetree->update |= NTREE_UPDATE;
+                       }
+                       for (mat=main->mat.first; mat; mat=mat->id.next)
+                               if (mat->nodetree) {
+                               do_versions_nodetree_clear_dynamic_sockets(mat->nodetree);
+                               do_versions_nodetree_default_value(mat->nodetree);
+                               mat->nodetree->update |= NTREE_UPDATE;
+                       }
+                       for (la=main->lamp.first; la; la=la->id.next)
+                               if (la->nodetree) {
+                               do_versions_nodetree_clear_dynamic_sockets(la->nodetree);
+                               do_versions_nodetree_default_value(la->nodetree);
+                               la->nodetree->update |= NTREE_UPDATE;
+                       }
+                       for (wo=main->world.first; wo; wo=wo->id.next)
+                               if (wo->nodetree) {
+                               do_versions_nodetree_clear_dynamic_sockets(wo->nodetree);
+                               do_versions_nodetree_default_value(wo->nodetree);
+                               wo->nodetree->update |= NTREE_UPDATE;
+                       }
+                       for (tex=main->tex.first; tex; tex=tex->id.next)
+                               if (tex->nodetree) {
+                               do_versions_nodetree_clear_dynamic_sockets(tex->nodetree);
+                               do_versions_nodetree_default_value(tex->nodetree);
+                               tex->nodetree->update |= NTREE_UPDATE;
+                       }
+               }
+
+               /* add SOCK_DYNAMIC flag to existing group sockets */
+               {
+                       bNodeTree *ntree;
+                       /* only need to do this for trees in main, local trees are not used as groups */
+                       for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) {
+                               do_versions_nodetree_dynamic_sockets(ntree);
+                               ntree->update |= NTREE_UPDATE;
+                       }
+               }
+
+               {
+                       /* Initialize group tree nodetypes.
+                        * These are used to distinguish tree types and
+                        * associate them with specific node types for polling.
+                        */
+                       bNodeTree *ntree;
+                       /* all node trees in main->nodetree are considered groups */
+                       for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+                               ntree->nodetype = NODE_GROUP;
+               }
+       }
+
+       if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 4)){
+               {
+                       /* Adaptive time step for particle systems */
+                       ParticleSettings *part;
+                       for (part = main->particle.first; part; part = part->id.next) {
+                               part->courant_target = 0.2f;
+                               part->time_flag &= ~PART_TIME_AUTOSF;
+                       }
+               }
+
+               {
+                       /* set defaults for obstacle avoidance, recast data */
+                       Scene *sce;
+                       for(sce = main->scene.first; sce; sce = sce->id.next)
+                       {
+                               if (sce->gm.levelHeight == 0.f)
+                                       sce->gm.levelHeight = 2.f;
+
+                               if(sce->gm.recastData.cellsize == 0.0f)
+                                       sce->gm.recastData.cellsize = 0.3f;
+                               if(sce->gm.recastData.cellheight == 0.0f)
+                                       sce->gm.recastData.cellheight = 0.2f;
+                               if(sce->gm.recastData.agentmaxslope == 0.0f)
+                                       sce->gm.recastData.agentmaxslope = (float)M_PI/4;
+                               if(sce->gm.recastData.agentmaxclimb == 0.0f)
+                                       sce->gm.recastData.agentmaxclimb = 0.9f;
+                               if(sce->gm.recastData.agentheight == 0.0f)
+                                       sce->gm.recastData.agentheight = 2.0f;
+                               if(sce->gm.recastData.agentradius == 0.0f)
+                                       sce->gm.recastData.agentradius = 0.6f;
+                               if(sce->gm.recastData.edgemaxlen == 0.0f)
+                                       sce->gm.recastData.edgemaxlen = 12.0f;
+                               if(sce->gm.recastData.edgemaxerror == 0.0f)
+                                       sce->gm.recastData.edgemaxerror = 1.3f;
+                               if(sce->gm.recastData.regionminsize == 0.0f)
+                                       sce->gm.recastData.regionminsize = 8.f;
+                               if(sce->gm.recastData.regionmergesize == 0.0f)
+                                       sce->gm.recastData.regionmergesize = 20.f;
+                               if(sce->gm.recastData.vertsperpoly<3)
+                                       sce->gm.recastData.vertsperpoly = 6;
+                               if(sce->gm.recastData.detailsampledist == 0.0f)
+                                       sce->gm.recastData.detailsampledist = 6.0f;
+                               if(sce->gm.recastData.detailsamplemaxerror == 0.0f)
+                                       sce->gm.recastData.detailsamplemaxerror = 1.0f;
+                       }
+               }
+
+               {
+                       /* flip normals */
+                       Material *ma= main->mat.first;
+                       while(ma) {
+                               int a;
+                               for(a= 0; a<MAX_MTEX; a++) {
+                                       MTex *mtex= ma->mtex[a];
+
+                                       if(mtex) {
+                                               if((mtex->texflag&MTEX_BUMP_FLIPPED)==0) {
+                                                       if((mtex->mapto&MAP_DISPLACE)==0) {
+                                                               if((mtex->mapto&MAP_NORM) && mtex->texflag&(MTEX_COMPAT_BUMP|MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) {
+                                                                       Tex *tex= newlibadr(fd, lib, mtex->tex);
+
+                                                                       if(!tex || (tex->imaflag&TEX_NORMALMAP)==0) {
+                                                                               mtex->norfac= -mtex->norfac;
+                                                                               mtex->texflag|= MTEX_BUMP_FLIPPED;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               ma= ma->id.next;
+                       }
+               }
+
+       }
+
+       if(main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 5)) {
+               Scene *sce;
+               Base *base;
+               Material *ma;
+
+               /* compatibility tweak */
+               for(sce = main->scene.first; sce; sce = sce->id.next) {
+                       if(strcmp(sce->r.engine, "CYCLES") == 0) {
+                               for(base = sce->base.first; base; base=base->next) {
+                                       Object *ob= newlibadr(fd, lib, base->object);
+
+                                       if(ob && ob->type == OB_LAMP) {
+                                               Lamp *la= newlibadr(fd, lib, ob->data);
+                                               if(la)
+                                                       la->area_size= 0.0f;
+                                       }
+                               }
+                       }
+               }
+
+               for(ma = main->mat.first; ma; ma= ma->id.next)
+                       if(ma->nodetree)
+                               ntree_tmp_cycles_emission_version_patch(fd, lib, ma->nodetree);
+       }
+
+       if (main->versionfile < 260){
+               {
+                       /* set default alpha value of Image outputs in image and render layer nodes to 0 */
+                       Scene *sce;
+                       bNodeTree *ntree;
+                       
+                       for (sce=main->scene.first; sce; sce=sce->id.next) {
+                               /* there are files with invalid audio_channels value, the real cause
+                                  is unknown, but we fix it here anyway to avoid crashes */
+                               if(sce->r.ffcodecdata.audio_channels == 0)
+                                       sce->r.ffcodecdata.audio_channels = 2;
+
+                               if (sce->nodetree)
+                                       do_versions_nodetree_image_default_alpha_output(sce->nodetree);
+                       }
+
+                       for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+                               do_versions_nodetree_image_default_alpha_output(ntree);
+               }
+
+               {
+                       /* support old particle dupliobject rotation settings */
+                       ParticleSettings *part;
+
+                       for (part=main->particle.first; part; part=part->id.next) {
+                               if(ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
+                                       part->draw |= PART_DRAW_ROTATE_OB;
+
+                                       if(part->rotmode == 0)
+                                               part->rotmode = PART_ROT_VEL;
+                               }
+                       }
+               }
+
+       }
+
+       if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)){
+               Object *ob;
+
+               for (ob= main->object.first; ob; ob= ob->id.next) {
+                       ob->collision_boundtype= ob->boundtype;
+               }
+
+               {
+                       Camera *cam;
+                       for(cam= main->camera.first; cam; cam= cam->id.next) {
+                               if (cam->sensor_x < 0.01)
+                                       cam->sensor_x = DEFAULT_SENSOR_WIDTH;
+
+                               if (cam->sensor_y < 0.01)
+                                       cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
+                       }
+               }
+
+               {
+                       bNodeTreeType *ntreetype= ntreeGetType(NTREE_SHADER);
+
+                       if(ntreetype && ntreetype->foreach_nodetree)
+                               ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_mapping_260);
+               }
+       }
+
+       /* put compatibility code here until next subversion bump */
        {
-       
+               
        }
-       
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
 
@@ -11799,6 +12422,7 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_latt(fd, main);
        lib_link_text(fd, main);
        lib_link_camera(fd, main);
+       lib_link_speaker(fd, main);
        lib_link_sound(fd, main);
        lib_link_group(fd, main);
        lib_link_armature(fd, main);
@@ -11884,13 +12508,13 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
        BlendFileData *bfd;
 
        bfd= MEM_callocN(sizeof(BlendFileData), "blendfiledata");
-       bfd->main= MEM_callocN(sizeof(Main), "main");
+       bfd->main= MEM_callocN(sizeof(Main), "readfile_Main");
        BLI_addtail(&fd->mainlist, bfd->main);
 
        bfd->main->versionfile= fd->fileversion;
        
        bfd->type= BLENFILETYPE_BLEND;
-       strncpy(bfd->main->name, filepath, sizeof(bfd->main->name)-1);
+       BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name));
 
        while(bhead) {
                switch(bhead->code) {
@@ -12673,6 +13297,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bArmatureActuator *arma= act->data;
                        expand_doit(fd, mainvar, arma->target);
                }
+               else if(act->type==ACT_STEERING) {
+                       bSteeringActuator *sta= act->data;
+                       expand_doit(fd, mainvar, sta->target);
+                       expand_doit(fd, mainvar, sta->navmesh);
+               }
                act= act->next;
        }
 
@@ -12745,6 +13374,14 @@ static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
                expand_animdata(fd, mainvar, ca->adt);
 }
 
+static void expand_speaker(FileData *fd, Main *mainvar, Speaker *spk)
+{
+       expand_doit(fd, mainvar, spk->sound);
+
+       if (spk->adt)
+               expand_animdata(fd, mainvar, spk->adt);
+}
+
 static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
 {
        expand_doit(fd, mainvar, snd->ipo); // XXX depreceated - old animation system
@@ -12807,6 +13444,9 @@ static void expand_main(FileData *fd, Main *mainvar)
                                        case ID_CA:
                                                expand_camera(fd, mainvar, (Camera *)id);
                                                break;
+                                       case ID_SPK:
+                                               expand_speaker(fd, mainvar,(Speaker *)id);
+                                               break;
                                        case ID_SO:
                                                expand_sound(fd, mainvar, (bSound *)id);
                                                break;
@@ -12864,7 +13504,7 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
                if( ob->id.flag & LIB_INDIRECT ) {
                        
                                /* IF below is quite confusing!
-                               if we are appending, but this object wasnt just added allong with a group,
+                               if we are appending, but this object wasnt just added along with a group,
                                then this is already used indirectly in the scene somewhere else and we didnt just append it.
                                
                                (ob->id.flag & LIB_PRE_EXISTING)==0 means that this is a newly appended object - Campbell */
@@ -13212,8 +13852,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                                                        printf("  enter a new path:\n");
 
                                                        if(scanf("%s", newlib_path) > 0) {
-                                                               strcpy(mainptr->curlib->name, newlib_path);
-                                                               strcpy(mainptr->curlib->filepath, newlib_path);
+                                                               BLI_strncpy(mainptr->curlib->name, newlib_path, sizeof(mainptr->curlib->name));
+                                                               BLI_strncpy(mainptr->curlib->filepath, newlib_path, sizeof(mainptr->curlib->filepath));
                                                                cleanup_path(G.main->name, mainptr->curlib->filepath);
                                                                
                                                                fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
@@ -13329,7 +13969,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 
 /* reading runtime */
 
-BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize, ReportList *reports)
+BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, ReportList *reports)
 {
        BlendFileData *bfd = NULL;
        FileData *fd = filedata_new();