Part 2 of 64 bits fixing; the files.
authorTon Roosendaal <ton@blender.org>
Sat, 28 Apr 2007 16:15:00 +0000 (16:15 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 28 Apr 2007 16:15:00 +0000 (16:15 +0000)
The good news; previously written 64 bits are still valid! All fixes
appeared to be possible in code, no versioning patches needed. :)
That also removes the I AM STUPID 64 bits ban from the code.

The bad news:
I couldn't get a 64 bits Blender running here (ghost-mac issues... it
has to be recoded using Quartz to be able to run 64 bits). So what I
have tested was:

32 bits binary:
  - Appending/linking data from 64 bits file.
  - Reading 64 bits chained library-linked files (file -> file -> etc)
  - Linking 32 bits files with 64 bits files

This has to be tested for 64 bits too. Will drop in IRC now to help.

Note: part 3 is fixing memory issues for addressing > 4 GB data. A first
start has been made for a blenlib API function.

source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/intern/util.c
source/blender/blenloader/intern/genfile.c
source/blender/blenloader/intern/genfile.h
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/src/buttons_object.c

index ad2dbc52d69f6321a5fb354bf525b08b417b44d7..6e51d171461dab6adb0de4e3cbd091c0e6042eaa 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
@@ -362,6 +362,13 @@ int BLI_strcasecmp(const char *s1, const char *s2);
 int BLI_strncasecmp(const char *s1, const char *s2, int n);
 void BLI_timestr(double time, char *str);
 
+/** 
+  * Trick to address 32 GB with an int (only for malloced pointers)
+  */
+int BLI_int_from_pointer(void *poin);
+void *BLI_pointer_from_int(int val);
+
+
 #define PRNTSUB(type,arg)                      printf(#arg ": %" #type " ", arg)
 
 #ifndef PRINT
index 2aa1b852ed3b07fcb5cd34ae834fac744b57d926..83e110101dc05f41d9d362ebe90ba72930a5d985 100644 (file)
@@ -1508,4 +1508,51 @@ void BLI_timestr(double time, char *str)
        str[11]=0;
 }
 
+/* ************** 64 bits magic, trick to support up to 32 gig of address space *************** */
+/*                only works for malloced pointers (8 aligned)                   */
+
+#ifdef __LP64__ 
+
+#if defined(WIN32) && !defined(FREE_WINDOWS)
+#define PMASK          0x07FFFFFFFFi64
+#else
+#define PMASK          0x07FFFFFFFFll
+#endif
+
+
+int BLI_int_from_pointer(void *poin)
+{
+       long lval= (long)poin;
+       
+       return (int)(lval>>3);
+}
+
+void *BLI_pointer_from_int(int val)
+{
+       static int firsttime= 1;
+       static long basevalue= 0;
+       
+       if(firsttime) {
+               void *poin= malloc(10000);
+               basevalue= (long)poin;
+               basevalue &= ~PMASK;
+               printf("base: %d pointer %p\n", basevalue, poin); /* debug */
+               firsttime= 0;
+               free(poin);
+       }
+       return basevalue | (((long)val)<<3);
+}
+
+#else
+
+int BLI_int_from_pointer(void *poin)
+{
+       return (int)poin;
+}
+void *BLI_pointer_from_int(int val)
+{
+       return (void *)val;
+}
+
+#endif
 
index 55cfc13fdec646f14928f02a4971b5dd9f236c15..b21185e84a0b23981b994ad4706aff81bea5b9b3 100644 (file)
@@ -1089,3 +1089,14 @@ void *dna_reconstruct(struct SDNA *newsdna, struct SDNA *oldsdna, char *compflag
        return cur;
 }
 
+int dna_elem_offset(struct SDNA *sdna, char *stype, char *vartype, char *name)
+{
+       
+       int SDNAnr= dna_findstruct_nr(sdna, stype);
+       short *spo= sdna->structs[SDNAnr];
+       char *cp= find_elem(sdna, vartype, name, spo, NULL, NULL);
+       return (int)((long)cp);
+}
+
+
+
index e23802958eec95ae3e4d3b36d0de04450bff6a41..f027c14ac7a33f2a686044a3a75a1a1985ec9bc4 100644 (file)
@@ -40,6 +40,7 @@ int dna_findstruct_nr(struct SDNA *sdna, char *str);
 char *dna_get_structDNA_compareflags(struct SDNA *sdna, struct SDNA *newsdna);
 void dna_switch_endian_struct(struct SDNA *oldsdna, int oldSDNAnr, char *data);
 void *dna_reconstruct(struct SDNA *newsdna, struct SDNA *oldsdna, char *compflags, int oldSDNAnr, int blocks, void *data);
+int dna_elem_offset(struct SDNA *sdna, char *stype, char *vartype, char *name);
 
 struct SDNA *dna_sdna_from_data(void *data, int datalen, int do_endian_swap);
 void dna_freestructDNA(struct SDNA *sdna);
index 6dd8e65ad28dd878e35bc6f5ea3efd609c75b81a..5f67c060c040dd144f2bc4487922616612e0b13f 100644 (file)
@@ -208,9 +208,9 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
 
        for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
                if (bhead->code==ofblocktype) {
-                       ID *id= (ID*) (bhead+1);
+                       char *idname= bhead_id_name(fd, bhead);
                        
-                       BLI_linklist_prepend(&names, strdup(id->name+2));
+                       BLI_linklist_prepend(&names, strdup(idname+2));
                } else if (bhead->code==ENDB)
                        break;
        }
index 70f8422968c1dcf82ef4c1605a5edc752e6cbd71..c7182c74d633da4792ab0f540af0b7d0be42dd5a 100644 (file)
@@ -554,8 +554,7 @@ static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
                }
 
                /* this patch is to avoid a long long being read from not-eight aligned positions
-                  is necessary on SGI with -n32 compiling (no, is necessary on
-                  any modern 64bit architecture) */
+                  is necessary on any modern 64bit architecture) */
                memcpy(&old, &bhead8->old, 8);
                bhead4->old = (int) (old >> 3);
 
@@ -794,8 +793,12 @@ static int read_file_dna(FileData *fd)
                        int do_endian_swap= (fd->flags&FD_FLAGS_SWITCH_ENDIAN)?1:0;
 
                        fd->filesdna= dna_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
-                       if (fd->filesdna)
+                       if (fd->filesdna) {
+                               
                                fd->compflags= dna_get_structDNA_compareflags(fd->filesdna, fd->memsdna);
+                               /* used to retrieve ID names from (bhead+1) */
+                               fd->id_name_offs= dna_elem_offset(fd->filesdna, "ID", "char", "name[]");
+                       }
 
                        return 1;
                } else if (bhead->code==ENDB)
@@ -1183,7 +1186,7 @@ static void switch_endian_structs(struct SDNA *filesdna, BHead *bhead)
        int blocksize, nblocks;
        char *data;
 
-       data= (char *)(bhead+1); /*  BHEAD+DATA dependancy */
+       data= (char *)(bhead+1);
        blocksize= filesdna->typelens[ filesdna->structs[bhead->SDNAnr][0] ];
 
        nblocks= bhead->nr;
@@ -1199,6 +1202,7 @@ static void *read_struct(FileData *fd, BHead *bh, char *blockname)
        void *temp= NULL;
 
        if (bh->len) {
+               /* switch is based on file dna */
                if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN))
                        switch_endian_structs(fd->filesdna, bh);
 
@@ -1207,7 +1211,7 @@ static void *read_struct(FileData *fd, BHead *bh, char *blockname)
                                temp= dna_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
                        } else {
                                temp= MEM_mallocN(bh->len, blockname);
-                               memcpy(temp, (bh+1), bh->len); /*  BHEAD+DATA dependancy */
+                               memcpy(temp, (bh+1), bh->len);
                        }
                }
        }
@@ -3936,15 +3940,6 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
        ListBase *lb;
        char *allocname;
        
-       if(bhead->code==ID_ID) {
-               ID *linkedid= (ID *)(bhead + 1); /*  BHEAD+DATA dependancy */
-
-               lb= wich_libbase(main, GS(linkedid->name));
-       }
-       else {
-               lb= wich_libbase(main, bhead->code);
-       }
-
        /* read libblock */
        id = read_struct(fd, bhead, "lib block");
        if (id_r)
@@ -3953,6 +3948,15 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                return blo_nextbhead(fd, bhead);
        
        oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);      /* for ID_ID check */
+       
+       /* do after read_struct, for dna reconstruct */
+       if(bhead->code==ID_ID) {
+               lb= wich_libbase(main, GS(id->name));
+       }
+       else {
+               lb= wich_libbase(main, bhead->code);
+       }
+       
        BLI_addtail(lb, id);
 
        /* clear first 8 bits */
@@ -6542,22 +6546,27 @@ static BHead *find_bhead(FileData *fd, void *old)
        return NULL;
 }
 
-static ID *is_yet_read(Main *mainvar, BHead *bhead)
+char *bhead_id_name(FileData *fd, BHead *bhead)
+{
+       return ((char *)(bhead+1)) + fd->id_name_offs;
+}
+
+static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
 {
        ListBase *lb;
-       ID *idtest, *id;
+       char *idname= bhead_id_name(fd, bhead);
 
-       // BHEAD+DATA dependancy
-       idtest= (ID *)(bhead +1);
-       lb= wich_libbase(mainvar, GS(idtest->name));
+       lb= wich_libbase(mainvar, GS(idname));
+       
        if(lb) {
-               id= lb->first;
+               ID *id= lb->first;
                while(id) {
-                       if( strcmp(id->name, idtest->name)==0 ) return id;
+                       if( strcmp(id->name, idname)==0 ) 
+                               return id;
                        id= id->next;
                }
        }
-       return 0;
+       return NULL;
 }
 
 static void expand_doit(FileData *fd, Main *mainvar, void *old)
@@ -6572,16 +6581,12 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
                        BHead *bheadlib= find_previous_lib(fd, bhead);
 
                        if(bheadlib) {
-                               // BHEAD+DATA dependancy
-                               Library *lib= (Library *)(bheadlib+1);
-                               /* ***************************** */
-                               /* we read the lib->name directly from the bhead, no DNA, potential danger (64 bits?) */
-                               /* ***************************** */
+                               Library *lib= read_struct(fd, bheadlib, "Library");
                                Main *ptr= blo_find_main(&fd->mainlist, lib->name, fd->filename);
 
-                               id= is_yet_read(ptr, bhead);
+                               id= is_yet_read(fd, ptr, bhead);
 
-                               if(id==0) {
+                               if(id==NULL) {
                                        read_libblock(fd, ptr, bhead, LIB_READ+LIB_INDIRECT, NULL);
                                        if(G.f & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name);
                                        
@@ -6594,20 +6599,20 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
                                        change_idid_adr_fd(fd, bhead->old, id);
                                        if(G.f & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name);
                                }
+                               
+                               MEM_freeN(lib);
                        }
                }
                else {
-                       id= is_yet_read(mainvar, bhead);
+                       id= is_yet_read(fd, mainvar, bhead);
                        if(id==NULL) {
-                               // BHEAD+DATA dependancy
-                               id= (ID *)(bhead+1);
                                read_libblock(fd, mainvar, bhead, LIB_TESTIND, NULL);
                        }
                        else {
                                /* this is actually only needed on UI call? when ID was already read before, and another append
                                   happens which invokes same ID... in that case the lookup table needs this entry */
                                oldnewmap_insert(fd->libmap, bhead->old, id, 1);
-                               // printf("expand: already read %s\n", id->name);
+                               if(G.f & G_DEBUG) printf("expand: already read %s\n", id->name);
                        }
                }
        }
@@ -7230,19 +7235,19 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
        Base *base;
        BHead *bhead;
        ID *id;
-       int afbreek=0;
+       int endloop=0;
 
        bhead = blo_firstbhead(fd);
-       while(bhead && afbreek==0) {
+       while(bhead && endloop==0) {
 
-               if(bhead->code==ENDB) afbreek= 1;
+               if(bhead->code==ENDB) endloop= 1;
                else if(bhead->code==idcode) {
-                       // BHEAD+DATA dependancy
-                       id= (ID *)(bhead+1);
-                       if(strcmp(id->name+2, name)==0) {
+                       char *idname= bhead_id_name(fd, bhead);
+                               
+                       if(strcmp(idname+2, name)==0) {
 
-                               id= is_yet_read(mainvar, bhead);
-                               if(id==0) {
+                               id= is_yet_read(fd, mainvar, bhead);
+                               if(id==NULL) {
                                        read_libblock(fd, mainvar, bhead, LIB_TESTEXT, NULL);
                                }
                                else {
@@ -7258,7 +7263,7 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                        base= MEM_callocN( sizeof(Base), "app_nam_part");
                                        BLI_addtail(&scene->base, base);
 
-                                       if(id==0) ob= mainvar->object.last;
+                                       if(id==NULL) ob= mainvar->object.last;
                                        else ob= (Object *)id;
                                        
                                        /* this is bad code... G.vd nor G.scene should be used on this level... */
@@ -7276,7 +7281,7 @@ static void append_named_part(FileData *fd, Main *mainvar, Scene *scene, char *n
                                                /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
                                        }
                                }
-                               afbreek= 1;
+                               endloop= 1;
                        }
                }
 
@@ -7290,9 +7295,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
        for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
                if (bhead->code == GS(id->name)) {
-                       ID *idread= (ID *)(bhead+1); /*  BHEAD+DATA dependancy */
-
-                       if (BLI_streq(id->name, idread->name)) {
+                       
+                       if (BLI_streq(id->name, bhead_id_name(fd, bhead))) {
                                id->flag &= ~LIB_READ;
                                id->flag |= LIB_TEST;
 //                             printf("read lib block %s\n", id->name);
@@ -7509,7 +7513,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
                while(mainptr) {
                        int tot= mainvar_count_libread_blocks(mainptr);
                        
-                       //printf("found LIB_READ %s\n", mainptr->curlib->name);
+                       // printf("found LIB_READ %s\n", mainptr->curlib->name);
                        if(tot) {
                                FileData *fd= mainptr->curlib->filedata;
 
index 96a004ee6b6d11536073297b7b0648e9d241e3f8..79392023a564e47640c6fcd7b7e4b64c02cbd16e 100644 (file)
@@ -69,6 +69,7 @@ typedef struct FileData {
        char *compflags;
        
        int fileversion;
+       int id_name_offs;               /* used to retrieve ID names from (bhead+1) */
        
        struct OldNewMap *datamap;
        struct OldNewMap *globmap;
@@ -119,6 +120,8 @@ void blo_freefiledata( FileData *fd);
 BHead *blo_firstbhead(FileData *fd);
 BHead *blo_nextbhead(FileData *fd, BHead *thisblock);
 BHead *blo_prevbhead(FileData *fd, BHead *thisblock);
-       
+
+char *bhead_id_name(FileData *fd, BHead *bhead);
+
 #endif
 
index a96cf8a0c7e48faa9266c65f4b8f630510f67fdc..07e57762db2f5b97596fa336b557fd2e192be104 100644 (file)
@@ -3044,9 +3044,9 @@ static void object_panel_fluidsim(Object *ob)
                                        || (fss->type == OB_FLUIDSIM_INFLOW) 
                                        ) {
                                uiBlockBeginAlign(block); // fluid
-                               uiDefButC(block, ROW, REDRAWBUTSOBJECT"Init Volume",    0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
-                               uiDefButC(block, ROW, REDRAWBUTSOBJECT, "Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defines by the faces of the mesh.");
-                               uiDefButC(block, ROW, REDRAWBUTSOBJECT"Init Both",    200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
+                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume",    0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
+                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
+                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both",    200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
                                uiBlockEndAlign(block);
                                yline -= lineHeight;
 
@@ -3079,7 +3079,7 @@ static void object_panel_fluidsim(Object *ob)
 
                                uiBlockBeginAlign(block); // outflow
                                uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume",    0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
-                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defines by the faces of the mesh.");
+                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
                                uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both",    200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
                                uiBlockEndAlign(block);
                                yline -= lineHeight;
@@ -3096,7 +3096,7 @@ static void object_panel_fluidsim(Object *ob)
 
                                uiBlockBeginAlign(block); // obstacle
                                uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Volume",    0, yline,100,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh.");
-                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defines by the faces of the mesh.");
+                               uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Shell",   100, yline,100,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh.");
                                uiDefButC(block, ROW, REDRAWBUTSOBJECT ,"Init Both",    200, yline,100,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell.");
                                uiBlockEndAlign(block);
                                yline -= lineHeight;