So i did this ugly thing
int model_octant_find_faces_sub(polymodel * pm, model_octant * oct, void *model_ptr, int just_count )
{
ubyte *p = (ubyte *)model_ptr;
int chunk_type, chunk_size;
chunk_type = w(p);
chunk_size = w(p+4);
mprintf(( "First chunk_type %d\n", chunk_type ));
mprintf(( "First chunk_size %d\n", chunk_size ));
while (chunk_type != OP_EOF) {
switch (chunk_type) {
case OP_DEFPOINTS:
moff_defpoints(p, just_count);
break;
case OP_FLATPOLY: moff_flatpoly(p, pm, oct, just_count ); break;
case OP_TMAPPOLY: moff_tmappoly(p, pm, oct, just_count ); break;
case OP_SORTNORM: {
int frontlist = w(p+36);
int backlist = w(p+40);
int prelist = w(p+44);
int postlist = w(p+48);
int onlist = w(p+52);
if (prelist) model_octant_find_faces_sub(pm,oct,p+prelist,just_count);
if (backlist) model_octant_find_faces_sub(pm,oct,p+backlist,just_count);
if (onlist) model_octant_find_faces_sub(pm,oct,p+onlist,just_count);
if (frontlist) model_octant_find_faces_sub(pm,oct,p+frontlist,just_count);
if (postlist) model_octant_find_faces_sub(pm,oct,p+postlist,just_count);
}
break;
case OP_BOUNDBOX: break;
default:
mprintf(( "Bad chunk type %d, len=%d in model_octant_find_faces_sub\n", chunk_type, chunk_size ));
Int3(); // Bad chunk type!
return 0;
}
p += chunk_size;
chunk_type = w(p);
chunk_size = w(p+4);
mprintf(( "End chunk_type %d\n", chunk_type ));
mprintf(( "End chunk_size %d\n", chunk_size ));
void model_octant_find_faces( polymodel * pm, model_octant * oct )
{
ubyte *p;
int submodel_num = pm->detail[0];
p = pm->submodel[submodel_num].bsp_data;
mprintf(( "chunk_type OP_DEFPOINTS %d\n", OP_DEFPOINTS ));
mprintf(( "chunk_type OP_FLATPOLY %d\n", OP_FLATPOLY ));
mprintf(( "chunk_type OP_TMAPPOLY %d\n", OP_TMAPPOLY ));
mprintf(( "chunk_type OP_SORTNORM %d\n", OP_SORTNORM ));
mprintf(( "chunk_type OP_BOUNDBOX %d\n", OP_BOUNDBOX ));
oct->nverts = 0;
model_octant_find_faces_sub(pm, oct, p, 1 );
mprintf(( "%s\n", "pass" ));
if ( oct->nverts < 1 ) {
oct->nverts = 0;
oct->verts = NULL;
return;
}
oct->verts = (vec3d **)vm_malloc( sizeof(vec3d *) * oct->nverts );
Assert(oct->verts!=NULL);
oct->nverts = 0;
model_octant_find_faces_sub(pm, oct, p, 0 );
// mprintf(( "Octant has %d faces\n", oct->nfaces ));
}
Results in this
chunk_type OP_DEFPOINTS 1
chunk_type OP_FLATPOLY 2
chunk_type OP_TMAPPOLY 3
chunk_type OP_SORTNORM 4
chunk_type OP_BOUNDBOX 5
First chunk_type 1
First chunk_size 74590
End chunk_type 4
End chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 4
First chunk_size 80
First chunk_type 0
First chunk_size 0
First chunk_type 5
First chunk_size 32
End chunk_type 3
End chunk_size 80
<crash here>
74590 is not multiple of 4 and that p += chunk_size; that makes the pointer to go to unaligned memory, so i went on to check that first chunk size on retail models:
First chunk_size 16072 | 4018.000000
First chunk_size 15268 | 3817.000000
First chunk_size 9716 | 2429.000000
No point in writting them all, they are all multiple of 4.
So Goober, you are right.
Now this happens while reading the .pof into memory or when reading the data in memory? Because if this happens while reading the file... well, i not sure if it can be fixed, altrought i dont know the code to think in a workaround, maybe memcpy the entire thing and work from there. Where exacty this is done in the code?