INDEX SrvrOpenWorld( uint32_t client_id, CTEXTSTR name ) { PWORLD world; INDEX iWorld; uintptr_t psvResult; psvResult = ForAllInSet( WORLD, g.worlds, CompareWorldName, (uintptr_t)name ); if( psvResult ) { world = (PWORLD)psvResult; iWorld = GetMemberIndex( WORLD, &g.worlds, world ); #if defined( WORLD_SCAPE_SERVER_EXPORTS ) || defined( WORLDSCAPE_SERVICE ) SrvrMarkWorldUpdated( client_id, iWorld ); #endif } else { world = GetFromSet( WORLD, &g.worlds ); iWorld = GetMemberIndex( WORLD, &g.worlds, world ); #if defined( WORLD_SCAPE_SERVER_EXPORTS ) || defined( WORLDSCAPE_SERVICE ) SrvrMarkWorldUpdated( client_id, iWorld ); #endif world->name = SrvrMakeName( client_id, iWorld, name ); // get from set is zero initialized. //world->lines = NULL; //world->walls = NULL; //world->sectors = NULL; //world->textures = NULL; //world->names = NULL; // derr just made a name for this world itself... then do what?! //world->spacetree = NULL; SrvrCreateSquareSector( client_id, iWorld, VectorConst_0, 50 ); } return iWorld; }
INDEX SrvrMakeTexture( uint32_t client_id, INDEX iWorld, INDEX iName ) { PWORLD world = GetSetMember( WORLD, &g.worlds, iWorld ); PFLATLAND_TEXTURE texture; INDEX iTexture = INVALID_INDEX; FINDTHING ft; ft.iWorld = iWorld; ft.iName = iName; if( iName != INVALID_INDEX ) { iTexture = ForAllTextures( iWorld, FindTextureName, (uintptr_t)&ft ); if( iTexture != INVALID_INDEX ) texture = GetSetMember( FLATLAND_TEXTURE, &world->textures, iTexture ); else { texture = GetFromSet( FLATLAND_TEXTURE, &world->textures ); iTexture = GetMemberIndex( FLATLAND_TEXTURE, &world->textures, texture ); texture->iName = iName; } } #if defined( WORLD_SCAPE_SERVER_EXPORTS ) || defined( WORLDSCAPE_SERVICE ) MarkTextureUpdated( client_id, iWorld, iTexture ); #endif return iTexture; }
uintptr_t CPROC CompareWorldName( POINTER p, uintptr_t psv ) { CTEXTSTR name = (CTEXTSTR)psv; PWORLD world = (PWORLD)p; TEXTCHAR buffer[256]; GetNameText( GetMemberIndex( WORLD, &g.worlds, world ), world->name, buffer, sizeof( buffer ) ); if( StrCmp( buffer, name ) == 0 ) return (uintptr_t)world; return 0; }
INDEX MakeName( INDEX iWorld, CTEXTSTR text ) { PWORLD world = GetSetMember( WORLD, &g.worlds, iWorld ); // anmes should be cached... and referenced... // ahh well we'll deal with this for now... there's not // that many names.... // see procreg for someone who needs to worry. PNAME name = GetFromSet( NAME, &world->names ); INDEX iName = GetMemberIndex( NAME, &world->names, name ); MemSet( name, 0, sizeof( NAME ) ); if( text ) SetName( iWorld, iName, text ); #ifdef WORLDSCAPE_SERVICE MarkNameUpdated( iWorld, iName ); #endif return iName; }
INDEX CPROC CheckWallSelect( PWALL wall, PWALLSELECTINFO si ) { GETWORLD(si->iWorld); //PWALL wall = GetWall( iWall ); PFLATLAND_MYLINESEG line = GetLine( wall->iLine ); RCOORD t1, t2; if( FindIntersectionTime( &t1, si->r.n, si->r.o , &t2, line->r.n, line->r.o ) ) { if( t1 >= 0 && t1 <= 1 && t2 >= line->dFrom && t2 <= line->dTo ) { if( si->nwalls < 2 ) { si->walls[si->nwalls++] = GetMemberIndex( WALL, &world->walls, wall ); } else return 1; // breaks for_all loop } //Log4( "Results: %g %g (%g %g)", t1, t2, line->start, line->dTo ); } return 0; }
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; }
INDEX SrvrCreateSquareSector( uint32_t client_id, INDEX iWorld, PC_POINT pOrigin, RCOORD size ) { PWORLD world = GetSetMember( WORLD, &g.worlds, iWorld ); PSECTOR pSector; INDEX iSector; _POINT o, n; pSector = GetFromSet( SECTOR, &world->sectors ); #ifdef OUTPUT_TO_VIRTUALITY pSector->facet = AddNormalPlane( world->object, VectorConst_0, VectorConst_Z, 0 ); #endif iSector = GetMemberIndex( SECTOR, &world->sectors, pSector ); /* { char name[20]; sprintf( name, "%d", SectorIDs++ ); pSector->name = GetName( &world->names, name ); } */ pSector->iName = INVALID_INDEX; pSector->iWorld = iWorld; /* east */ addscaled( o, pOrigin, VectorConst_X, size/2 ); scale( n, VectorConst_Y, 20 ); // creates an open line.... pSector->iWall = SrvrCreateWall( client_id, iWorld, iSector, INVALID_INDEX, FALSE, INVALID_INDEX, FALSE, o, n ); /* south */ addscaled( o, pOrigin, VectorConst_Y, size/2 ); scale( n, VectorConst_X, -20 ); // creates a wall whos start is at the start of the wall... SrvrCreateWall( client_id, iWorld, iSector, pSector->iWall, TRUE, INVALID_INDEX, FALSE, o, n ); /* west */ addscaled( o, pOrigin, VectorConst_Y, -size/2 ); scale( n, VectorConst_X, -20 ); SrvrCreateWall( client_id, iWorld, iSector, pSector->iWall, FALSE, INVALID_INDEX, FALSE, o, n ); /* north */ addscaled( o, pOrigin, VectorConst_X, -size/2 ); scale( n, VectorConst_Y, 20 ); { PWALL pWall = GetSetMember( WALL, &world->walls, pSector->iWall ); SrvrCreateWall( client_id, iWorld, iSector , pWall->iWallStart, TRUE , pWall->iWallEnd, TRUE, o, n ); } //ComputeSectorPointList( iWorld, iSector, NULL ); //ComputeSectorOrigin( iWorld, iSector ); #ifdef OUTPUT_TO_VIRTUALITY OrderObjectLines( world->object ); #endif SetPoint( pSector->r.n, VectorConst_Y ); //DumpWall( pSector->wall ); //DumpWall( pSector->wall->wall_at_start ); //DumpWall( pSector->wall->wall_at_end ); //DumpWall( pSector->wall->wall_at_start->wall_at_end ); { INDEX texture = SrvrMakeTexture( client_id, iWorld, SrvrMakeName( client_id, iWorld, WIDE( "Default" ) ) ); PFLATLAND_TEXTURE pTexture = GetSetMember( FLATLAND_TEXTURE, &world->textures, texture ); if( !pTexture->flags.bColor ) SrvrSetSolidColor( client_id, iWorld, texture, AColor( 170, 170, 170, 0x80 ) ); SrvrSetTexture( client_id, iWorld, iSector, texture ); } #ifdef WORLDSCAPE_SERVER /* this doesn't exist in direct library */ MarkSectorUpdated( client_id, iWorld, iSector ); #endif return iSector; }