Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / source / blender / blenloader / intern / writefile.c
index ef1e7d7..fda35d2 100644 (file)
@@ -72,27 +72,28 @@ Any case: direct data is ALWAYS after the lib block
 #include <config.h>
 #endif
 
+#include <math.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
 #include "zlib.h"
 
 #ifndef WIN32
 #include <unistd.h>
 #else
 #include "winsock2.h"
-#include "BLI_winstuff.h"
 #include <io.h>
 #include <process.h> // for getpid
+#include "BLI_winstuff.h"
 #endif
 
-#include <math.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
 #include "DNA_anim_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_action_types.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"
@@ -129,6 +130,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "DNA_sdna_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_sensor_types.h"
+#include "DNA_smoke_types.h"
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_sound_types.h"
@@ -155,6 +157,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "BKE_main.h"
 #include "BKE_node.h"
 #include "BKE_packedFile.h" // for packAll
+#include "BKE_pointcache.h"
 #include "BKE_report.h"
 #include "BKE_screen.h" // for waitcursor
 #include "BKE_sequence.h"
@@ -404,13 +407,13 @@ static void IDP_WriteIDPArray(IDProperty *prop, void *wd)
 {
        /*REMEMBER to set totalen to len in the linking code!!*/
        if (prop->data.pointer) {
-               IDProperty **array = prop->data.pointer;
+               IDProperty *array = prop->data.pointer;
                int a;
 
-               writedata(wd, DATA, MEM_allocN_len(prop->data.pointer), prop->data.pointer);
+               writestruct(wd, DATA, "IDProperty", prop->len, array);
 
                for(a=0; a<prop->len; a++)
-                       IDP_WriteProperty(array[a], wd);
+                       IDP_WriteProperty_OnlyData(&array[a], wd);
        }
 }
 
@@ -497,12 +500,6 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
                writestruct(wd, DATA, "bNodeLink", 1, link);
 }
 
-static void write_scriptlink(WriteData *wd, ScriptLink *slink)
-{
-       writedata(wd, DATA, sizeof(void *)*slink->totscript, slink->scripts);
-       writedata(wd, DATA, sizeof(short)*slink->totscript, slink->flag);
-}
-
 static void current_screen_compat(Main *mainvar, bScreen **screen)
 {
        wmWindowManager *wm;
@@ -550,19 +547,63 @@ static void write_userdef(WriteData *wd)
        }
 }
 
+static void write_boid_state(WriteData *wd, BoidState *state)
+{
+       BoidRule *rule = state->rules.first;
+       //BoidCondition *cond = state->conditions.first;
+
+       writestruct(wd, DATA, "BoidState", 1, state);
+
+       for(; rule; rule=rule->next) {
+               switch(rule->type) {
+                       case eBoidRuleType_Goal:
+                       case eBoidRuleType_Avoid:
+                               writestruct(wd, DATA, "BoidRuleGoalAvoid", 1, rule);
+                               break;
+                       case eBoidRuleType_AvoidCollision:
+                               writestruct(wd, DATA, "BoidRuleAvoidCollision", 1, rule);
+                               break;
+                       case eBoidRuleType_FollowLeader:
+                               writestruct(wd, DATA, "BoidRuleFollowLeader", 1, rule);
+                               break;
+                       case eBoidRuleType_AverageSpeed:
+                               writestruct(wd, DATA, "BoidRuleAverageSpeed", 1, rule);
+                               break;
+                       case eBoidRuleType_Fight:
+                               writestruct(wd, DATA, "BoidRuleFight", 1, rule);
+                               break;
+                       default:
+                               writestruct(wd, DATA, "BoidRule", 1, rule);
+                               break;
+               }
+       }
+       //for(; cond; cond=cond->next)
+       //      writestruct(wd, DATA, "BoidCondition", 1, cond);
+}
 /* TODO: replace *cache with *cachelist once it's coded */
 #define PTCACHE_WRITE_PSYS     0
-static void write_pointcaches(WriteData *wd, PointCache *cache, int type)
+#define PTCACHE_WRITE_CLOTH    1
+static void write_pointcaches(WriteData *wd, ListBase *ptcaches)
 {
-       writestruct(wd, DATA, "PointCache", 1, cache);
+       PointCache *cache = ptcaches->first;
+       int i;
+
+       for(; cache; cache=cache->next) {
+               writestruct(wd, DATA, "PointCache", 1, cache);
 
-       if((cache->flag & PTCACHE_DISK_CACHE)==0) {
-               PTCacheMem *pm = cache->mem_cache.first;
+               if((cache->flag & PTCACHE_DISK_CACHE)==0) {
+                       PTCacheMem *pm = cache->mem_cache.first;
 
-               for(; pm; pm=pm->next) {
-                       writestruct(wd, DATA, "PTCacheMem", 1, pm);
-                       if(type==PTCACHE_WRITE_PSYS)
-                               writestruct(wd, DATA, "ParticleKey", pm->totpoint, pm->data);
+                       for(; pm; pm=pm->next) {
+                               writestruct(wd, DATA, "PTCacheMem", 1, pm);
+                               if(pm->index_array)
+                                       writedata(wd, DATA, sizeof(int) * pm->totpoint, pm->index_array);
+                               
+                               for(i=0; i<BPHYS_TOT_DATA; i++) {
+                                       if(pm->data[i] && pm->data_types & (1<<i))
+                                               writedata(wd, DATA, BKE_ptcache_data_size(i) * pm->totpoint, pm->data[i]);
+                               }
+                       }
                }
        }
 }
@@ -579,6 +620,15 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
                        if (part->adt) write_animdata(wd, part->adt);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
+
+                       if(part->boids && part->phystype == PART_PHYS_BOIDS) {
+                               BoidState *state = part->boids->states.first;
+
+                               writestruct(wd, DATA, "BoidSettings", 1, part->boids);
+
+                               for(; state; state=state->next)
+                                       write_boid_state(wd, state);
+                       }
                }
                part= part->id.next;
        }
@@ -586,6 +636,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 static void write_particlesystems(WriteData *wd, ListBase *particles)
 {
        ParticleSystem *psys= particles->first;
+       ParticleTarget *pt;
        int a;
 
        for(; psys; psys=psys->next) {
@@ -600,11 +651,23 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
                                for(a=0; a<psys->totpart; a++, pa++)
                                        writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair);
                        }
+
+                       if(psys->particles->boid && psys->part->phystype == PART_PHYS_BOIDS)
+                               writestruct(wd, DATA, "BoidParticle", psys->totpart, psys->particles->boid);
                }
+               pt = psys->targets.first;
+               for(; pt; pt=pt->next)
+                       writestruct(wd, DATA, "ParticleTarget", 1, pt);
+
                if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
-               writestruct(wd, DATA, "SoftBody", 1, psys->soft);
-               if(psys->soft) write_pointcaches(wd, psys->soft->pointcache, PTCACHE_WRITE_PSYS);
-               write_pointcaches(wd, psys->pointcache, PTCACHE_WRITE_PSYS);
+
+               if(psys->clmd) {
+                       writestruct(wd, DATA, "ClothModifierData", 1, psys->clmd);
+                       writestruct(wd, DATA, "ClothSimSettings", 1, psys->clmd->sim_parms);
+                       writestruct(wd, DATA, "ClothCollSettings", 1, psys->clmd->coll_parms);
+               }
+               
+               write_pointcaches(wd, &psys->ptcaches);
        }
 }
 
@@ -649,6 +712,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
                case SENS_PROPERTY:
                        writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
                        break;
+               case SENS_ARMATURE:
+                       writestruct(wd, DATA, "bArmatureSensor", 1, sens->data);
+                       break;
                case SENS_ACTUATOR:
                        writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
                        break;
@@ -722,9 +788,6 @@ static void write_actuators(WriteData *wd, ListBase *lb)
                case ACT_SOUND:
                        writestruct(wd, DATA, "bSoundActuator", 1, act->data);
                        break;
-               case ACT_CD:
-                       writestruct(wd, DATA, "bCDActuator", 1, act->data);
-                       break;
                case ACT_OBJECT:
                        writestruct(wd, DATA, "bObjectActuator", 1, act->data);
                        break;
@@ -770,6 +833,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
                case ACT_STATE:
                        writestruct(wd, DATA, "bStateActuator", 1, act->data);
                        break;
+               case ACT_ARMATURE:
+                       writestruct(wd, DATA, "bArmatureActuator", 1, act->data);
+                       break;
                default:
                        ; /* error: don't know how to write this file */
                }
@@ -778,10 +844,59 @@ static void write_actuators(WriteData *wd, ListBase *lb)
        }
 }
 
+static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
+{
+       FModifier *fcm;
+       
+       /* Modifiers */
+       for (fcm= fmodifiers->first; fcm; fcm= fcm->next) {
+               FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+               
+               /* Write the specific data */
+               if (fmi && fcm->data) {
+                       /* firstly, just write the plain fmi->data struct */
+                       writestruct(wd, DATA, fmi->structName, 1, fcm->data);
+                       
+                       /* do any modifier specific stuff */
+                       switch (fcm->type) {
+                               case FMODIFIER_TYPE_GENERATOR:
+                               {
+                                       FMod_Generator *data= (FMod_Generator *)fcm->data;
+                                       
+                                       /* write coefficients array */
+                                       if (data->coefficients)
+                                               writedata(wd, DATA, sizeof(float)*(data->arraysize), data->coefficients);
+                               }
+                                       break;
+                               case FMODIFIER_TYPE_ENVELOPE:
+                               {
+                                       FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+                                       
+                                       /* write envelope data */
+                                       if (data->data)
+                                               writedata(wd, DATA, sizeof(FCM_EnvelopeData)*(data->totvert), data->data);
+                               }
+                                       break;
+                               case FMODIFIER_TYPE_PYTHON:
+                               {
+                                       FMod_Python *data = (FMod_Python *)fcm->data;
+                                       
+                                       /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+                                        of library blocks that implement this.*/
+                                       IDP_WriteProperty(data->prop, wd);
+                               }
+                                       break;
+                       }
+               }
+               
+               /* Write the modifier */
+               writestruct(wd, DATA, "FModifier", 1, fcm);
+       }
+}
+
 static void write_fcurves(WriteData *wd, ListBase *fcurves)
 {
        FCurve *fcu;
-       FModifier *fcm;
        
        for (fcu=fcurves->first; fcu; fcu=fcu->next) {
                /* F-Curve */
@@ -812,50 +927,8 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
                        }
                }
                
-               /* Modifiers */
-               for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
-                       FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
-                       
-                       /* Write the specific data */
-                       if (fmi && fcm->data) {
-                               /* firstly, just write the plain fmi->data struct */
-                               writestruct(wd, DATA, fmi->structName, 1, fcm->data);
-                               
-                               /* do any modifier specific stuff */
-                               switch (fcm->type) {
-                                       case FMODIFIER_TYPE_GENERATOR:
-                                       {
-                                               FMod_Generator *data= (FMod_Generator *)fcm->data;
-                                               
-                                               /* write coefficients array */
-                                               if (data->coefficients)
-                                                       writedata(wd, DATA, sizeof(float)*(data->arraysize), data->coefficients);
-                                       }
-                                               break;
-                                       case FMODIFIER_TYPE_ENVELOPE:
-                                       {
-                                               FMod_Envelope *data= (FMod_Envelope *)fcm->data;
-                                               
-                                               /* write envelope data */
-                                               if (data->data)
-                                                       writedata(wd, DATA, sizeof(FCM_EnvelopeData)*(data->totvert), data->data);
-                                       }
-                                               break;
-                                       case FMODIFIER_TYPE_PYTHON:
-                                       {
-                                               FMod_Python *data = (FMod_Python *)fcm->data;
-                                               
-                                               /* Write ID Properties -- and copy this comment EXACTLY for easy finding
-                                                of library blocks that implement this.*/
-                                               IDP_WriteProperty(data->prop, wd);
-                                       }
-                                               break;
-                               }
-                       }
-                       
-                       /* Write the modifier */
-                       writestruct(wd, DATA, "FModifier", 1, fcm);
-               }
+               /* write F-Modifiers */
+               write_fmodifiers(wd, &fcu->modifiers);
        }
 }
 
@@ -906,6 +979,37 @@ static void write_keyingsets(WriteData *wd, ListBase *list)
        }
 }
 
+static void write_nlastrips(WriteData *wd, ListBase *strips)
+{
+       NlaStrip *strip;
+       
+       for (strip= strips->first; strip; strip= strip->next) {
+               /* write the strip first */
+               writestruct(wd, DATA, "NlaStrip", 1, strip);
+               
+               /* write the strip's F-Curves and modifiers */
+               write_fcurves(wd, &strip->fcurves);
+               write_fmodifiers(wd, &strip->modifiers);
+               
+               /* write the strip's children */
+               write_nlastrips(wd, &strip->strips);
+       }
+}
+
+static void write_nladata(WriteData *wd, ListBase *nlabase)
+{
+       NlaTrack *nlt;
+       
+       /* write all the tracks */
+       for (nlt= nlabase->first; nlt; nlt= nlt->next) {
+               /* write the track first */
+               writestruct(wd, DATA, "NlaTrack", 1, nlt);
+               
+               /* write the track's strips */
+               write_nlastrips(wd, &nlt->strips);
+       }
+}
+
 static void write_animdata(WriteData *wd, AnimData *adt)
 {
        AnimOverride *aor;
@@ -917,14 +1021,17 @@ static void write_animdata(WriteData *wd, AnimData *adt)
        write_fcurves(wd, &adt->drivers);
        
        /* write overrides */
+       // FIXME: are these needed?
        for (aor= adt->overrides.first; aor; aor= aor->next) {
                /* overrides consist of base data + rna_path */
                writestruct(wd, DATA, "AnimOverride", 1, aor);
                writedata(wd, DATA, strlen(aor->rna_path)+1, aor->rna_path);
        }
        
+       // TODO write the remaps (if they are needed)
+       
        /* write NLA data */
-       // XXX todo...
+       write_nladata(wd, &adt->nla_tracks);
 }
 
 static void write_constraints(WriteData *wd, ListBase *conlist)
@@ -992,8 +1099,16 @@ static void write_pose(WriteData *wd, bPose *pose)
        for (grp=pose->agroups.first; grp; grp=grp->next) 
                writestruct(wd, DATA, "bActionGroup", 1, grp);
 
+       /* write IK param */
+       if (pose->ikparam) {
+               const char *structname = get_ikparam_name(pose);
+               if (structname)
+                       writestruct(wd, DATA, structname, 1, pose->ikparam);
+       }
+
        /* Write this pose */
        writestruct(wd, DATA, "bPose", 1, pose);
+
 }
 
 static void write_defgroups(WriteData *wd, ListBase *defbase)
@@ -1004,7 +1119,7 @@ static void write_defgroups(WriteData *wd, ListBase *defbase)
                writestruct(wd, DATA, "bDeformGroup", 1, defgroup);
 }
 
-static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
+static void write_modifiers(WriteData *wd, ListBase *modbase)
 {
        ModifierData *md;
 
@@ -1025,7 +1140,25 @@ static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
                        
                        writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
                        writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
-                       writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
+                       write_pointcaches(wd, &clmd->ptcaches);
+               } 
+               else if(md->type==eModifierType_Smoke) {
+                       SmokeModifierData *smd = (SmokeModifierData*) md;
+                       
+                       if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
+                               writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain);
+                       else if(smd->type & MOD_SMOKE_TYPE_FLOW)
+                               writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow);
+                       /*
+                       else if(smd->type & MOD_SMOKE_TYPE_COLL)
+                               writestruct(wd, DATA, "SmokeCollSettings", 1, smd->coll);
+                       */
+
+                       if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+                       {
+                               write_pointcaches(wd, &(smd->domain->ptcaches[0]));
+                               write_pointcaches(wd, &(smd->domain->ptcaches[1]));
+                       }
                } 
                else if(md->type==eModifierType_Fluidsim) {
                        FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
@@ -1058,13 +1191,13 @@ static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
                else if (md->type==eModifierType_Multires) {
                        MultiresModifierData *mmd = (MultiresModifierData*) md;
 
-                       if(mmd->undo_verts && write_undo)
+                       if(mmd->undo_verts)
                                writestruct(wd, DATA, "MVert", mmd->undo_verts_tot, mmd->undo_verts);
                }
        }
 }
 
-static void write_objects(WriteData *wd, ListBase *idbase, int write_undo)
+static void write_objects(WriteData *wd, ListBase *idbase)
 {
        Object *ob;
        
@@ -1082,23 +1215,23 @@ static void write_objects(WriteData *wd, ListBase *idbase, int write_undo)
                        
                        /* direct data */
                        writedata(wd, DATA, sizeof(void *)*ob->totcol, ob->mat);
+                       writedata(wd, DATA, sizeof(char)*ob->totcol, ob->matbits);
                        /* write_effects(wd, &ob->effect); */ /* not used anymore */
                        write_properties(wd, &ob->prop);
                        write_sensors(wd, &ob->sensors);
                        write_controllers(wd, &ob->controllers);
                        write_actuators(wd, &ob->actuators);
-                       write_scriptlink(wd, &ob->scriptlink);
                        write_pose(wd, ob->pose);
                        write_defgroups(wd, &ob->defbase);
                        write_constraints(wd, &ob->constraints);
                        
                        writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
                        writestruct(wd, DATA, "SoftBody", 1, ob->soft);
-                       if(ob->soft) writestruct(wd, DATA, "PointCache", 1, ob->soft->pointcache);
+                       if(ob->soft) write_pointcaches(wd, &ob->soft->ptcaches);
                        writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
                        
                        write_particlesystems(wd, &ob->particlesystem);
-                       write_modifiers(wd, &ob->modifiers, write_undo);
+                       write_modifiers(wd, &ob->modifiers);
                }
                ob= ob->id.next;
        }
@@ -1175,9 +1308,6 @@ static void write_cameras(WriteData *wd, ListBase *idbase)
                        if (cam->id.properties) IDP_WriteProperty(cam->id.properties, wd);
                        
                        if (cam->adt) write_animdata(wd, cam->adt);
-                       
-                       /* direct data */
-                       write_scriptlink(wd, &cam->scriptlink);
                }
 
                cam= cam->id.next;
@@ -1198,6 +1328,7 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
 
                        /* direct data */
                        writedata(wd, DATA, sizeof(void *)*mb->totcol, mb->mat);
+                       if (mb->adt) write_animdata(wd, mb->adt);
 
                        ml= mb->elems.first;
                        while(ml) {
@@ -1246,7 +1377,7 @@ static void write_curves(WriteData *wd, ListBase *idbase)
                                }
                                nu= cu->nurb.first;
                                while(nu) {
-                                       if( (nu->type & 7)==CU_BEZIER)
+                                       if(nu->type == CU_BEZIER)
                                                writestruct(wd, DATA, "BezTriple", nu->pntsu, nu->bezt);
                                        else {
                                                writestruct(wd, DATA, "BPoint", nu->pntsu*nu->pntsv, nu->bp);
@@ -1436,7 +1567,10 @@ static void write_images(WriteData *wd, ListBase *idbase)
 
                        write_previews(wd, ima->preview);
 
-                       }
+                       /* exception: render text only saved in undo files (wd->current) */
+                       if (ima->render_text && wd->current)
+                               writedata(wd, DATA, IMA_RW_MAXTEXT, ima->render_text);
+               }
                ima= ima->id.next;
        }
        /* flush helps the compression for undo-save */
@@ -1460,6 +1594,11 @@ static void write_textures(WriteData *wd, ListBase *idbase)
                        if(tex->type == TEX_PLUGIN && tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
                        if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
                        if(tex->type == TEX_ENVMAP && tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+                       if(tex->type == TEX_POINTDENSITY && tex->pd) {
+                               writestruct(wd, DATA, "PointDensity", 1, tex->pd);
+                               if(tex->pd->coba) writestruct(wd, DATA, "ColorBand", 1, tex->pd->coba);
+                       }
+                       if(tex->type == TEX_VOXELDATA && tex->vd) writestruct(wd, DATA, "VoxelData", 1, tex->vd);
                        
                        /* nodetree is integral part of texture, no libdata */
                        if(tex->nodetree) {
@@ -1502,8 +1641,6 @@ static void write_materials(WriteData *wd, ListBase *idbase)
                        if(ma->ramp_col) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_col);
                        if(ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec);
                        
-                       write_scriptlink(wd, &ma->scriptlink);
-                       
                        /* nodetree is integral part of material, no libdata */
                        if(ma->nodetree) {
                                writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree);
@@ -1534,8 +1671,6 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
                                if(wrld->mtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]);
                        }
                        
-                       write_scriptlink(wd, &wrld->scriptlink);
-                       
                        write_previews(wd, wrld->preview);
                }
                wrld= wrld->id.next;
@@ -1564,8 +1699,6 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
                        if(la->curfalloff)
                                write_curvemapping(wd, la->curfalloff); 
                        
-                       write_scriptlink(wd, &la->scriptlink);
-                       
                        write_previews(wd, la->preview);
                        
                }
@@ -1573,6 +1706,11 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
        }
 }
 
+static void write_paint(WriteData *wd, Paint *p)
+{
+       if(p && p->brushes)
+               writedata(wd, DATA, p->brush_count * sizeof(Brush*), p->brushes);
+}
 
 static void write_scenes(WriteData *wd, ListBase *scebase)
 {
@@ -1585,6 +1723,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
        TimeMarker *marker;
        TransformOrientation *ts;
        SceneRenderLayer *srl;
+       ToolSettings *tos;
        
        sce= scebase->first;
        while(sce) {
@@ -1602,13 +1741,22 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                        base= base->next;
                }
                
-               writestruct(wd, DATA, "ToolSettings", 1, sce->toolsettings);
-               if(sce->toolsettings->vpaint)
-                       writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->vpaint);
-               if(sce->toolsettings->wpaint)
-                       writestruct(wd, DATA, "VPaint", 1, sce->toolsettings->wpaint);
-               if(sce->toolsettings->sculpt)
-                       writestruct(wd, DATA, "Sculpt", 1, sce->toolsettings->sculpt);
+               tos = sce->toolsettings;
+               writestruct(wd, DATA, "ToolSettings", 1, tos);
+               if(tos->vpaint) {
+                       writestruct(wd, DATA, "VPaint", 1, tos->vpaint);
+                       write_paint(wd, &tos->vpaint->paint);
+               }
+               if(tos->wpaint) {
+                       writestruct(wd, DATA, "VPaint", 1, tos->wpaint);
+                       write_paint(wd, &tos->wpaint->paint);
+               }
+               if(tos->sculpt) {
+                       writestruct(wd, DATA, "Sculpt", 1, tos->sculpt);
+                       write_paint(wd, &tos->sculpt->paint);
+               }
+
+               write_paint(wd, &tos->imapaint.paint);
 
                ed= sce->ed;
                if(ed) {
@@ -1677,8 +1825,6 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                        }
                }
                
-               write_scriptlink(wd, &sce->scriptlink);
-               
                if (sce->r.avicodecdata) {
                        writestruct(wd, DATA, "AviCodecData", 1, sce->r.avicodecdata);
                        if (sce->r.avicodecdata->lpFormat) writedata(wd, DATA, sce->r.avicodecdata->cbFormat, sce->r.avicodecdata->lpFormat);
@@ -1820,9 +1966,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "Panel", 1, pa);
                        }
                        
-                       /* space handler scriptlinks */
-                       write_scriptlink(wd, &sa->scriptlink);
-                       
                        sl= sa->spacedata.first;
                        while(sl) {
                                for(ar= sl->regionbase.first; ar; ar= ar->next)
@@ -1893,7 +2036,10 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceSound", 1, sl);
                                }
                                else if(sl->spacetype==SPACE_NLA){
-                                       writestruct(wd, DATA, "SpaceNla", 1, sl);
+                                       SpaceNla *snla= (SpaceNla *)sl;
+                                       
+                                       writestruct(wd, DATA, "SpaceNla", 1, snla);
+                                       if(snla->ads) writestruct(wd, DATA, "bDopeSheet", 1, snla->ads);
                                }
                                else if(sl->spacetype==SPACE_TIME){
                                        writestruct(wd, DATA, "SpaceTime", 1, sl);
@@ -1904,6 +2050,13 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                else if(sl->spacetype==SPACE_LOGIC){
                                        writestruct(wd, DATA, "SpaceLogic", 1, sl);
                                }
+                               else if(sl->spacetype==SPACE_CONSOLE) {
+                                       writestruct(wd, DATA, "SpaceConsole", 1, sl);
+                               }
+                               else if(sl->spacetype==SPACE_USERPREF) {
+                                       writestruct(wd, DATA, "SpaceUserPref", 1, sl);
+                               }
+
                                sl= sl->next;
                        }
                }
@@ -1977,6 +2130,8 @@ static void write_armatures(WriteData *wd, ListBase *idbase)
                        writestruct(wd, ID_AR, "bArmature", 1, arm);
                        if (arm->id.properties) IDP_WriteProperty(arm->id.properties, wd);
 
+                       if (arm->adt) write_animdata(wd, arm->adt);
+
                        /* Direct data */
                        bone= arm->bonebase.first;
                        while(bone) {
@@ -2039,45 +2194,21 @@ static void write_texts(WriteData *wd, ListBase *idbase)
 static void write_sounds(WriteData *wd, ListBase *idbase)
 {
        bSound *sound;
-       bSample *sample;
 
        PackedFile * pf;
 
-       // set all samples to unsaved status
-
-       sample = samples->first; // samples is a global defined in sound.c
-       while (sample) {
-               sample->flags |= SAMPLE_NEEDS_SAVE;
-               sample = sample->id.next;
-       }
-
        sound= idbase->first;
        while(sound) {
                if(sound->id.us>0 || wd->current) {
-                       // do we need to save the packedfile as well ?
-                       sample = sound->sample;
-                       if (sample) {
-                               if (sample->flags & SAMPLE_NEEDS_SAVE) {
-                                       sound->newpackedfile = sample->packedfile;
-                                       sample->flags &= ~SAMPLE_NEEDS_SAVE;
-                               } else {
-                                       sound->newpackedfile = NULL;
-                               }
-                       }
-
                        /* write LibData */
                        writestruct(wd, ID_SO, "bSound", 1, sound);
                        if (sound->id.properties) IDP_WriteProperty(sound->id.properties, wd);
 
-                       if (sound->newpackedfile) {
-                               pf = sound->newpackedfile;
+                       if (sound->packedfile) {
+                               pf = sound->packedfile;
                                writestruct(wd, DATA, "PackedFile", 1, pf);
                                writedata(wd, DATA, pf->size, pf->data);
                        }
-
-                       if (sample) {
-                               sound->newpackedfile = sample->packedfile;
-                       }
                }
                sound= sound->id.next;
        }
@@ -2221,7 +2352,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
        write_groups   (wd, &mainvar->group);
        write_armatures(wd, &mainvar->armature);
        write_actions  (wd, &mainvar->action);
-       write_objects  (wd, &mainvar->object, (current != NULL));
+       write_objects  (wd, &mainvar->object);
        write_materials(wd, &mainvar->mat);
        write_textures (wd, &mainvar->tex);
        write_meshs    (wd, &mainvar->mesh);