int SrvrLoadWorldFromFile( uint32_t client_id, FILE *file, INDEX iWorld ) { FILE *pFile; PWORLD world = GetSetMember( WORLD, &g.worlds, iWorld ); int sz = 0, cnt, version, size; char tag[4]; // read in make sure we're still aligned in the file... int linesize; int nlines; PFLATLAND_MYLINESEG *linearray; int wallsize; int nwalls; PWALL *wallarray; int sectorsize; int nsectors; PSECTOR *sectorarray; int namesize; int nnames; PNAME *namearray; int texturesize; int ntextures; PFLATLAND_TEXTURE *texturearray; INDEX texture; if( !world ) return 0; { char buffer[256]; GetNameText( iWorld, world->name, buffer, sizeof( buffer ) ); Fopen( pFile, buffer, "rb" ); } if( !pFile ) return 0; ResetWorld( iWorld ); // make sure this thing is empty ); sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "FLAT", 4 ) ) { Log( "Alignment error in file load... totally invalid file." ); return 0; } sz += fread( &size, 1, sizeof( size ), pFile ); if( size < 10 ) // can assume that it was a version ID version = size; else sz = fread( &version, 1, sizeof( version ), pFile ); if( version < 8 ) { texture = SrvrMakeTexture( client_id, iWorld, SrvrMakeName( client_id, iWorld, WIDE( "Default" ) ) ); SrvrSetSolidColor( client_id, iWorld, texture, AColor( 43, 76, 180, 0x80 ) ); } Log1( "Loading version: %d", version ); sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "LINE", 4 ) ) { // was not LINE or FLAT tag... Log( "Alignment error in file line load." ); return 0; } if( version > 9 ) sz += fread( &linesize, 1, sizeof( linesize ), pFile ); sz += fread( &nlines, 1, sizeof(nlines), pFile ); linearray = (PFLATLAND_MYLINESEG*)Allocate( sizeof( PFLATLAND_MYLINESEG ) * nlines ); for( cnt = 0; cnt < nlines; cnt++ ) { PFLATLAND_MYLINESEG pls; LINESEGFILE lsf; sz += fread( &lsf, 1, sizeof(LINESEGFILE), pFile ); pls = GetFromSet( FLATLAND_MYLINESEG, &world->lines ); #ifdef OUTPUT_TO_VIRTUALITY pls->pfl = CreateFacetLine( world->object, lsf.r.o, lsf.r.n, lsf.start, lsf.end ); #endif linearray[cnt] = pls; /* some sort of update line... */ SetRay( &pls->r, &lsf.r ); if( version < 9 ) { pls->r.o[1] = -pls->r.o[1]; pls->r.n[1] = -pls->r.n[1]; } pls->dFrom = lsf.start; pls->dTo = lsf.end; } sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "WALL", 4 ) ) { Log( "Alignment error in file wall load." ); return 0; } if( version > 9 ) sz += fread( &wallsize, 1, sizeof( wallsize ), pFile ); sz += fread( &nwalls, 1, sizeof(nwalls), pFile ); wallarray = (PWALL*)Allocate( sizeof( PWALL ) * nwalls ); for( cnt = 0; cnt < nwalls; cnt++ ) { wallarray[cnt] = GetFromSet( WALL, &world->walls ); } for( cnt = 0; cnt < nwalls; cnt++ ) { FILEWALLV1 ReadWall1; FILEWALLV2 ReadWall2; PWALL pwall; pwall = wallarray[cnt]; if( version < 2 ) { sz += fread( &ReadWall1, 1, sizeof( FILEWALLV1 ), pFile ); pwall->flags = ReadWall1.flags; pwall->iSector = ReadWall1.nSector; SetLineWorld( world, pwall->iLine, linearray[ReadWall1.nLine] ); if( ReadWall1.nWallInto == -1 ) pwall->iWallInto = INVALID_INDEX; else pwall->iWallInto = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall1.nWallInto] ); pwall->iWallStart = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall1.nWallStart] ); pwall->iWallEnd = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall1.nWallEnd] ); } else { sz += fread( &ReadWall2, 1, sizeof( FILEWALLV2 ), pFile ); pwall->flags = ReadWall2.flags; pwall->iSector = ReadWall2.nSector; if( ReadWall2.nLine != -1 ) { pwall->iLine = GetMemberIndex( FLATLAND_MYLINESEG, &world->lines, linearray[ReadWall2.nLine] ); //SetLine( pwall->line, linearray[ReadWall2.nLine] ); } else { Log( "Wall without line? cant be!" ); DebugBreak(); pwall->iLine = INVALID_INDEX; } if( ReadWall2.nWallInto == -1 ) pwall->iWallInto = INVALID_INDEX; else pwall->iWallInto = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall2.nWallInto] ); pwall->iWallStart = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall2.nWallStart] ); pwall->iWallEnd = GetMemberIndex( WALL, &world->walls, wallarray[ReadWall2.nWallEnd] ); } } sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "SECT", 4 ) ) { Log2( "Alignment error in file sector load. %s(%d)", __FILE__, __LINE__ ); return 0; } if( version > 9 ) sz += fread( §orsize, 1, sizeof( sectorsize ), pFile ); sz += fread( &nsectors, 1, sizeof(nsectors), pFile ); sectorarray = (PSECTOR*)Allocate( sizeof( PSECTOR ) * nsectors ); for( cnt = 0; cnt < nsectors; cnt++ ) { FILESECTORV3 ReadSector3; FILESECTORV4 ReadSector4; FILESECTORV5 ReadSector5; FILESECTORV8 ReadSector8; INDEX sector; sectorarray[cnt] = GetFromSet( SECTOR, &world->sectors ); #ifdef OUTPUT_TO_VIRTUALITY sectorarray[cnt]->facet = AddNormalPlane( world->object, VectorConst_0, VectorConst_Z, 0 ); #endif sector = GetMemberIndex( SECTOR, &world->sectors, sectorarray[cnt] ); if( version < 8 ) { // one texture is sufficient... // in fact textures should be highly sharable. sectorarray[cnt]->iTexture = texture; } if( version < 4 ) { /* { char name[20]; sprintf( name, "%d", SectorIDs++ ); sectorarray[cnt]->name = GetName( &world->names, name ); } */ sectorarray[cnt]->iName = INVALID_INDEX; sz += fread( &ReadSector3, 1, sizeof( FILESECTORV3 ), pFile ); sectorarray[cnt]->flags = ReadSector3.flags; sectorarray[cnt]->iWorld = iWorld; SetRay( §orarray[cnt]->r, &ReadSector3.r ); sectorarray[cnt]->iWall = GetMemberIndex( WALL, &world->walls, wallarray[ReadSector3.nwall] ); if( version < 3 ) { ComputeSectorOrigin( iWorld, sector); } } else if( version < 5 ) { sz += fread( &ReadSector4, 1, sizeof( FILESECTORV4 ), pFile ); /* { char name[20]; sprintf( name, "%d", ReadSector4.nID ); sectorarray[cnt]->name = GetName( &world->names, name ); if( atoi( name ) > SectorIDs ) SectorIDs = atoi( name ); } */ sectorarray[cnt]->iName = INVALID_INDEX; sectorarray[cnt]->flags = ReadSector4.flags; sectorarray[cnt]->iWorld = iWorld; SetRay( §orarray[cnt]->r, &ReadSector4.r ); sectorarray[cnt]->iWall = GetMemberIndex( WALL, &world->walls, wallarray[ReadSector4.nwall] ); } else if( version < 8 ) { sz += fread( &ReadSector5, 1, sizeof( FILESECTORV5 ), pFile ); sectorarray[cnt]->iName = ReadSector5.nName; sectorarray[cnt]->flags = ReadSector5.flags; sectorarray[cnt]->iWorld = iWorld; SetRay( §orarray[cnt]->r, &ReadSector5.r ); sectorarray[cnt]->iWall = GetMemberIndex( WALL, &world->walls, wallarray[ReadSector5.nwall] ); } else { sz += fread( &ReadSector8, 1, sizeof( FILESECTORV8 ), pFile ); sectorarray[cnt]->iName = ReadSector8.nName; sectorarray[cnt]->flags = ReadSector8.flags; sectorarray[cnt]->iWorld = iWorld; SetRay( §orarray[cnt]->r, &ReadSector8.r ); sectorarray[cnt]->iWall = ReadSector8.nwall; sectorarray[cnt]->iTexture = ReadSector8.nTexture; } // walls should all be valid at this point... // have valid lines, and valid linkings... ComputeSectorPointList( iWorld, sector, NULL ); ComputeSectorOrigin( iWorld, sector ); #ifdef OUTPUT_TO_VIRTUALITY OrderObjectLines( world->object ); #endif } // fix sector references in walls. //for( cnt = 0; cnt < nwalls; cnt++ ) //{ // wallarray[cnt]->iSector = wallarray[cnt]->iSector; //} for( cnt = 0; cnt < nwalls; cnt++ ) { if( wallarray[cnt]->iLine == INVALID_INDEX ) { SrvrDestroySector( client_id, iWorld, wallarray[cnt]->iSector ); Log( "attempting to fix broken walls" ); break; } } if( version >= 5 ) { sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "NAME", 4 ) ) { Log2( "Alignment error in name section load. %s(%d)", __FILE__, __LINE__ ); return 0; } if( version > 9 ) sz += fread( &namesize, 1, sizeof( namesize ), pFile ); sz += fread( &nnames, 1, sizeof(nnames), pFile ); namearray = (PNAME*)Allocate( sizeof( PNAME ) * nnames ); for( cnt = 0; cnt < nnames; cnt++ ) { namearray[cnt] = GetFromSet( NAME, &world->names ); if( version < 6 ) { uint32_t length; namearray[cnt]->name = (struct name_data*)Allocate( sizeof( *namearray[cnt]->name ) ); sz += fread( &length, 1, sizeof( length ), pFile ); namearray[cnt]->name[0].length = length; namearray[cnt]->name[0].name = (TEXTSTR)Allocate( namearray[cnt]->name[0].length + 1 ); sz += fread( namearray[cnt]->name[0].name, 1, namearray[cnt]->name[0].length, pFile ); namearray[cnt]->name[0].name[namearray[cnt]->name[0].length] = 0; namearray[cnt]->lines = 1; } else if( version < 7 ) { int l; sz += fread( &namearray[cnt]->lines, 1, sizeof( namearray[cnt]->lines ), pFile ); if( namearray[cnt]->lines ) { namearray[cnt]->name = (struct name_data*)Allocate( sizeof( *namearray[cnt]->name ) * namearray[cnt]->lines ); for( l = 0; l < namearray[cnt]->lines; l++ ) { sz += fread( &namearray[cnt]->name[l].length, 1, sizeof( namearray[cnt]->name[l].length ), pFile ); namearray[cnt]->name[l].name = (TEXTSTR)Allocate( namearray[cnt]->name[l].length + 1 ); sz += fread( namearray[cnt]->name[l].name, 1, namearray[cnt]->name[l].length, pFile ); namearray[cnt]->name[l].name[namearray[cnt]->name[l].length] = 0; } } else namearray[cnt]->name = NULL; } else { int l; sz += fread( &namearray[cnt]->flags, 1, sizeof( namearray[cnt]->flags ), pFile ); sz += fread( &namearray[cnt]->lines, 1, sizeof( namearray[cnt]->lines ), pFile ); if( namearray[cnt]->lines ) { namearray[cnt]->name = (struct name_data*)Allocate( sizeof( *namearray[cnt]->name ) * namearray[cnt]->lines ); for( l = 0; l < namearray[cnt]->lines; l++ ) { sz += fread( &namearray[cnt]->name[l].length, 1, sizeof( namearray[cnt]->name[l].length ), pFile ); namearray[cnt]->name[l].name = (TEXTSTR)Allocate( namearray[cnt]->name[l].length + 1 ); sz += fread( namearray[cnt]->name[l].name, 1, namearray[cnt]->name[l].length, pFile ); namearray[cnt]->name[l].name[namearray[cnt]->name[l].length] = 0; } } else namearray[cnt]->name = NULL; } } /* for( cnt = 0; cnt < nsectors; cnt++ ) { if( (int)sectorarray[cnt]->iName == -1 ) sectorarray[cnt]->iName = INVALID_INDEX; else { int n; PNAME pName = namearray[(int)sectorarray[cnt]->name]; if( pName->name && pName->name[0].name ) if( ( n = atoi( pName->name[0].name ) ) > SectorIDs ) SectorIDs = n; sectorarray[cnt]->name = pName; } } */ if( version >= 8 ) { sz += fread( tag, 1, 4, pFile ); if( strncmp( tag, "TEXT", 4 ) ) { Log2( "Alignment error in texture section load. %s(%d)", __FILE__, __LINE__ ); return 0; } if( version > 9 ) sz += fread( &texturesize, 1, sizeof( texturesize ), pFile ); sz += fread( &ntextures, 1, sizeof(ntextures), pFile ); texturearray = (PFLATLAND_TEXTURE*)Allocate( sizeof( PFLATLAND_TEXTURE ) * ntextures ); for( cnt = 0; cnt < ntextures; cnt++ ) { char flag; int nName; sz += fread( &nName, 1, sizeof( nName ), pFile ); texturearray[cnt] = GetFromSet( FLATLAND_TEXTURE, &world->textures ); texturearray[cnt]->iName = GetMemberIndex( NAME, &world->names, namearray[nName] ); sz += fread( &flag, 1, sizeof( flag ), pFile ); texturearray[cnt]->flags.bColor = flag; if( flag ) { sz += fread( &texturearray[cnt]->data.color, 1, sizeof(CDATA), pFile ); } } //for( cnt = 0; cnt < nsectors; cnt++ ) //{ // int ntexture = (int)sectorarray[cnt]->iTexture; // sectorarray[cnt]->texture = NULL; // SetTexture( sectorarray[cnt]->texture, texturearray[ntexture] ); //} Release( texturearray ); } Release( namearray ); } if( version > 9 ) { if( sz != size ) { Log2( "Total load size %d is not %d", sz, size ); } } //for( cnt = 0; cnt < nsectors; cnt++ ) { //PSECTOR pSector = sectorarray[cnt]; // again with the min/max fetch with // spacetree add //pSector->spacenode = AddSpaceNode( &world->spacetree, pSector, min, max ); } Release( linearray ); Release( wallarray ); Release( sectorarray ); ValidateWorldLinks(iWorld); return version; }
int DrawTextureSolidColor( PCOMMON pc, INDEX iSector, CDATA color ) { int npoints, n; _POINT *pointlist; PDISPLAY display = ControlData( PDISPLAY, pc ); DISPLAYPOINT display_points[16]; int top; // at this point - 4 extra points 1 for each // clipping side of the display is sufficient // when we introduce more clip plane - the current // count of planes must be added worst case; pointlist = ComputeSectorPointList( display->pWorld, iSector, &npoints ); //pointlist = sector->pointlist; //npoints = sector->npoints; //glBegin(); //lprintf( WIDE("points %p count %d"), pointlist, npoints ); for( n = 0; n < npoints; n++ ) { //gl display_points[n][0] = DISPLAY_X( display, pointlist[n][0] ); display_points[n][1] = DISPLAY_Y( display, pointlist[n][1] ); //Log3( "Point id: %d at: (%d,%d)", n // , display_points[n][0] // , display_points[n][1] ); } //glEnd(); npoints = ClipDisplayPointsToScreen( npoints, display_points ); if( !IsTextureVisible( pc, npoints, display_points ) ) { //Release( display_points ); return FALSE; } if( npoints ) // if any points are left to display.... { int y; LINEDEL left, right; top = FindTopPoint( npoints, display_points ); //Log1( "Top point is : %d", top ); left.to = right.to = top; left.from = right.from = top; left.len = right.len = 0; y = display_points[top][1]; do { leftloop: { if( !left.len ) { left.from = left.to; if( !StepLineDelta( &left, -1, npoints, display_points ) ) { //Log( "Breaking loop on step left delta" ); break; } if( left.to == right.from ) { //Log( "Leaving loop cause left overlapped right." ); break; } } //Log2( "Stepped Left... doing loop len: %d %d", left.len, left.err ); while( left.len && left.err < 0 ) { left.err += left.dely; left.x += left.xinc; } //Log1( "did loop... doing final increments %d", left.len ); if( left.len ) { left.err -= left.delx; left.len--; } else { //Log( "Supposed to go back and restep left!" ); goto leftloop; } } rightloop: { if( !right.len ) { right.from = right.to; if( !StepLineDelta( &right, 1, npoints, display_points ) ) { //Log( "Breaking loop on step right delta" ); break; } if( right.to == left.from ) { //Log( "Leaving loop cause right overlapped left." ); break; } } //Log1( "Stepped Right... doing loop len: %d", right.len ); while( right.len && right.err < 0 ) { right.err += right.dely; right.x += right.xinc; } //Log1( "did loop... doing final increments %d", right.len ); if( right.len ) { right.err -= right.delx; right.len--; } else { //Log( "Supposed to go back and restep right!" ); goto rightloop; } } { if( right.x > left.x ) do_hlineAlpha( display->pImage, y, left.x, right.x-1, color ); //BlatColorAlpha( display->pImage, left.x, y, right.x-left.x, 1, color ); y++; } // Log4( "DrawLine (%d,%d) - (%d,%d)", left.x, left.y, right.x, right.y ); } while( 1 ); // rely on internal break.... } /* for( n = 0; n < npoints; n++ ) { plot( display->pImage, display_points[n][0] , display_points[n][1] , Color( 255, 0, 0 ) ); } */ //Release( pointlist ); //Release( display_points ); return TRUE; }