Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / source / blender / blenloader / intern / readfile.c
index 7921740..204176f 100644 (file)
 
 #include "zlib.h"
 
-#ifdef WIN32
-#include "winsock2.h"
-#include "BLI_winstuff.h"
-#endif
-
 #include <limits.h>
 #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
 #include <stdlib.h> // for getenv atoi
@@ -46,6 +41,8 @@
     #include <sys/param.h> // for MAXPATHLEN
 #else
     #include <io.h> // for open close read
+#include "winsock2.h"
+#include "BLI_winstuff.h"
 #endif
 
 #include "DNA_anim_types.h"
@@ -53,6 +50,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_ID.h"
 #include "DNA_actuator_types.h"
+#include "DNA_boid_types.h"
 #include "DNA_brush_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_cloth_types.h"
@@ -93,6 +91,7 @@
 #include "DNA_sdna_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
+#include "DNA_smoke_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_space_types.h"
 #include "DNA_texture_types.h"
 #include "BKE_cloth.h"
 #include "BKE_colortools.h"
 #include "BKE_constraint.h"
+#include "BKE_context.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
 #include "BKE_deform.h"
 #include "BKE_group.h"
 #include "BKE_image.h"
 #include "BKE_ipo.h" 
-#include "BKE_key.h" //void set_four_ipo
 #include "BKE_lattice.h"
 #include "BKE_library.h" // for wich_libbase
 #include "BKE_main.h" // for Main
 #include "BKE_multires.h"
 #include "BKE_node.h" // for tree type defines
 #include "BKE_object.h"
+#include "BKE_paint.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_property.h" // for get_ob_property
 #include "BKE_scene.h"
 #include "BKE_softbody.h"      // sbNew()
 #include "BKE_bullet.h"                // bsbNew()
-#include "BKE_sculpt.h"
 #include "BKE_sequence.h"
 #include "BKE_texture.h" // for open_plugin_tex
 #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
 #include "BKE_idprop.h"
 
+#include "BKE_sound.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
@@ -1065,6 +1066,46 @@ int BLO_has_bfile_extension(char *str)
        return (BLI_testextensie(str, ".ble") || BLI_testextensie(str, ".blend")||BLI_testextensie(str, ".blend.gz"));
 }
 
+int BLO_is_a_library(char *path, char *dir, char *group)
+{
+       /* return ok when a blenderfile, in dir is the filename,
+        * in group the type of libdata
+        */
+       int len;
+       char *fd;
+       
+       strcpy(dir, path);
+       len= strlen(dir);
+       if(len<7) return 0;
+       if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
+       
+       group[0]= 0;
+       dir[len-1]= 0;
+
+       /* Find the last slash */
+       fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+
+       if(fd==0) return 0;
+       *fd= 0;
+       if(BLO_has_bfile_extension(fd+1)) {
+               /* the last part of the dir is a .blend file, no group follows */
+               *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */
+       }
+       else {          
+               char *gp = fd+1; // in case we have a .blend file, gp points to the group
+
+               /* Find the last slash */
+               fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
+               if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
+
+               /* now we know that we are in a blend file and it is safe to 
+                  assume that gp actually points to a group */
+               if (BLI_streq("Screen", gp)==0)
+                       BLI_strncpy(group, gp, GROUP_MAX);
+       }
+       return 1;
+}
+
 /* ************** OLD POINTERS ******************* */
 
 static void *newdataadr(FileData *fd, void *adr)               /* only direct databocks */
@@ -1362,20 +1403,17 @@ void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
 
 static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
 {
-       IDProperty **array;
+       IDProperty *array;
        int i;
 
        /*since we didn't save the extra buffer, set totallen to len.*/
        prop->totallen = prop->len;
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
-       if (switch_endian) {
-               test_pointer_array(fd, prop->data.pointer);
-               array= (IDProperty**) prop->data.pointer;
+       array= (IDProperty*) prop->data.pointer;
 
-               for(i=0; i<prop->len; i++)
-                       IDP_DirectLinkProperty(array[i], switch_endian, fd);
-       }
+       for(i=0; i<prop->len; i++)
+               IDP_DirectLinkProperty(&array[i], switch_endian, fd);
 }
 
 static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd)
@@ -1387,19 +1425,22 @@ static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *f
        prop->totallen = prop->len;
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
-       if (switch_endian) {
-               if(prop->subtype == IDP_GROUP) {
-                       test_pointer_array(fd, prop->data.pointer);
-                       array= prop->data.pointer;
+       if(prop->subtype == IDP_GROUP) {
+               test_pointer_array(fd, prop->data.pointer);
+               array= prop->data.pointer;
 
-                       for(i=0; i<prop->len; i++)
-                               IDP_DirectLinkProperty(array[i], switch_endian, fd);
-               }
-               else if(prop->subtype == IDP_DOUBLE) {
+               for(i=0; i<prop->len; i++)
+                       IDP_DirectLinkProperty(array[i], switch_endian, fd);
+       }
+       else if(prop->subtype == IDP_DOUBLE) {
+               if (switch_endian) {
                        for (i=0; i<prop->len; i++) {
                                SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
                        }
-               } else {
+               }
+       }
+       else {
+               if (switch_endian) {
                        for (i=0; i<prop->len; i++) {
                                SWITCH_INT(((int*)prop->data.pointer)[i]);
                        }
@@ -1564,33 +1605,6 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
        return prv;
 }
 
-/* ************ READ SCRIPTLINK *************** */
-
-static void lib_link_scriptlink(FileData *fd, ID *id, ScriptLink *slink)
-{
-       int i;
-
-       for(i=0; i<slink->totscript; i++) {
-               slink->scripts[i]= newlibadr(fd, id->lib, slink->scripts[i]);
-       }
-}
-
-static void direct_link_scriptlink(FileData *fd, ScriptLink *slink)
-{
-       slink->scripts= newdataadr(fd, slink->scripts);
-       test_pointer_array(fd, (void **)&slink->scripts);
-       
-       slink->flag= newdataadr(fd, slink->flag);
-
-       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
-               int a;
-
-               for(a=0; a<slink->totscript; a++) {
-                       SWITCH_SHORT(slink->flag[a]);
-               }
-       }
-}
-
 /* ************ READ ANIMATION STUFF ***************** */
 
 /* Legacy Data Support (for Version Patching) ----------------------------- */
@@ -1667,10 +1681,26 @@ static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbas
 
 /* Data Linking ----------------------------- */
 
+static void lib_link_fmodifiers(FileData *fd, ID *id, ListBase *list)
+{
+       FModifier *fcm;
+       
+       for (fcm= list->first; fcm; fcm= fcm->next) {
+               /* data for specific modifiers */
+               switch (fcm->type) {
+                       case FMODIFIER_TYPE_PYTHON:
+                       {
+                               FMod_Python *data= (FMod_Python *)fcm->data;
+                               data->script = newlibadr(fd, id->lib, data->script);
+                       }
+                               break;
+               }
+       }
+}
+
 static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list) 
 {
        FCurve *fcu;
-       FModifier *fcm;
        
        /* relink ID-block references... */
        for (fcu= list->first; fcu; fcu= fcu->next) {
@@ -1684,16 +1714,45 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
                }
                
                /* modifiers */
-               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
-                       /* data for specific modifiers */
-                       switch (fcm->type) {
-                               case FMODIFIER_TYPE_PYTHON:
-                               {
-                                       FMod_Python *data= (FMod_Python *)fcm->data;
-                                       data->script = newlibadr(fd, id->lib, data->script);
-                               }
-                                       break;
+               lib_link_fmodifiers(fd, id, &fcu->modifiers);
+       }
+}
+
+
+/* NOTE: this assumes that link_list has already been called on the list */
+static void direct_link_fmodifiers(FileData *fd, ListBase *list)
+{
+       FModifier *fcm;
+       
+       for (fcm= list->first; fcm; fcm= fcm->next) {
+               /* relink general data */
+               fcm->data = newdataadr(fd, fcm->data);
+               fcm->edata= NULL;
+               
+               /* do relinking of data for specific types */
+               switch (fcm->type) {
+                       case FMODIFIER_TYPE_GENERATOR:
+                       {
+                               FMod_Generator *data= (FMod_Generator *)fcm->data;
+                               
+                               data->coefficients= newdataadr(fd, data->coefficients);
                        }
+                               break;
+                       case FMODIFIER_TYPE_ENVELOPE:
+                       {
+                               FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+                               
+                               data->data= newdataadr(fd, data->data);
+                       }
+                               break;
+                       case FMODIFIER_TYPE_PYTHON:
+                       {
+                               FMod_Python *data= (FMod_Python *)fcm->data;
+                               
+                               data->prop = newdataadr(fd, data->prop);
+                               IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+                       }
+                               break;
                }
        }
 }
@@ -1702,7 +1761,6 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
 static void direct_link_fcurves(FileData *fd, ListBase *list)
 {
        FCurve *fcu;
-       FModifier *fcm;
        
        /* link F-Curve data to F-Curve again (non ID-libs) */
        for (fcu= list->first; fcu; fcu= fcu->next) {
@@ -1730,37 +1788,7 @@ static void direct_link_fcurves(FileData *fd, ListBase *list)
                
                /* modifiers */
                link_list(fd, &fcu->modifiers);
-               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
-                       /* relink general data */
-                       fcm->data = newdataadr(fd, fcm->data);
-                       fcm->edata= NULL;
-                       
-                       /* do relinking of data for specific types */
-                       switch (fcm->type) {
-                               case FMODIFIER_TYPE_GENERATOR:
-                               {
-                                       FMod_Generator *data= (FMod_Generator *)fcm->data;
-                                       
-                                       data->coefficients= newdataadr(fd, data->coefficients);
-                               }
-                                       break;
-                               case FMODIFIER_TYPE_ENVELOPE:
-                               {
-                                       FMod_Envelope *data= (FMod_Envelope *)fcm->data;
-                                       
-                                       data->data= newdataadr(fd, data->data);
-                               }
-                                       break;
-                               case FMODIFIER_TYPE_PYTHON:
-                               {
-                                       FMod_Python *data= (FMod_Python *)fcm->data;
-                                       
-                                       data->prop = newdataadr(fd, data->prop);
-                                       IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-                               }
-                                       break;
-                       }
-               }
+               direct_link_fmodifiers(fd, &fcu->modifiers);
        }
 }
 
@@ -1812,6 +1840,65 @@ static void direct_link_action(FileData *fd, bAction *act)
        }
 }
 
+static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list)
+{
+       NlaStrip *strip;
+       
+       for (strip= list->first; strip; strip= strip->next) {
+               /* check strip's children */
+               lib_link_nladata_strips(fd, id, &strip->strips);
+               
+               /* reassign the counted-reference to action */
+               strip->act = newlibadr_us(fd, id->lib, strip->act);
+       }
+}
+
+static void lib_link_nladata(FileData *fd, ID *id, ListBase *list)
+{
+       NlaTrack *nlt;
+       
+       /* we only care about the NLA strips inside the tracks */
+       for (nlt= list->first; nlt; nlt= nlt->next) {
+               lib_link_nladata_strips(fd, id, &nlt->strips);
+       }
+}
+
+/* This handles Animato NLA-Strips linking 
+ * NOTE: this assumes that link_list has already been called on the list 
+ */
+static void direct_link_nladata_strips(FileData *fd, ListBase *list)
+{
+       NlaStrip *strip;
+       
+       for (strip= list->first; strip; strip= strip->next) {
+               /* strip's child strips */
+               link_list(fd, &strip->strips);
+               direct_link_nladata_strips(fd, &strip->strips);
+               
+               /* strip's F-Curves */
+               link_list(fd, &strip->fcurves);
+               direct_link_fcurves(fd, &strip->fcurves);
+               
+               /* strip's F-Modifiers */
+               link_list(fd, &strip->modifiers);
+               direct_link_fcurves(fd, &strip->modifiers);
+       }
+}
+
+/* NOTE: this assumes that link_list has already been called on the list */
+static void direct_link_nladata(FileData *fd, ListBase *list)
+{
+       NlaTrack *nlt;
+       
+       for (nlt= list->first; nlt; nlt= nlt->next) {
+               /* relink list of strips */
+               link_list(fd, &nlt->strips);
+               
+               /* relink strip data */
+               direct_link_nladata_strips(fd, &nlt->strips);
+       }
+}
+
 /* ------- */
 
 static void lib_link_keyingsets(FileData *fd, ID *id, ListBase *list)
@@ -1854,6 +1941,7 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
        
        /* link action data */
        adt->action= newlibadr_us(fd, id->lib, adt->action);
+       adt->tmpact= newlibadr_us(fd, id->lib, adt->tmpact);
        
        /* link drivers */
        lib_link_fcurves(fd, id, &adt->drivers);
@@ -1861,7 +1949,7 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
        /* overrides don't have lib-link for now, so no need to do anything */
        
        /* link NLA-data */
-       // TODO... 
+       lib_link_nladata(fd, id, &adt->nla_tracks);
 }
 
 static void direct_link_animdata(FileData *fd, AnimData *adt)
@@ -1878,7 +1966,12 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
        // TODO...
        
        /* link NLA-data */
-       // TODO...
+       link_list(fd, &adt->nla_tracks);
+       direct_link_nladata(fd, &adt->nla_tracks);
+       
+       /* clear temp pointers that may have been set... */
+       // TODO: it's probably only a small cost to reload this anyway...
+       adt->actstrip= NULL;
 }      
 
 /* ************ READ NODE TREE *************** */
@@ -2091,6 +2184,8 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data = ((bKinematicConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
                                data->poletar = newlibadr(fd, id->lib, data->poletar);
+                               con->lin_error = 0.f;
+                               con->rot_error = 0.f;
                        }
                        break;
                case CONSTRAINT_TYPE_TRACKTO:
@@ -2238,6 +2333,7 @@ static void lib_link_armature(FileData *fd, Main *main)
 
        while(arm) {
                if(arm->id.flag & LIB_NEEDLINK) {
+                       if (arm->adt) lib_link_animdata(fd, &arm->id, arm->adt);
                        arm->id.flag -= LIB_NEEDLINK;
                }
                arm= arm->id.next;
@@ -2263,6 +2359,8 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
 
        link_list(fd, &arm->bonebase);
        arm->edbo= NULL;
+       arm->sketch = NULL;
+       arm->adt= newdataadr(fd, arm->adt);
        
        bone=arm->bonebase.first;
        while (bone) {
@@ -2286,8 +2384,6 @@ static void lib_link_camera(FileData *fd, Main *main)
                        
                        ca->dof_ob= newlibadr_us(fd, ca->id.lib, ca->dof_ob);
                        
-                       lib_link_scriptlink(fd, &ca->id, &ca->scriptlink);
-                       
                        ca->id.flag -= LIB_NEEDLINK;
                }
                ca= ca->id.next;
@@ -2298,8 +2394,6 @@ static void direct_link_camera(FileData *fd, Camera *ca)
 {
        ca->adt= newdataadr(fd, ca->adt);
        direct_link_animdata(fd, ca->adt);
-       
-       direct_link_scriptlink(fd, &ca->scriptlink);
 }
 
 
@@ -2326,8 +2420,6 @@ static void lib_link_lamp(FileData *fd, Main *main)
                        
                        la->ipo= newlibadr_us(fd, la->id.lib, la->ipo); // XXX depreceated - old animation system
                        
-                       lib_link_scriptlink(fd, &la->id, &la->scriptlink);
-                       
                        la->id.flag -= LIB_NEEDLINK;
                }
                la= la->id.next;
@@ -2340,8 +2432,6 @@ static void direct_link_lamp(FileData *fd, Lamp *la)
        
        la->adt= newdataadr(fd, la->adt);
        direct_link_animdata(fd, la->adt);
-       
-       direct_link_scriptlink(fd, &la->scriptlink);
 
        for(a=0; a<MAX_MTEX; a++) {
                la->mtex[a]= newdataadr(fd, la->mtex[a]);
@@ -2441,7 +2531,8 @@ static void lib_link_mball(FileData *fd, Main *main)
        mb= main->mball.first;
        while(mb) {
                if(mb->id.flag & LIB_NEEDLINK) {
-
+                       if (mb->adt) lib_link_animdata(fd, &mb->id, mb->adt);
+                       
                        for(a=0; a<mb->totcol; a++) mb->mat[a]= newlibadr_us(fd, mb->id.lib, mb->mat[a]);
 
                        mb->ipo= newlibadr_us(fd, mb->id.lib, mb->ipo); // XXX depreceated - old animation system
@@ -2454,6 +2545,9 @@ static void lib_link_mball(FileData *fd, Main *main)
 
 static void direct_link_mball(FileData *fd, MetaBall *mb)
 {
+       mb->adt= newdataadr(fd, mb->adt);
+       direct_link_animdata(fd, mb->adt);
+       
        mb->mat= newdataadr(fd, mb->mat);
        test_pointer_array(fd, (void **)&mb->mat);
 
@@ -2462,6 +2556,8 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
        mb->disp.first= mb->disp.last= NULL;
        mb->editelems= NULL;
        mb->bb= NULL;
+/*     mb->edit_elems.first= mb->edit_elems.last= NULL;*/
+       mb->lastelem= NULL;
 }
 
 /* ************ READ WORLD ***************** */
@@ -2487,8 +2583,6 @@ static void lib_link_world(FileData *fd, Main *main)
                                }
                        }
                        
-                       lib_link_scriptlink(fd, &wrld->id, &wrld->scriptlink);
-                       
                        wrld->id.flag -= LIB_NEEDLINK;
                }
                wrld= wrld->id.next;
@@ -2501,8 +2595,6 @@ static void direct_link_world(FileData *fd, World *wrld)
 
        wrld->adt= newdataadr(fd, wrld->adt);
        direct_link_animdata(fd, wrld->adt);
-       
-       direct_link_scriptlink(fd, &wrld->scriptlink);
 
        for(a=0; a<MAX_MTEX; a++) {
                wrld->mtex[a]= newdataadr(fd, wrld->mtex[a]);
@@ -2641,6 +2733,7 @@ static void direct_link_image(FileData *fd, Image *ima)
        ima->anim= NULL;
        ima->rr= NULL;
        ima->repbind= NULL;
+       ima->render_text= newdataadr(fd, ima->render_text);
        
        ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
        ima->preview = direct_link_preview_image(fd, ima->preview);
@@ -2768,6 +2861,11 @@ static void lib_link_texture(FileData *fd, Main *main)
                        tex->ima= newlibadr_us(fd, tex->id.lib, tex->ima);
                        tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
                        if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
+                       if(tex->pd) {
+                               tex->pd->object= newlibadr(fd, tex->id.lib, tex->pd->object);
+                               tex->pd->psys= newlibadr(fd, tex->id.lib, tex->pd->psys);
+                       }
+                       if(tex->vd) tex->vd->object= newlibadr(fd, tex->id.lib, tex->vd->object);
 
                        if(tex->nodetree)
                                lib_link_ntree(fd, &tex->id, tex->nodetree);
@@ -2800,6 +2898,16 @@ static void direct_link_texture(FileData *fd, Tex *tex)
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
+       tex->pd= newdataadr(fd, tex->pd);
+       if(tex->pd) {
+               tex->pd->point_tree = NULL;
+               tex->pd->coba= newdataadr(fd, tex->pd->coba);
+       }
+       
+       tex->vd= newdataadr(fd, tex->vd);
+       if(tex->vd) {
+               tex->vd->dataset = NULL;
+       }
        
        tex->nodetree= newdataadr(fd, tex->nodetree);
        if(tex->nodetree)
@@ -2839,7 +2947,6 @@ static void lib_link_material(FileData *fd, Main *main)
                                        mtex->object= newlibadr(fd, ma->id.lib, mtex->object);
                                }
                        }
-                       lib_link_scriptlink(fd, &ma->id, &ma->scriptlink);
                        
                        if(ma->nodetree)
                                lib_link_ntree(fd, &ma->id, ma->nodetree);
@@ -2864,8 +2971,6 @@ static void direct_link_material(FileData *fd, Material *ma)
        ma->ramp_col= newdataadr(fd, ma->ramp_col);
        ma->ramp_spec= newdataadr(fd, ma->ramp_spec);
        
-       direct_link_scriptlink(fd, &ma->scriptlink);
-       
        ma->nodetree= newdataadr(fd, ma->nodetree);
        if(ma->nodetree)
                direct_link_nodetree(fd, ma->nodetree);
@@ -2880,16 +2985,49 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache)
 {
        if((cache->flag & PTCACHE_DISK_CACHE)==0) {
                PTCacheMem *pm;
+               int i;
 
                link_list(fd, &cache->mem_cache);
 
                pm = cache->mem_cache.first;
 
-               for(; pm; pm=pm->next)
-                       pm->data = newdataadr(fd, pm->data);
+               for(; pm; pm=pm->next) {
+                       if(pm->index_array)
+                               pm->index_array = newdataadr(fd, pm->index_array);
+                       
+                       for(i=0; i<BPHYS_TOT_DATA; i++) {
+                               if(pm->data[i] && pm->data_types & (1<<i))
+                                       pm->data[i] = newdataadr(fd, pm->data[i]);
+                       }
+               }
        }
-       cache->flag &= ~(PTCACHE_SIMULATION_VALID|PTCACHE_BAKE_EDIT_ACTIVE);
+       else
+               cache->mem_cache.first = cache->mem_cache.last = NULL;
+
+       cache->flag &= ~PTCACHE_SIMULATION_VALID;
        cache->simframe= 0;
+       cache->edit= NULL;
+       cache->free_edit= NULL;
+}
+
+static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache)
+{
+       PointCache *cache;
+
+       if(ptcaches->first) {
+               link_list(fd, ptcaches);
+               for(cache=ptcaches->first; cache; cache=cache->next)
+                       direct_link_pointcache(fd, cache);
+
+               *ocache = newdataadr(fd, *ocache);
+       }
+       else if(*ocache) {
+               /* old "single" caches need to be linked too */
+               *ocache = newdataadr(fd, *ocache);
+               direct_link_pointcache(fd, *ocache);
+
+               ptcaches->first = ptcaches->last = *ocache;
+       }
 }
 
 static void lib_link_particlesettings(FileData *fd, Main *main)
@@ -2906,6 +3044,29 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
                        part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
                        part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
                        part->bb_ob = newlibadr(fd, part->id.lib, part->bb_ob);
+                       if(part->boids) {
+                               BoidState *state = part->boids->states.first;
+                               BoidRule *rule;
+                               for(; state; state=state->next) {
+                                       rule = state->rules.first;
+                               for(; rule; rule=rule->next)
+                                       switch(rule->type) {
+                                               case eBoidRuleType_Goal:
+                                               case eBoidRuleType_Avoid:
+                                               {
+                                                       BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid*)rule;
+                                                       brga->ob = newlibadr(fd, part->id.lib, brga->ob);
+                                                       break;
+                                               }
+                                               case eBoidRuleType_FollowLeader:
+                                               {
+                                                       BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader*)rule;
+                                                       brfl->ob = newlibadr(fd, part->id.lib, brfl->ob);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
                        part->id.flag -= LIB_NEEDLINK;
                }
                part= part->id.next;
@@ -2917,26 +3078,36 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
        part->adt= newdataadr(fd, part->adt);
        part->pd= newdataadr(fd, part->pd);
        part->pd2= newdataadr(fd, part->pd2);
+
+       part->boids= newdataadr(fd, part->boids);
+
+       if(part->boids) {
+               BoidState *state;
+               link_list(fd, &part->boids->states);
+               
+               for(state=part->boids->states.first; state; state=state->next) {
+                       link_list(fd, &state->rules);
+                       link_list(fd, &state->conditions);
+                       link_list(fd, &state->actions);
+               }
+       }
 }
 
 static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
 {
        ParticleSystem *psys, *psysnext;
-       int a;
 
        for(psys=particles->first; psys; psys=psysnext){
-               ParticleData *pa;
-               
                psysnext= psys->next;
                
                psys->part = newlibadr_us(fd, id->lib, psys->part);
                if(psys->part) {
-                       psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
-                       psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob);
+                       ParticleTarget *pt = psys->targets.first;
 
-                       for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){
-                               pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
-                       }
+                       for(; pt; pt=pt->next)
+                               pt->ob=newlibadr(fd, id->lib, pt->ob);
+
+                       psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
                }
                else {
                        /* particle modifier must be removed before particle system */
@@ -2952,51 +3123,73 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase
 static void direct_link_particlesystems(FileData *fd, ListBase *particles)
 {
        ParticleSystem *psys;
+       ParticleData *pa;
        int a;
 
        for(psys=particles->first; psys; psys=psys->next) {
                psys->particles=newdataadr(fd,psys->particles);
+               
                if(psys->particles && psys->particles->hair){
-                       ParticleData *pa = psys->particles;
-                       for(a=0; a<psys->totpart; a++, pa++)
+                       for(a=0,pa=psys->particles; a<psys->totpart; a++, pa++)
                                pa->hair=newdataadr(fd,pa->hair);
                }
+               
                if(psys->particles && psys->particles->keys){
-                       ParticleData *pa = psys->particles;
-                       for(a=0; a<psys->totpart; a++, pa++) {
+                       for(a=0,pa=psys->particles; a<psys->totpart; a++, pa++) {
                                pa->keys= NULL;
                                pa->totkey= 0;
                        }
 
                        psys->flag &= ~PSYS_KEYED;
                }
+
+               if(psys->particles && psys->particles->boid) {
+                       pa = psys->particles;
+                       pa->boid = newdataadr(fd, pa->boid);
+                       for(a=1,pa++; a<psys->totpart; a++, pa++)
+                               pa->boid = (pa-1)->boid + 1;
+               }
+               else {
+                       for(a=0,pa=psys->particles; a<psys->totpart; a++, pa++)
+                               pa->boid = NULL;
+               }
+
+
                psys->child=newdataadr(fd,psys->child);
                psys->effectors.first=psys->effectors.last=0;
 
-               psys->soft= newdataadr(fd, psys->soft);
-               if(psys->soft) {
-                       SoftBody *sb = psys->soft;
-                       sb->particles = psys;
-                       sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
-                       sb->bspring= NULL;
-                       sb->scratch= NULL;
+               link_list(fd, &psys->targets);
 
-                       sb->pointcache= newdataadr(fd, sb->pointcache);
-                       if(sb->pointcache)
-                               direct_link_pointcache(fd, sb->pointcache);
-               }
-
-               psys->edit = 0;
+               psys->edit = NULL;
                psys->free_edit = NULL;
                psys->pathcache = 0;
                psys->childcache = 0;
                psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
                psys->childcachebufs.first = psys->childcachebufs.last = 0;
                psys->reactevents.first = psys->reactevents.last = 0;
+               psys->frand = NULL;
+               psys->pdd = NULL;
+
+               direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache);
+
+               if(psys->clmd) {
+                       psys->clmd = newdataadr(fd, psys->clmd);
+                       psys->clmd->clothObject = NULL;
+                       
+                       psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
+                       psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
+                       
+                       if(psys->clmd->sim_parms) {
+                               if(psys->clmd->sim_parms->presets > 10)
+                                       psys->clmd->sim_parms->presets = 0;
+                       }
+
+                       psys->hair_in_dm = psys->hair_out_dm = NULL;
 
-               psys->pointcache= newdataadr(fd, psys->pointcache);
-               if(psys->pointcache)
-                       direct_link_pointcache(fd, psys->pointcache);
+                       psys->clmd->point_cache = psys->pointcache;
+               }
+
+               psys->tree = NULL;
        }
        return;
 }
@@ -3294,11 +3487,13 @@ static void lib_link_object(FileData *fd, Main *main)
                                if(ob->pose) {
                                        free_pose(ob->pose);
                                        ob->pose= NULL;
-                                       ob->flag &= ~OB_POSEMODE;
+                                       ob->mode &= ~OB_MODE_POSE;
                                }
                        }
                        for(a=0; a<ob->totcol; a++) ob->mat[a]= newlibadr_us(fd, ob->id.lib, ob->mat[a]);
                        
+                       ob->gpd= newlibadr_us(fd, ob->id.lib, ob->gpd);
+                       
                        ob->id.flag -= LIB_NEEDLINK;
                        /* if id.us==0 a new base will be created later on */
                        
@@ -3355,9 +3550,6 @@ static void lib_link_object(FileData *fd, Main *main)
                                        bSoundActuator *sa= act->data;
                                        sa->sound= newlibadr_us(fd, ob->id.lib, sa->sound);
                                }
-                               else if(act->type==ACT_CD) {
-                                       /* bCDActuator *cda= act->data; */
-                               }
                                else if(act->type==ACT_GAME) {
                                        /* bGameActuator *ga= act->data; */
                                }
@@ -3425,6 +3617,11 @@ static void lib_link_object(FileData *fd, Main *main)
                                else if(act->type==ACT_STATE) {
                                        /* bStateActuator *statea = act->data; */
                                }
+                               else if(act->type==ACT_ARMATURE) {
+                                       bArmatureActuator *arma= act->data;
+                                       arma->target= newlibadr(fd, ob->id.lib, arma->target);
+                                       arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget);
+                               }
                                act= act->next;
                        }
                        
@@ -3434,13 +3631,23 @@ static void lib_link_object(FileData *fd, Main *main)
                                if(fluidmd && fluidmd->fss) 
                                        fluidmd->fss->ipo = newlibadr_us(fd, ob->id.lib, fluidmd->fss->ipo);
                        }
+
+                       {
+                               SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke);
+                               
+                               if(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain) 
+                               {
+                                       smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
+                                       smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
+                                       smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
+                               }
+                       }
                        
                        /* texture field */
                        if(ob->pd)
                                if(ob->pd->tex)
                                        ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex);
 
-                       lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
                        lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem);
                        lib_link_modifiers(fd, ob);
                }
@@ -3476,6 +3683,10 @@ static void direct_link_pose(FileData *fd, bPose *pose)
                pchan->iktree.first= pchan->iktree.last= NULL;
                pchan->path= NULL;
        }
+       pose->ikdata = NULL;
+       if (pose->ikparam != NULL) {
+               pose->ikparam= newdataadr(fd, pose->ikparam);
+       }
 }
 
 static void direct_link_modifiers(FileData *fd, ListBase *lb)
@@ -3509,10 +3720,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        
                        clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
                        clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
-                       clmd->point_cache= newdataadr(fd, clmd->point_cache);
 
-                       if(clmd->point_cache)
-                               direct_link_pointcache(fd, clmd->point_cache);
+                       direct_link_pointcache_list(fd, &clmd->ptcaches, &clmd->point_cache);
                        
                        if(clmd->sim_parms) {
                                if(clmd->sim_parms->presets > 10)
@@ -3526,6 +3735,46 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        fluidmd->fss= newdataadr(fd, fluidmd->fss);
                        fluidmd->fss->meshSurfNormals = 0;
                }
+               else if (md->type==eModifierType_Smoke) {
+                       SmokeModifierData *smd = (SmokeModifierData*) md;
+
+                       if(smd->type==MOD_SMOKE_TYPE_DOMAIN)
+                       {
+                               smd->flow = NULL;
+                               smd->coll = NULL;
+                               smd->domain = newdataadr(fd, smd->domain);
+                               smd->domain->smd = smd;
+
+                               smd->domain->fluid = NULL;
+                               smd->domain->wt = NULL;
+                               smd->domain->shadow = NULL;
+                               smd->domain->tex = NULL;
+                               smd->domain->tex_shadow = NULL;
+                               smd->domain->tex_wt = NULL;
+
+                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[0]), &(smd->domain->point_cache[0]));
+                               direct_link_pointcache_list(fd, &(smd->domain->ptcaches[1]), &(smd->domain->point_cache[1]));
+                       }
+                       else if(smd->type==MOD_SMOKE_TYPE_FLOW)
+                       {
+                               smd->domain = NULL;
+                               smd->coll = NULL;
+                               smd->flow = newdataadr(fd, smd->flow);
+                               smd->flow->smd = smd;
+                               smd->flow->psys = newdataadr(fd, smd->flow->psys);
+                       }
+                       else if(smd->type==MOD_SMOKE_TYPE_COLL)
+                       {
+                               smd->flow = NULL;
+                               smd->domain = NULL;
+                               smd->coll = NULL;
+                               /*
+                               smd->coll = newdataadr(fd, smd->coll);
+                               smd->coll->points = NULL;
+                               smd->coll->numpoints = 0;
+                               */
+                       }
+               }
                else if (md->type==eModifierType_Collision) {
                        
                        CollisionModifierData *collmd = (CollisionModifierData*) md;
@@ -3557,6 +3806,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 
                        surmd->dm = NULL;
                        surmd->bvhtree = NULL;
+                       surmd->x = NULL;
+                       surmd->v = NULL;
+                       surmd->numverts = 0;
                }
                else if (md->type==eModifierType_Hook) {
                        HookModifierData *hmd = (HookModifierData*) md;
@@ -3637,10 +3889,9 @@ static void direct_link_object(FileData *fd, Object *ob)
        link_list(fd, &ob->constraintChannels);
 // >>> XXX depreceated - old animation system 
 
-       direct_link_scriptlink(fd, &ob->scriptlink);
-
        ob->mat= newdataadr(fd, ob->mat);
        test_pointer_array(fd, (void **)&ob->mat);
+       ob->matbits= newdataadr(fd, ob->matbits);
        
        /* do it here, below old data gets converted */
        direct_link_modifiers(fd, &ob->modifiers);
@@ -3714,9 +3965,7 @@ static void direct_link_object(FileData *fd, Object *ob)
                        }
                }
 
-               sb->pointcache= newdataadr(fd, sb->pointcache);
-               if(sb->pointcache)
-                       direct_link_pointcache(fd, sb->pointcache);
+               direct_link_pointcache_list(fd, &sb->ptcaches, &sb->pointcache);
        }
        ob->bsoft= newdataadr(fd, ob->bsoft);
        ob->fluidsimSettings= newdataadr(fd, ob->fluidsimSettings); /* NT */
@@ -3802,6 +4051,10 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->derivedDeform= NULL;
        ob->derivedFinal= NULL;
        ob->gpulamp.first= ob->gpulamp.last= NULL;
+       link_list(fd, &ob->pc_ids);
+
+       if(ob->sculpt)
+               ob->sculpt= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
 }
 
 /* ************ READ SCENE ***************** */
@@ -3816,6 +4069,14 @@ static void composite_patch(bNodeTree *ntree, Scene *scene)
                        node->id= &scene->id;
 }
 
+static void link_paint(FileData *fd, Scene *sce, Paint *p)
+{
+       if(p && p->brushes) {
+               int i;
+               for(i = 0; i < p->brush_count; ++i)
+                       p->brushes[i]= newlibadr_us(fd, sce->id.lib, p->brushes[i]);
+       }
+}
 
 static void lib_link_scene(FileData *fd, Main *main)
 {
@@ -3838,19 +4099,13 @@ static void lib_link_scene(FileData *fd, Main *main)
                        sce->world= newlibadr_us(fd, sce->id.lib, sce->world);
                        sce->set= newlibadr(fd, sce->id.lib, sce->set);
                        sce->ima= newlibadr_us(fd, sce->id.lib, sce->ima);
+                       sce->gpd= newlibadr_us(fd, sce->id.lib, sce->gpd);
                        
-                       sce->toolsettings->imapaint.brush=
-                               newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.brush);
-                       if(sce->toolsettings->sculpt)
-                               sce->toolsettings->sculpt->brush=
-                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->brush);
-                       if(sce->toolsettings->vpaint)
-                               sce->toolsettings->vpaint->brush=
-                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->vpaint->brush);
-                       if(sce->toolsettings->wpaint)
-                               sce->toolsettings->wpaint->brush=
-                                       newlibadr_us(fd, sce->id.lib, sce->toolsettings->wpaint->brush);
-                       
+                       link_paint(fd, sce, &sce->toolsettings->sculpt->paint);
+                       link_paint(fd, sce, &sce->toolsettings->vpaint->paint);
+                       link_paint(fd, sce, &sce->toolsettings->wpaint->paint);
+                       link_paint(fd, sce, &sce->toolsettings->imapaint.paint);
+
                        sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
 
                        for(base= sce->base.first; base; base= next) {
@@ -3879,19 +4134,19 @@ static void lib_link_scene(FileData *fd, Main *main)
                                if(seq->ipo) seq->ipo= newlibadr_us(fd, sce->id.lib, seq->ipo);
                                if(seq->scene) seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
                                if(seq->sound) {
-                                       seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
+                                       if(seq->type == SEQ_HD_SOUND)
+                                               seq->type = SEQ_SOUND;
+                                       else
+                                               seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
                                        if (seq->sound) {
                                                seq->sound->id.us++;
-                                               seq->sound->flags |= SOUND_FLAGS_SEQUENCE;
+                                               seq->sound_handle= sound_new_handle(sce, seq->sound, seq->startdisp, seq->enddisp, seq->startofs);
                                        }
                                }
                                seq->anim= 0;
-                               seq->hdaudio = 0;
                        }
                        SEQ_END
                        
-                       lib_link_scriptlink(fd, &sce->id, &sce->scriptlink);
-                       
                        if(sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
                                composite_patch(sce->nodetree, sce);
@@ -3902,7 +4157,8 @@ static void lib_link_scene(FileData *fd, Main *main)
                                srl->light_override= newlibadr_us(fd, sce->id.lib, srl->light_override);
                        }
                        /*Game Settings: Dome Warp Text*/
-                       sce->r.dometext= newlibadr_us(fd, sce->id.lib, sce->r.dometext);
+//                     sce->r.dometext= newlibadr_us(fd, sce->id.lib, sce->r.dometext); // XXX deprecated since 2.5
+                       sce->gm.dome.warptext= newlibadr_us(fd, sce->id.lib, sce->gm.dome.warptext);
 
                        sce->id.flag -= LIB_NEEDLINK;
                }
@@ -3922,6 +4178,13 @@ static void link_recurs_seq(FileData *fd, ListBase *lb)
                        link_recurs_seq(fd, &seq->seqbase);
 }
 
+static void direct_link_paint(FileData *fd, Paint **paint)
+{
+       (*paint)= newdataadr(fd, (*paint));
+       if(*paint)
+               (*paint)->brushes= newdataadr(fd, (*paint)->brushes);
+}
+
 static void direct_link_scene(FileData *fd, Scene *sce)
 {
        Editing *ed;
@@ -3931,7 +4194,10 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        sce->theDag = NULL;
        sce->dagisvalid = 0;
        sce->obedit= NULL;
-       
+       sce->stats= 0;
+
+       memset(&sce->sound_handles, 0, sizeof(sce->sound_handles));
+
        /* set users to one by default, not in lib-link, this will increase it for compo nodes */
        sce->id.us= 1;
 
@@ -3947,14 +4213,14 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        
        sce->toolsettings= newdataadr(fd, sce->toolsettings);
        if(sce->toolsettings) {
-               sce->toolsettings->vpaint= newdataadr(fd, sce->toolsettings->vpaint);
-               sce->toolsettings->wpaint= newdataadr(fd, sce->toolsettings->wpaint);
-               sce->toolsettings->sculpt= newdataadr(fd, sce->toolsettings->sculpt);
+               direct_link_paint(fd, (Paint**)&sce->toolsettings->sculpt);
+               direct_link_paint(fd, (Paint**)&sce->toolsettings->vpaint);
+               direct_link_paint(fd, (Paint**)&sce->toolsettings->wpaint);
+
+               sce->toolsettings->imapaint.paint.brushes= newdataadr(fd, sce->toolsettings->imapaint.paint.brushes);
+
                sce->toolsettings->imapaint.paintcursor= NULL;
                sce->toolsettings->particle.paintcursor= NULL;
-
-               if(sce->toolsettings->sculpt)
-                       sce->toolsettings->sculpt->session= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
        }
 
        if(sce->ed) {
@@ -4023,6 +4289,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                                } else {
                                        seq->strip->color_balance = 0;
                                }
+                               if (seq->strip->color_balance) {
+                                       // seq->strip->color_balance->gui = 0; // XXX - peter, is this relevant in 2.5?
+                               }
                        }
                }
                SEQ_END
@@ -4066,8 +4335,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
                        }
                }
        }
-
-       direct_link_scriptlink(fd, &sce->scriptlink);
        
        sce->r.avicodecdata = newdataadr(fd, sce->r.avicodecdata);
        if (sce->r.avicodecdata) {
@@ -4117,6 +4384,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
                win->timers.first= win->timers.last= NULL;
                win->queue.first= win->queue.last= NULL;
                win->handlers.first= win->handlers.last= NULL;
+               win->modalhandlers.first= win->modalhandlers.last= NULL;
                win->subwindows.first= win->subwindows.last= NULL;
                win->gesture.first= win->gesture.last= NULL;
 
@@ -4129,7 +4397,9 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        wm->keymaps.first= wm->keymaps.last= NULL;
        wm->paintcursors.first= wm->paintcursors.last= NULL;
        wm->queue.first= wm->queue.last= NULL;
-       wm->reports.first= wm->reports.last= NULL;
+       BKE_reports_init(&wm->reports, RPT_STORE);
+
+       wm->jobs.first= wm->jobs.last= NULL;
        
        wm->windrawable= NULL;
        wm->initialized= 0;
@@ -4138,11 +4408,14 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
 static void lib_link_windowmanager(FileData *fd, Main *main)
 {
        wmWindowManager *wm;
+       wmWindow *win;
        
        for(wm= main->wm.first; wm; wm= wm->id.next) {
-               wmWindow *win;
-               for(win= wm->windows.first; win; win= win->next) {
-                       win->screen= newlibadr(fd, NULL, win->screen);
+               if(wm->id.flag & LIB_NEEDLINK) {
+                       for(win= wm->windows.first; win; win= win->next)
+                               win->screen= newlibadr(fd, NULL, win->screen);
+
+                       wm->id.flag -= LIB_NEEDLINK;
                }
        }
 }
@@ -4220,9 +4493,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                
                                sa->full= newlibadr(fd, sc->id.lib, sa->full);
                                
-                               /* space handler scriptlinks */
-                               lib_link_scriptlink(fd, &sc->id, &sa->scriptlink);
-                               
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                        if(sl->spacetype==SPACE_VIEW3D) {
                                                View3D *v3d= (View3D*) sl;
@@ -4245,9 +4515,10 @@ static void lib_link_screen(FileData *fd, Main *main)
                                        }
                                        else if(sl->spacetype==SPACE_BUTS) {
                                                SpaceButs *sbuts= (SpaceButs *)sl;
-                                               sbuts->lockpoin= NULL;
                                                sbuts->ri= NULL;
                                                sbuts->pinid= newlibadr(fd, sc->id.lib, sbuts->pinid);
+                                               sbuts->mainbo= sbuts->mainb;
+                                               sbuts->mainbuser= sbuts->mainb;
                                                if(main->versionfile<132)
                                                        butspace_version_132(sbuts);
                                        }
@@ -4257,6 +4528,8 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                sfile->params= NULL;
                                                sfile->op= NULL;
                                                sfile->layout= NULL;
+                                               sfile->folders_prev= NULL;
+                                               sfile->folders_next= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
                                                SpaceImaSel *simasel= (SpaceImaSel *)sl;
@@ -4399,16 +4672,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                while(sa) {
                        SpaceLink *sl;
 
-                       if (sa->scriptlink.totscript) {
-                               /* restore screen area script links */
-                               ScriptLink *slink = &sa->scriptlink;
-                               int script_idx;
-                               for (script_idx = 0; script_idx < slink->totscript; script_idx++) {
-                                       slink->scripts[script_idx] = restore_pointer_by_name(newmain,
-                                               (ID *)slink->scripts[script_idx], 1);
-                               }
-                       }
-
                        for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                if(sl->spacetype==SPACE_VIEW3D) {
                                        View3D *v3d= (View3D*) sl;
@@ -4436,7 +4699,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                                        v3d->layact= v3d->localvd->layact;
                                                        MEM_freeN(v3d->localvd); 
                                                        v3d->localvd= NULL;
-                                                       v3d->localview= 0;
                                                }
                                                */
                                        }
@@ -4464,7 +4726,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                }
                                else if(sl->spacetype==SPACE_BUTS) {
                                        SpaceButs *sbuts= (SpaceButs *)sl;
-                                       sbuts->lockpoin= NULL;
                                        sbuts->pinid = restore_pointer_by_name(newmain, sbuts->pinid, 0);
                                        //XXX if (sbuts->ri) sbuts->ri->curtile = 0;
                                }
@@ -4472,13 +4733,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                        
                                        SpaceFile *sfile= (SpaceFile *)sl;
                                        sfile->files= NULL;
+                                       sfile->folders_prev= NULL;
+                                       sfile->folders_next= NULL;
                                        sfile->params= NULL;
                                        sfile->op= NULL;
-                                       /* XXX needs checking - best solve in filesel itself 
-                                       if(sfile->libfiledata)  
-                                               BLO_blendhandle_close(sfile->libfiledata);
-                                       sfile->libfiledata= 0;
-                                       */
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
                     SpaceImaSel *simasel= (SpaceImaSel *)sl;
@@ -4583,10 +4841,12 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                        rv3d->ri= NULL;
                        rv3d->sms= NULL;
                        rv3d->smooth_timer= NULL;
-                       rv3d->lastmode= 0;
                }
        }
        
+       ar->v2d.tab_offset= NULL;
+       ar->v2d.tab_num= 0;
+       ar->v2d.tab_cur= 0;
        ar->handlers.first= ar->handlers.last= NULL;
        ar->uiblocks.first= ar->uiblocks.last= NULL;
        ar->headerstr= NULL;
@@ -4615,6 +4875,10 @@ static void view3d_split_250(View3D *v3d, ListBase *regions)
                        QUATCOPY(rv3d->viewquat, v3d->viewquat);
                }
        }
+
+       /* this was not initialized correct always */
+       if(v3d->twtype == 0)
+               v3d->twtype= V3D_MANIP_TRANSLATE;
 }
 
 static void direct_link_screen(FileData *fd, bScreen *sc)
@@ -4710,6 +4974,11 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                sipo->ads= newdataadr(fd, sipo->ads);
                                sipo->ghostCurves.first= sipo->ghostCurves.last= NULL;
                        }
+                       else if (sl->spacetype==SPACE_NLA) {
+                               SpaceNla *snla= (SpaceNla*)sl;
+                               
+                               snla->ads= newdataadr(fd, snla->ads);
+                       }
                        else if (sl->spacetype==SPACE_OUTLINER) {
                                SpaceOops *soops= (SpaceOops*) sl;
                                
@@ -4744,7 +5013,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                        }
                        else if(sl->spacetype==SPACE_LOGIC) {
                                SpaceLogic *slogic= (SpaceLogic *)sl;
-                               
+                                       
                                if(slogic->gpd) {
                                        slogic->gpd= newdataadr(fd, slogic->gpd);
                                        direct_link_gpencil(fd, slogic->gpd);
@@ -4761,6 +5030,20 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                SpaceButs *sbuts= (SpaceButs *)sl;
                                sbuts->path= NULL;
                        }
+                       else if(sl->spacetype==SPACE_CONSOLE) {
+                               SpaceConsole *sconsole= (SpaceConsole *)sl;
+                               //ConsoleLine *cl;
+                               
+                               link_list(fd, &sconsole->scrollback);
+                               link_list(fd, &sconsole->history);
+                               
+                               //for(cl= sconsole->scrollback.first; cl; cl= cl->next)
+                               //      cl->line= newdataadr(fd, cl->line);
+                               
+                               //for(cl= sconsole->history.first; cl; cl= cl->next)
+                               //      cl->line= newdataadr(fd, cl->line);
+                               
+                       }
                }
                
                sa->actionzones.first= sa->actionzones.last= NULL;
@@ -4769,9 +5052,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                sa->v2= newdataadr(fd, sa->v2);
                sa->v3= newdataadr(fd, sa->v3);
                sa->v4= newdataadr(fd, sa->v4);
-
-               /* space handler scriptlinks */
-               direct_link_scriptlink(fd, &sa->scriptlink);
        }
 }
 
@@ -4844,8 +5124,7 @@ static void fix_relpaths_library(const char *basepath, Main *main)
 
 static void direct_link_sound(FileData *fd, bSound *sound)
 {
-       sound->sample = NULL;
-       sound->snd_sound = NULL;
+       sound->handle = NULL;
 
        sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
        sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
@@ -4860,7 +5139,11 @@ static void lib_link_sound(FileData *fd, Main *main)
                if(sound->id.flag & LIB_NEEDLINK) {
                        sound->id.flag -= LIB_NEEDLINK;
                        sound->ipo= newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX depreceated - old animation system
-                       sound->stream = 0;
+                       
+                       sound_load(main, sound);
+
+                       if(sound->cache)
+                               sound_cache(sound, 1);
                }
                sound= sound->id.next;
        }
@@ -5131,6 +5414,9 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
        bfd->curscene= fg->curscene;
        
        MEM_freeN(fg);
+
+       fd->globalf= bfd->globalf;
+       fd->fileflags= bfd->fileflags;
        
        return blo_nextbhead(fd, bhead);
 }
@@ -5522,7 +5808,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
                                tf = ((MTFace*)me->fdata.layers[b].data) + a;
 
                                tf->mode &= ~TF_ALPHASORT;
-                               if(ma && (ma->mode & MA_ZTRA))
+                               if(ma && (ma->mode & MA_ZTRANSP))
                                        if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
                                                tf->mode |= TF_ALPHASORT;
                        }
@@ -5544,7 +5830,7 @@ static void area_add_header_region(ScrArea *sa, ListBase *lb)
        
        /* initialise view2d data for header region, to allow panning */
        /* is copy from ui_view2d.c */
-       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
        ar->v2d.keepofs = V2D_LOCKOFS_Y;
        ar->v2d.keeptot = V2D_KEEPTOT_STRICT; 
        ar->v2d.align = V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y;
@@ -5565,6 +5851,14 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                ar->regiontype= RGN_TYPE_CHANNELS;
                                ar->alignment= RGN_ALIGN_LEFT; 
                                ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
+                               
+                                       // for some reason, this doesn't seem to go auto like for NLA...
+                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               BLI_addtail(lb, ar);
+                               ar->regiontype= RGN_TYPE_UI;
+                               ar->alignment= RGN_ALIGN_RIGHT;
+                               ar->v2d.scroll= V2D_SCROLL_RIGHT;
+                               ar->v2d.flag = RGN_FLAG_HIDDEN;
                                break;
                                
                        case SPACE_ACTION:
@@ -5595,21 +5889,17 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                /* temporarily hide it */
                                ar->flag = RGN_FLAG_HIDDEN;
                                break;
-                               
                        case SPACE_FILE:
-                               /* channel (bookmarks/directories) region */
-                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+                               ar= MEM_callocN(sizeof(ARegion), "nodetree area for node");
                                BLI_addtail(lb, ar);
                                ar->regiontype= RGN_TYPE_CHANNELS;
                                ar->alignment= RGN_ALIGN_LEFT;
-                               ar->v2d.scroll= V2D_SCROLL_RIGHT;
-                               /* button UI region */
-                               ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
+
+                               ar= MEM_callocN(sizeof(ARegion), "ui area for file");
                                BLI_addtail(lb, ar);
                                ar->regiontype= RGN_TYPE_UI;
                                ar->alignment= RGN_ALIGN_TOP;
                                break;
-
 #if 0
                        case SPACE_BUTS:
                                /* context UI region */
@@ -5741,13 +6031,15 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                memcpy(&ar->v2d, &snode->v2d, sizeof(View2D));
                                
                                ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
-                               ar->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+                               ar->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
                                break;
                        }
                        case SPACE_BUTS:
                        {
                                SpaceButs *sbuts= (SpaceButs *)sl;
                                memcpy(&ar->v2d, &sbuts->v2d, sizeof(View2D));
+                               
+                               ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM); 
                                break;
                        }
                        case SPACE_FILE:
@@ -5760,7 +6052,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                ar->regiontype= RGN_TYPE_WINDOW;
                                ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
                                ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
-                               ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
                                break;
                        }
                        case SPACE_TEXT:
@@ -6164,7 +6456,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
 
        if(main->versionfile <= 191) {
-               bScreen *sc= main->screen.first;
                Object *ob= main->object.first;
                Material *ma = main->mat.first;
 
@@ -6180,22 +6471,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        /*ob->quat[1]= 1.0f;*/ /* quats arnt used yet */
                        ob= ob->id.next;
                }
-
-               while(sc) {
-                       ScrArea *sa= sc->areabase.first;
-                       while(sa) {
-                               SpaceLink *sl= sa->spacedata.first;
-                               while(sl) {
-                                       if(sl->spacetype==SPACE_BUTS) {
-                                               SpaceButs *sbuts= (SpaceButs*) sl;
-                                               sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK;
-                                       }
-                                       sl= sl->next;
-                               }
-                               sa= sa->next;
-                       }
-                       sc= sc->id.next;
-               }
        }
 
        if(main->versionfile <= 193) {
@@ -8108,7 +8383,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        simasel->v2d.minzoom= 0.5f;
                                                        simasel->v2d.maxzoom= 1.21f;                                            
                                                        simasel->v2d.scroll= 0;
-                                                       simasel->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+                                                       simasel->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
                                                        simasel->v2d.keeptot= 0;
                                                        simasel->prv_h = 96;
                                                        simasel->prv_w = 96;
@@ -8128,20 +8403,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                /* add point caches */
                for(ob=main->object.first; ob; ob=ob->id.next) {
                        if(ob->soft && !ob->soft->pointcache)
-                               ob->soft->pointcache= BKE_ptcache_add();
+                               ob->soft->pointcache= BKE_ptcache_add(&ob->soft->ptcaches);
 
                        for(psys=ob->particlesystem.first; psys; psys=psys->next) {
-                               if(psys->soft && !psys->soft->pointcache)
-                                       psys->soft->pointcache= BKE_ptcache_add();
+                               //if(psys->soft && !psys->soft->pointcache)
+                               //      psys->soft->pointcache= BKE_ptcache_add(&psys->soft->ptcaches);
                                if(!psys->pointcache)
-                                       psys->pointcache= BKE_ptcache_add();
+                                       psys->pointcache= BKE_ptcache_add(&psys->ptcaches);
                        }
 
                        for(md=ob->modifiers.first; md; md=md->next) {
                                if(md->type==eModifierType_Cloth) {
                                        ClothModifierData *clmd = (ClothModifierData*) md;
                                        if(!clmd->point_cache)
-                                               clmd->point_cache= BKE_ptcache_add();
+                                               clmd->point_cache= BKE_ptcache_add(&clmd->ptcaches);
                                }
                        }
                }
@@ -8429,9 +8704,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                /* create new particle system */
                                psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
-                               psys->pointcache = BKE_ptcache_add();
+                               psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
 
-                               part = psys->part = psys_new_settings("PSys", main);
+                               part = psys->part = psys_new_settings("ParticleSettings", main);
                                
                                /* needed for proper libdata lookup */
                                oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
@@ -9007,13 +9282,78 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        if (main->versionfile < 250) {
                bScreen *screen;
                Scene *scene;
+               Base *base;
                Material *ma;
+               Camera *cam;
                Mesh *me;
+               Curve *cu;
                Scene *sce;
                Tex *tx;
                ParticleSettings *part;
                Object *ob;
-               
+               //PTCacheID *pid;
+               //ListBase pidlist;
+
+               bSound *sound;
+               Sequence *seq;
+               bActuator *act;
+
+               for(sound = main->sound.first; sound; sound = sound->id.next)
+               {
+                       if(sound->newpackedfile)
+                       {
+                               sound->packedfile = sound->newpackedfile;
+                               sound->newpackedfile = NULL;
+                       }
+               }
+
+               for(ob = main->object.first; ob; ob= ob->id.next) {
+                       for(act= ob->actuators.first; act; act= act->next) {
+                               if (act->type == ACT_SOUND) {
+                                       bSoundActuator *sAct = (bSoundActuator*) act->data;
+                                       if(sAct->sound)
+                                       {
+                                               sound = newlibadr(fd, lib, sAct->sound);
+                                               sAct->flag = sound->flags | SOUND_FLAGS_3D ? ACT_SND_3D_SOUND : 0;
+                                               sAct->pitch = sound->pitch;
+                                               sAct->volume = sound->volume;
+                                               sAct->sound3D.reference_distance = sound->distance;
+                                               sAct->sound3D.max_gain = sound->max_gain;
+                                               sAct->sound3D.min_gain = sound->min_gain;
+                                               sAct->sound3D.rolloff_factor = sound->attenuation;
+                                       }
+                                       else
+                                       {
+                                               sAct->sound3D.reference_distance = 1.0f;
+                                               sAct->volume = 1.0f;
+                                               sAct->sound3D.max_gain = 1.0f;
+                                               sAct->sound3D.rolloff_factor = 1.0f;
+                                       }
+                                       sAct->sound3D.cone_inner_angle = 360.0f;
+                                       sAct->sound3D.cone_outer_angle = 360.0f;
+                                       sAct->sound3D.max_distance = FLT_MAX;
+                               }
+                       }
+               }
+
+               for(scene = main->scene.first; scene; scene = scene->id.next)
+               {
+                       if(scene->ed && scene->ed->seqbasep)
+                       {
+                               for(seq = scene->ed->seqbasep->first; seq; seq = seq->next)
+                               {
+                                       if(seq->type == SEQ_HD_SOUND)
+                                       {
+                                               char str[FILE_MAX];
+                                               BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
+                                               BLI_convertstringcode(str, G.sce);
+                                               BLI_convertstringframe(str, scene->r.cfra);
+                                               seq->sound = sound_new_file(main, str);
+                                       }
+                               }
+                       }
+               }
+
                for(screen= main->screen.first; screen; screen= screen->id.next) {
                        do_versions_windowmanager_2_50(screen);
                        do_versions_gpencil_2_50(main, screen);
@@ -9024,14 +9364,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                 */
                //do_versions_ipos_to_animato(main);
                
-               /* struct audio data moved to renderdata */
-               for(scene= main->scene.first; scene; scene= scene->id.next) {
-                       scene->r.audio = scene->audio;
-                       
-                       if(!scene->toolsettings->uv_selectmode)
-                               scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
-               }
-               
                /* shader, composit and texture node trees have id.name empty, put something in
                 * to have them show in RNA viewer and accessible otherwise.
                 */
@@ -9043,6 +9375,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                for(sce= main->scene.first; sce; sce= sce->id.next) {
                        if(sce->nodetree && strlen(sce->nodetree->id.name)==0)
                                strcpy(sce->nodetree->id.name, "NTComposit Nodetree");
+
+                       /* move to cameras */
+                       if(sce->r.mode & R_PANORAMA) {
+                               for(base=sce->base.first; base; base=base->next) {
+                                       ob= newlibadr(fd, lib, base->object);
+
+                                       if(ob->type == OB_CAMERA && !ob->id.lib) {
+                                               cam= newlibadr(fd, lib, ob->data);
+                                               cam->flag |= CAM_PANORAMA;
+                                       }
+                               }
+
+                               sce->r.mode &= ~R_PANORAMA;
+                       }
                }
                /* and texture trees */
                for(tx= main->tex.first; tx; tx= tx->id.next) {
@@ -9070,37 +9416,57 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        part->draw_as = PART_DRAW_REND;
                                }
                        }
+                       part->path_end = 1.0f;
+                       part->clength = 1.0f;
                }
                /* set old pointcaches to have disk cache flag */
                for(ob = main->object.first; ob; ob= ob->id.next) {
-                       ParticleSystem *psys = ob->particlesystem.first;
 
-                       for(; psys; psys=psys->next) {
-                               if(psys->pointcache)
-                                       psys->pointcache->flag |= PTCACHE_DISK_CACHE;
-                       }
+                       //BKE_ptcache_ids_from_object(&pidlist, ob);
+
+                       //for(pid=pidlist.first; pid; pid=pid->next)
+                       //      pid->cache->flag |= PTCACHE_DISK_CACHE;
+
+                       //BLI_freelistN(&pidlist);
+               }
 
-                       /* TODO: softbody & cloth caches */
+               /* type was a mixed flag & enum. move the 2d flag elsewhere */
+               for(cu = main->curve.first; cu; cu= cu->id.next) {
+                       Nurb *nu;
+
+                       for(nu= cu->nurb.first; nu; nu= nu->next) {
+                               nu->flag |= (nu->type & CU_2D);
+                               nu->type &= CU_TYPE;
+                       }
                }
        }
 
-       /* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
-          bump the version (or sub-version.) */
-       {
+       if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) {
                Object *ob;
                Material *ma;
+               Tex *tex;
                Scene *sce;
                ToolSettings *ts;
-               int i;
+               //PTCacheID *pid;
+               //ListBase pidlist;
+               int i, a;
 
                for(ob = main->object.first; ob; ob = ob->id.next) {
+                       //BKE_ptcache_ids_from_object(&pidlist, ob);
+
+                       //for(pid=pidlist.first; pid; pid=pid->next) {
+                       //      if(pid->ptcaches->first == NULL)
+                       //              pid->ptcaches->first = pid->ptcaches->last = pid->cache;
+                       //}
+
+                       //BLI_freelistN(&pidlist);
 
                        if(ob->type == OB_MESH) {
                                Mesh *me = newlibadr(fd, lib, ob->data);
                                void *olddata = ob->data;
                                ob->data = me;
 
-                               if(me && me->mr) {
+                               if(me && me->id.lib==NULL && me->mr) { /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid -  Campbell */
                                        MultiresLevel *lvl;
                                        ModifierData *md;
                                        MultiresModifierData *mmd;
@@ -9140,7 +9506,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                        mmd->lvl = mmd->totlvl;
                                        orig = CDDM_from_mesh(me, NULL);
-                                       dm = multires_dm_create_from_derived(mmd, orig, me, 0, 0);
+                                       dm = multires_dm_create_from_derived(mmd, 0, orig, ob, 0, 0);
                                        
                                        multires_load_old(dm, me->mr);
 
@@ -9155,22 +9521,208 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                ob->data = olddata;
                        }
+
+                       if(ob->totcol && ob->matbits == NULL) {
+                               int a;
+
+                               ob->matbits= MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
+                               for(a=0; a<ob->totcol; a++)
+                                       ob->matbits[a]= ob->colbits & (1<<a);
+                       }
+               }
+
+               /* texture filter */
+               for(tex = main->tex.first; tex; tex = tex->id.next) {
+                       if(tex->afmax == 0)
+                               tex->afmax= 8;
                }
 
                for(ma = main->mat.first; ma; ma = ma->id.next) {
+                       if(ma->mode & MA_WIRE) {
+                               ma->material_type= MA_TYPE_WIRE;
+                               ma->mode &= ~MA_WIRE;
+                       }
                        if(ma->mode & MA_HALO) {
                                ma->material_type= MA_TYPE_HALO;
                                ma->mode &= ~MA_HALO;
                        }
+
+                       if(ma->mode & (MA_ZTRANSP|MA_RAYTRANSP)) {
+                               ma->mode |= MA_TRANSP;
+                       }
+                       else {
+                               ma->mode |= MA_ZTRANSP;
+                               ma->mode &= ~MA_TRANSP;
+                       }
+
+                       /* set new bump for unused slots */
+                       for(a=0; a<MAX_MTEX; a++) {
+                               if(ma->mtex[a]) {
+                                       tex= ma->mtex[a]->tex;
+                                       if(!tex)
+                                               ma->mtex[a]->texflag |= MTEX_NEW_BUMP;
+                                       else {
+                                               tex= (Tex*)newlibadr(fd, ma->id.lib, tex);
+                                               if(tex && tex->type == 0) /* invalid type */
+                                                       ma->mtex[a]->texflag |= MTEX_NEW_BUMP;
+                                       }
+                               }
+                       }
+                       
+                       /* volume rendering settings */
+                       if (ma->vol.stepsize < 0.0001f) {
+                               ma->vol.density = 1.0f;
+                               ma->vol.emission = 0.0f;
+                               ma->vol.absorption = 1.0f;
+                               ma->vol.scattering = 1.0f;
+                               ma->vol.emission_col[0] = ma->vol.emission_col[1] = ma->vol.emission_col[2] = 1.0f;
+                               ma->vol.absorption_col[0] = ma->vol.absorption_col[1] = ma->vol.absorption_col[2] = 0.0f;
+                               ma->vol.density_scale = 1.0f;
+                               ma->vol.depth_cutoff = 0.01f;
+                               ma->vol.stepsize_type = MA_VOL_STEP_RANDOMIZED;
+                               ma->vol.stepsize = 0.2f;
+                               ma->vol.shade_stepsize = 0.2f;
+                               ma->vol.shade_type = MA_VOL_SHADE_SINGLE;
+                               ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
+                               ma->vol.precache_resolution = 50;
+                       }
                }
 
                for(sce = main->scene.first; sce; sce = sce->id.next) {
                        ts= sce->toolsettings;
-                       if(ts->normalsize == 0.0) {
+                       if(ts->normalsize == 0.0 || !ts->uv_selectmode || ts->vgroup_weight == 0.0) {
                                ts->normalsize= 0.1f;
                                ts->selectmode= SCE_SELECT_VERTEX;
+                               
+                               /* autokeying - setting should be taken from the user-prefs
+                                * but the userprefs version may not have correct flags set 
+                                * (i.e. will result in blank box when enabled)
+                                */
                                ts->autokey_mode= U.autokey_mode;
+                               if (ts->autokey_mode == 0) 
+                                       ts->autokey_mode= 2; /* 'add/replace' but not on */
+                               ts->uv_selectmode= UV_SELECT_VERTEX;
+                               ts->vgroup_weight= 1.0f;
+                       }
+
+                       /* Game Settings */
+                       //Dome
+                       sce->gm.dome.angle = sce->r.domeangle;
+                       sce->gm.dome.mode = sce->r.domemode;
+                       sce->gm.dome.res = sce->r.domeres;
+                       sce->gm.dome.resbuf = sce->r.domeresbuf;
+                       sce->gm.dome.tilt = sce->r.dometilt;
+                       sce->gm.dome.warptext = sce->r.dometext;
+
+                       //Stand Alone
+                       sce->gm.fullscreen = sce->r.fullscreen;
+                       sce->gm.xplay = sce->r.xplay;
+                       sce->gm.yplay = sce->r.yplay;
+                       sce->gm.freqplay = sce->r.freqplay;
+                       sce->gm.depth = sce->r.depth;
+                       sce->gm.attrib = sce->r.attrib;
+
+                       //Stereo
+                       sce->gm.xsch = sce->r.xsch;
+                       sce->gm.ysch = sce->r.ysch;
+                       sce->gm.stereomode = sce->r.stereomode;
+                       /* reassigning stereomode NO_STEREO and DOME to a separeted flag*/
+                       if (sce->gm.stereomode == 1){ //1 = STEREO_NOSTEREO
+                               sce->gm.stereoflag = STEREO_NOSTEREO;
+                               sce->gm.stereomode = STEREO_ANAGLYPH;
+                       }
+                       else if(sce->gm.stereomode == 8){ //8 = STEREO_DOME
+                               sce->gm.stereoflag = STEREO_DOME;
+                               sce->gm.stereomode = STEREO_ANAGLYPH;
                        }
+                       else
+                               sce->gm.stereoflag = STEREO_ENABLED;
+
+                       //Framing
+                       sce->gm.framing = sce->framing;
+                       sce->gm.xplay = sce->r.xplay;
+                       sce->gm.yplay = sce->r.yplay;
+                       sce->gm.freqplay= sce->r.freqplay;
+                       sce->gm.depth= sce->r.depth;
+
+                       //Physic (previously stored in world)
+                       sce->gm.gravity =9.8f;
+                       sce->gm.physicsEngine= WOPHY_BULLET;// Bullet by default
+                       sce->gm.mode = WO_DBVT_CULLING; // DBVT culling by default
+                       sce->gm.occlusionRes = 128;
+                       sce->gm.ticrate = 60;
+                       sce->gm.maxlogicstep = 5;
+                       sce->gm.physubstep = 1;
+                       sce->gm.maxphystep = 5;
+               }
+       }
+
+       if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 2)) {
+               Scene *sce;
+               Object *ob;
+
+               for(sce = main->scene.first; sce; sce = sce->id.next) {
+                       if(fd->fileflags & G_FILE_ENABLE_ALL_FRAMES)
+                               sce->gm.flag |= GAME_ENABLE_ALL_FRAMES;
+                       if(fd->fileflags & G_FILE_SHOW_DEBUG_PROPS)
+                               sce->gm.flag |= GAME_SHOW_DEBUG_PROPS;
+                       if(fd->fileflags & G_FILE_SHOW_FRAMERATE)
+                               sce->gm.flag |= GAME_SHOW_FRAMERATE;
+                       if(fd->fileflags & G_FILE_SHOW_PHYSICS)
+                               sce->gm.flag |= GAME_SHOW_PHYSICS;
+                       if(fd->fileflags & G_FILE_GLSL_NO_SHADOWS)
+                               sce->gm.flag |= GAME_GLSL_NO_SHADOWS;
+                       if(fd->fileflags & G_FILE_GLSL_NO_SHADERS)
+                               sce->gm.flag |= GAME_GLSL_NO_SHADERS;
+                       if(fd->fileflags & G_FILE_GLSL_NO_RAMPS)
+                               sce->gm.flag |= GAME_GLSL_NO_RAMPS;
+                       if(fd->fileflags & G_FILE_GLSL_NO_NODES)
+                               sce->gm.flag |= GAME_GLSL_NO_NODES;
+                       if(fd->fileflags & G_FILE_GLSL_NO_EXTRA_TEX)
+                               sce->gm.flag |= GAME_GLSL_NO_EXTRA_TEX;
+                       if(fd->fileflags & G_FILE_IGNORE_DEPRECATION_WARNINGS)
+                               sce->gm.flag |= GAME_IGNORE_DEPRECATION_WARNINGS;
+
+                       if(fd->fileflags & G_FILE_GAME_MAT_GLSL)
+                               sce->gm.matmode= GAME_MAT_GLSL;
+                       else if(fd->fileflags & G_FILE_GAME_MAT)
+                               sce->gm.matmode= GAME_MAT_MULTITEX;
+                       else
+                               sce->gm.matmode= GAME_MAT_TEXFACE;
+
+                       sce->gm.flag |= GAME_DISPLAY_LISTS;
+               }
+               
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       if(ob->flag & 8192) // OB_POSEMODE = 8192
+                               ob->mode |= OB_MODE_POSE;
+               }
+       }
+
+       /* put 2.50 compatibility code here until next subversion bump */
+       {
+               Scene *sce;
+               Object *ob;
+
+               for(sce = main->scene.first; sce; sce = sce->id.next)
+                       if(sce->unit.scale_length == 0.0f)
+                               sce->unit.scale_length= 1.0f;
+               
+               for(ob = main->object.first; ob; ob = ob->id.next) {
+                       FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+                       if (fluidmd) fluidmd->fss->fmd = fluidmd;
+               }
+
+               for(sce= main->scene.first; sce; sce= sce->id.next)
+               {
+                       if(sce->audio.main == 0.0)
+                               sce->audio.main = 1.0;
+
+                       sce->r.ffcodecdata.audio_mixrate = sce->audio.mixrate;
+                       sce->r.ffcodecdata.audio_volume = sce->audio.main;
+                       sce->audio.distance_model = 2.0;
+                       sce->audio.doppler_factor = 1.0;
+                       sce->audio.speed_of_sound = 343.3;
                }
        }
 
@@ -9224,7 +9776,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
        // XXX
        bfd->user->uifonts.first= bfd->user->uifonts.last= NULL;
        bfd->user->uistyles.first= bfd->user->uistyles.last= NULL;
-       
+
        bhead = blo_nextbhead(fd, bhead);
 
                /* read all attached data */
@@ -9237,7 +9789,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
        return bhead;
 }
 
-BlendFileData *blo_read_file_internal(FileData *fd)
+BlendFileData *blo_read_file_internal(FileData *fd, char *file)
 {
        BHead *bhead= blo_firstbhead(fd);
        BlendFileData *bfd;
@@ -9248,6 +9800,9 @@ BlendFileData *blo_read_file_internal(FileData *fd)
 
        bfd->main->versionfile= fd->fileversion;
        
+       bfd->type= BLENFILETYPE_BLEND;
+       strncpy(bfd->main->name, file, sizeof(bfd->main->name)-1);
+
        while(bhead) {
                switch(bhead->code) {
                case DATA:
@@ -9502,12 +10057,27 @@ static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list)
        }
 }
 
+static void expand_animdata_nlastrips(FileData *fd, Main *mainvar, ListBase *list)
+{
+       NlaStrip *strip;
+       
+       for (strip= list->first; strip; strip= strip->next) {
+               /* check child strips */
+               expand_animdata_nlastrips(fd, mainvar, &strip->strips);
+               
+               /* relink referenced action */
+               expand_doit(fd, mainvar, strip->act);
+       }
+}
+
 static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
 {
        FCurve *fcd;
+       NlaTrack *nlt;
        
        /* own action */
        expand_doit(fd, mainvar, adt->action);
+       expand_doit(fd, mainvar, adt->tmpact);
        
        /* drivers - assume that these F-Curves have driver data to be in this list... */
        for (fcd= adt->drivers.first; fcd; fcd= fcd->next) {
@@ -9517,6 +10087,10 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
                for (dtar= driver->targets.first; dtar; dtar= dtar->next)
                        expand_doit(fd, mainvar, dtar->id);
        }
+       
+       /* nla-data - referenced actions */
+       for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) 
+               expand_animdata_nlastrips(fd, mainvar, &nlt->strips);
 }      
 
 static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
@@ -9526,7 +10100,8 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
        expand_doit(fd, mainvar, part->eff_group);
        expand_doit(fd, mainvar, part->bb_ob);
        
-       expand_animdata(fd, mainvar, part->adt);
+       if(part->adt)
+               expand_animdata(fd, mainvar, part->adt);
 }
 
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
@@ -9650,6 +10225,9 @@ static void expand_mball(FileData *fd, Main *mainvar, MetaBall *mb)
        for(a=0; a<mb->totcol; a++) {
                expand_doit(fd, mainvar, mb->mat[a]);
        }
+       
+       if(mb->adt)
+               expand_animdata(fd, mainvar, mb->adt);
 }
 
 static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
@@ -9861,6 +10439,9 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
 {
        Bone *curBone;
 
+       if(arm->adt)
+               expand_animdata(fd, mainvar, arm->adt);
+
        for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
                expand_bones(fd, mainvar, curBone);
        }
@@ -9895,14 +10476,15 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
                expand_doit(fd, mainvar, dmd->map_object);
                expand_doit(fd, mainvar, dmd->texture);
        }
-}
-
-static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
-{
-       int i;
-       
-       for(i=0; i<slink->totscript; i++) {
-               expand_doit(fd, mainvar, slink->scripts[i]);
+       else if (md->type==eModifierType_Smoke) {
+               SmokeModifierData *smd = (SmokeModifierData*) md;
+                       
+               if(smd->type==MOD_SMOKE_TYPE_DOMAIN && smd->domain)
+               {       
+                       expand_doit(fd, mainvar, smd->domain->coll_group);
+                       expand_doit(fd, mainvar, smd->domain->fluid_group);
+                       expand_doit(fd, mainvar, smd->domain->eff_group);
+               }
        }
 }
 
@@ -9928,6 +10510,8 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
        expand_doit(fd, mainvar, ob->poselib);
        expand_constraints(fd, mainvar, &ob->constraints);
        
+       expand_doit(fd, mainvar, ob->gpd);
+       
 // XXX depreceated - old animation system (for version patching only) 
        expand_doit(fd, mainvar, ob->ipo);
        expand_doit(fd, mainvar, ob->action);
@@ -10006,11 +10590,19 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bObjectActuator *oa= act->data;
                        expand_doit(fd, mainvar, oa->reference);
                }
+               else if(act->type==ACT_ADD_OBJECT) {
+                       bAddObjectActuator *aoa= act->data;
+                       expand_doit(fd, mainvar, aoa->ob);
+               }
                else if(act->type==ACT_SCENE) {
                        bSceneActuator *sa= act->data;
                        expand_doit(fd, mainvar, sa->camera);
                        expand_doit(fd, mainvar, sa->scene);
                }
+               else if(act->type==ACT_2DFILTER) {
+                       bTwoDFilterActuator *tdfa= act->data;
+                       expand_doit(fd, mainvar, tdfa->text);
+               }
                else if(act->type==ACT_ACTION) {
                        bActionActuator *aa= act->data;
                        expand_doit(fd, mainvar, aa->act);
@@ -10027,13 +10619,20 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
                        bMessageActuator *ma= act->data;
                        expand_doit(fd, mainvar, ma->toObject);
                }
+               else if(act->type==ACT_PARENT) {
+                       bParentActuator *pa= act->data;
+                       expand_doit(fd, mainvar, pa->ob);
+               }
+               else if(act->type==ACT_ARMATURE) {
+                       bArmatureActuator *arma= act->data;
+                       expand_doit(fd, mainvar, arma->target);
+               }
                act= act->next;
        }
 
        if(ob->pd && ob->pd->tex)
                expand_doit(fd, mainvar, ob->pd->tex);
        
-       expand_scriptlink(fd, mainvar, &ob->scriptlink);
 }
 
 static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
@@ -10063,7 +10662,10 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
        }
 
        if(sce->r.dometext)
-               expand_doit(fd, mainvar, sce->r.dometext);
+               expand_doit(fd, mainvar, sce->gm.dome.warptext);
+               
+       if(sce->gpd)
+               expand_doit(fd, mainvar, sce->gpd);
 }
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
@@ -10224,8 +10826,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, int is
 }
 
 
-static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *name, int idcode, short flag)
+static void append_named_part(const bContext *C, Main *mainl, FileData *fd, char *name, int idcode, short flag)
 {
+       Scene *scene= CTX_data_scene(C);
        Object *ob;
        Base *base;
        BHead *bhead;
@@ -10241,9 +10844,9 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                
                        if(strcmp(idname+2, name)==0) {
 
-                               id= is_yet_read(fd, mainvar, bhead);
+                               id= is_yet_read(fd, mainl, bhead);
                                if(id==NULL) {
-                                       read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
+                                       read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
                                }
                                else {
                                        printf("append: already linked\n");
@@ -10254,17 +10857,22 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        }
                                }
 
-                               if(idcode==ID_OB) {     /* loose object: give a base */
+                               if(idcode==ID_OB && scene) {    /* loose object: give a base */
                                        base= MEM_callocN( sizeof(Base), "app_nam_part");
                                        BLI_addtail(&scene->base, base);
 
-                                       if(id==NULL) ob= mainvar->object.last;
+                                       if(id==NULL) ob= mainl->object.last;
                                        else ob= (Object *)id;
                                        
-                                       /* XXX use context to find view3d->lay */
-                                       //if((flag & FILE_ACTIVELAY)) {
-                                       //      scene->lay;
-                                       //}
+                                       /* link at active layer (view3d->lay if in context, else scene->lay */
+                                       if((flag & FILE_ACTIVELAY)) {
+                                               View3D *v3d = CTX_wm_view3d(C);
+                                               if (v3d) {
+                                                       ob->lay = v3d->layact;
+                                               } else {
+                                                       ob->lay = scene->lay;
+                                               }
+                                       }
                                        base->lay= ob->lay;
                                        base->object= ob;
                                        ob->id.us++;
@@ -10283,6 +10891,12 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
        }
 }
 
+void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, char *name, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       append_named_part(C, mainl, fd, name, idcode, flag);
+}
+
 static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 {
        BHead *bhead;
@@ -10305,11 +10919,10 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
 /* common routine to append/link something from a library */
 
-static Library* library_append(Main *mainvar, Scene *scene, char* file, char *dir, int idcode,
-               int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
+static Main* library_append_begin(const bContext *C, FileData **fd, char *dir)
 {
+       Main *mainvar= CTX_data_main(C);
        Main *mainl;
-       Library *curlib;
 
        /* make mains */
        blo_split_main(&(*fd)->mainlist, mainvar);
@@ -10319,19 +10932,69 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        
        mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
        
-       curlib= mainl->curlib;
+       return mainl;
+}
+
+Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, char *dir)
+{
+       FileData *fd= (FileData*)(*bh);
+       return library_append_begin(C, &fd, dir);
+}
+
+static void append_do_cursor(Scene *scene, Library *curlib, short flag)
+{
+       Base *centerbase;
+       Object *ob;
+       float *curs, centerloc[3], vec[3], min[3], max[3];
+       int count= 0;
+
+       /* when not linking (appending)... */
+       if(flag & FILE_LINK) 
+               return;
+
+       /* we're not appending at cursor */
+       if((flag & FILE_ATCURSOR) == 0) 
+               return;
        
-       if(totsel==0) {
-               append_named_part(*fd, mainl, scene, file, idcode, flag);
+       /* find the center of everything appended */
+       INIT_MINMAX(min, max);
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       VECCOPY(vec, centerbase->object->loc);
+                       DO_MINMAX(vec, min, max);
+                       count++;
+               }
+               centerbase= centerbase->next;
        }
-       else {
-               int a;
-               for(a=0; a<totfile; a++) {
-                       if(filelist[a].flags & ACTIVE) {
-                               append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
-                       }
+       /* we haven't found any objects to move to cursor */
+       if(!count) 
+               return;
+       
+       /* move from the center of the appended objects to cursor */
+       centerloc[0]= (min[0]+max[0])/2;
+       centerloc[1]= (min[1]+max[1])/2;
+       centerloc[2]= (min[2]+max[2])/2;
+       curs = scene->cursor;
+       VECSUB(centerloc,curs,centerloc);
+       
+       /* now translate the center of the objects */
+       centerbase= (scene->base.first);
+       while(centerbase) {
+               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
+                       ob= centerbase->object;
+                       ob->loc[0] += centerloc[0];
+                       ob->loc[1] += centerloc[1];
+                       ob->loc[2] += centerloc[2];
                }
+               centerbase= centerbase->next;
        }
+}
+
+static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
+{
+       Main *mainvar= CTX_data_main(C);
+       Scene *scene= CTX_data_scene(C);
 
        /* make main consistant */
        expand_main(*fd, mainl);
@@ -10339,6 +11002,7 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        /* do this when expand found other libs */
        read_libraries(*fd, &(*fd)->mainlist);
 
+       /* make the lib path relative if required */
        if(flag & FILE_STRINGCODE) {
 
                /* use the full path, this could have been read by other library even */
@@ -10356,14 +11020,16 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
        fix_relpaths_library(G.sce, mainvar); /* make all relative paths, relative to the open blend file */
 
        /* give a base to loose objects. If group append, do it for objects too */
-       if(idcode==ID_GR) {
-               if (flag & FILE_LINK) {
-                       give_base_to_objects(mainvar, scene, NULL, 0);
+       if(scene) {
+               if(idcode==ID_GR) {
+                       if (flag & FILE_LINK) {
+                               give_base_to_objects(mainvar, scene, NULL, 0);
+                       } else {
+                               give_base_to_objects(mainvar, scene, mainl->curlib, 1);
+                       }       
                } else {
-                       give_base_to_objects(mainvar, scene, curlib, 1);
-               }       
-       } else {
-               give_base_to_objects(mainvar, scene, NULL, 0);
+                       give_base_to_objects(mainvar, scene, NULL, 0);
+               }
        }
        /* has been removed... erm, why? s..ton) */
        /* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
@@ -10375,14 +11041,23 @@ static Library* library_append(Main *mainvar, Scene *scene, char* file, char *di
                *fd = NULL;
        }       
 
-       return curlib;
+       append_do_cursor(scene, mainl->curlib, flag);
+}
+
+void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
+{
+       FileData *fd= (FileData*)(*bh);
+       library_append_end(C, mainl, &fd, idcode, flag);
+       *bh= (BlendHandle*)fd;
 }
 
 /* this is a version of BLO_library_append needed by the BPython API, so
  * scripts can load data from .blend files -- see Blender.Library module.*/
 /* append to scene */
 /* this should probably be moved into the Python code anyway */
-
+/* tentatively removed, Python should be able to use the split functions too: */
+/* BLO_library_append_begin, BLO_library_append_end, BLO_library_append_named_part */
+#if 0 
 void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, 
                int idcode, short flag, Main *mainvar, Scene *scene, ReportList *reports)
 {
@@ -10394,92 +11069,12 @@ void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
        if(fd) fd->reports= NULL;
 
        /* do we need to do this? */
-       DAG_scene_sort(scene);
+       if(scene)
+               DAG_scene_sort(scene);
 
        *bh= (BlendHandle*)fd;
 }
-
-/* append to scene */
-void BLO_library_append(BlendHandle** bh, struct direntry* filelist, int totfile, 
-                                                char *dir, char* file, short flag, int idcode, Main *mainvar, Scene *scene, ReportList *reports)
-{
-       FileData *fd= (FileData*)(*bh);
-       Library *curlib;
-       Base *centerbase;
-       Object *ob;
-       int a, totsel=0;
-       
-       /* are there files selected? */
-       for(a=0; a<totfile; a++) {
-               if(filelist[a].flags & ACTIVE) {
-                       totsel++;
-               }
-       }
-
-       if(totsel==0) {
-               /* is the indicated file in the filelist? */
-               if(file[0]) {
-                       for(a=0; a<totfile; a++) {
-                               if( strcmp(filelist[a].relname, file)==0) break;
-                       }
-                       if(a==totfile) {
-                               BKE_report(reports, RPT_ERROR, "Wrong indicated name");
-                               return;
-                       }
-               }
-               else {
-                       BKE_report(reports, RPT_ERROR, "Nothing indicated");
-                       return;
-               }
-       }
-       /* now we have or selected, or an indicated file */
-       
-       if(flag & FILE_AUTOSELECT) scene_deselect_all(scene);
-
-       fd->reports= reports;
-       curlib = library_append(mainvar, scene, file, dir, idcode, totsel, &fd, filelist, totfile,flag );
-       if(fd) fd->reports= NULL;
-
-       *bh= (BlendHandle*)fd;
-
-       /* when not linking (appending)... */
-       if((flag & FILE_LINK)==0) {
-               if(flag & FILE_ATCURSOR) {
-                       float *curs, centerloc[3], vec[3], min[3], max[3];
-                       int count= 0;
-                       
-                       INIT_MINMAX(min, max);
-                       
-                       centerbase= (scene->base.first);
-                       while(centerbase) {
-                               if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                       VECCOPY(vec, centerbase->object->loc);
-                                       DO_MINMAX(vec, min, max);
-                                       count++;
-                               }
-                               centerbase= centerbase->next;
-                       }
-                       if(count) {
-                               centerloc[0]= (min[0]+max[0])/2;
-                               centerloc[1]= (min[1]+max[1])/2;
-                               centerloc[2]= (min[2]+max[2])/2;
-                               curs = scene->cursor;
-                               VECSUB(centerloc,curs,centerloc);
-                       
-                               centerbase= (scene->base.first);
-                               while(centerbase) {
-                                       if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
-                                               ob= centerbase->object;
-                                               ob->loc[0] += centerloc[0];
-                                               ob->loc[1] += centerloc[1];
-                                               ob->loc[2] += centerloc[2];
-                                       }
-                                       centerbase= centerbase->next;
-                               }
-                       }
-               }
-       }
-}
+#endif
 
 /* ************* READ LIBRARY ************** */
 
@@ -10523,9 +11118,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
 
                                        printf("read library: lib %s\n", mainptr->curlib->name);
                                        fd= blo_openblenderfile(mainptr->curlib->filename, &reports);
-                                       fd->reports= basefd->reports;
 
                                        if (fd) {
+                                               fd->reports= basefd->reports;
+                                               
                                                if (fd->libmap)
                                                        oldnewmap_free(fd->libmap);
 
@@ -10639,7 +11235,7 @@ BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize,
                return NULL;
 
        fd->reports= reports;
-       bfd= blo_read_file_internal(fd);
+       bfd= blo_read_file_internal(fd, "");
        blo_freefiledata(fd);
 
        return bfd;