Part 2 of 64 bits fixing; the files.
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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
lb= wich_libbase(mainvar, GS(idname));
|
||||
|
||||
// BHEAD+DATA dependancy
|
||||
idtest= (ID *)(bhead +1);
|
||||
lb= wich_libbase(mainvar, GS(idtest->name));
|
||||
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);
|
||||
|
||||
id= is_yet_read(mainvar, bhead);
|
||||
if(id==0) {
|
||||
if(strcmp(idname+2, name)==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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -120,5 +121,7 @@ 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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user