void SrvrMergeOverlappingWalls( uint32_t client_id, INDEX iWorld, PORTHOAREA rect ) { // for all walls - find a wall without a mate in the rect area... // then for all remaining walls - find another wall that is the // same line as this one.... GETWORLD(iWorld); int nwalls, n; PWALL *wallarray; wallarray = GetLinearWallArray( world->walls, &nwalls ); for( n = 0; n < nwalls; n++ ) { _POINT start, end; PWALL wall = wallarray[n]; if( wall->iWallInto == INVALID_INDEX ) { PFLATLAND_MYLINESEG line = GetLine( wall->iLine ); addscaled( start, line->r.o, line->r.n, line->dFrom ); addscaled( end, line->r.o, line->r.n, line->dTo ); if( PointInRect( start, rect ) && PointInRect( end, rect ) ) { int m; for( m = n+1; m < nwalls; m++ ) { PWALL wall2 = wallarray[m]; if( wall2->iWallInto == INVALID_INDEX ) { _POINT start2, end2; PFLATLAND_MYLINESEG line = GetLine( wall2->iLine ); addscaled( start2, line->r.o, line->r.n, line->dFrom ); addscaled( end2, line->r.o, line->r.n, line->dTo ); /* if( PointInRect( start2, rect ) && PointInRect( end2, rect ) ) { Log4( "starts: (%12.12g,%12.12g) vs (%12.12g,%12.12g)" ,start[0], start[1] ,start2[0], start2[1] ); Log4( "ends : (%12.12g,%12.12g) vs (%12.12g,%12.12g)" ,end[0], end[1] ,end2[0], end2[1] ); } */ if( ( Near( start2, start ) && Near( end2, end ) ) ||( Near( start2, end ) && Near( end2, start ) ) ) { SrvrMergeWalls( client_id, iWorld, GetWallIndex( wall ), GetWallIndex( wall2 ) ); break; } } } } } } Release( wallarray ); }
int SrvrMergeSelectedWalls( uint32_t client_id, INDEX iWorld, INDEX iDefinite, PORTHOAREA rect ) { GETWORLD(iWorld ); //PWALL pDefinite = GetWall( iDefinite ); WALLSELECTINFO si; // normal 1 si.r.n[0] = rect->w; si.r.n[1] = rect->h; si.r.n[2] = 0; si.r.o[0] = rect->x; si.r.o[1] = rect->y; si.r.o[2] = 0; si.iWorld = iWorld; si.nwalls = 0; if( !ForAllWalls( world->walls, CheckWallSelect, &si ) ) { Log1( "Found %d walls to merge: %d", si.nwalls ); if( si.nwalls == 2 && ( GetWall( si.walls[0] )->iSector != GetWall( si.walls[1] )->iSector ) ) { SrvrMergeWalls( client_id, iWorld, si.walls[0], si.walls[1] ); } if( si.nwalls == 1 && iDefinite != INVALID_INDEX && si.walls[0] != iDefinite ) { SrvrMergeWalls( client_id, iWorld, iDefinite, si.walls[0] ); } return TRUE; } return FALSE; }
int MarkSelectedWalls( INDEX iWorld, PORTHOAREA rect, INDEX **wallarray, int *wallcount ) { GETWORLD( iWorld ); GROUPWALLSELECTINFO si; si.iWorld = iWorld; si.rect = rect; si.nwalls = 0; si.ppwalls = NULL; ForAllWalls( world->walls, CheckWallInRect, &si ); if( si.nwalls ) { if( wallcount ) *wallcount = si.nwalls; if( wallarray ) { *wallarray = (INDEX*)Allocate( sizeof( INDEX ) * si.nwalls ); si.ppwalls = *wallarray; si.nwalls = 0; ForAllWalls( world->walls, CheckWallInRect, &si ); } return TRUE; } else { if( wallcount ) *wallcount = si.nwalls; if( wallarray ) *wallarray = NULL; } return FALSE; }
void SetName( INDEX iWorld, INDEX iName, CTEXTSTR text ) { GETWORLD( iWorld ); PNAME name = GetName( iName ); int l, start, end; if( !name ) return; if( name->name ) { for( l = 0; l < name->lines; l++ ) Release( name->name[l].name ); Release( name->name ); } name->lines = LineCount( text ); if( name->lines ) { name->name = (struct name_data*)Allocate( sizeof( *name->name ) * name->lines ); start = 0; end = 0; for( l= 0; l < name->lines; l++ ) { while( text[end] && text[end] != '\n' ) end++; name->name[l].length = end-start; name->name[l].name = (TEXTCHAR*)Allocate( (end-start) + 1 ); MemCpy( name->name[l].name, text + start, end-start ); name->name[l].name[end-start] = 0; start = end+1; end = start; } } else name->name = NULL; }
static INDEX CPROC DeleteATexture( INDEX iTexture, uintptr_t psv ) { INDEX iWorld = (INDEX)psv; GETWORLD( iWorld ); PFLATLAND_TEXTURE texture = GetSetMember( FLATLAND_TEXTURE, &world->textures, iTexture ); if( texture ) DeleteName( iWorld, texture->iName ); DeleteFromSet( FLATLAND_TEXTURE, world->textures, texture ); return INVALID_INDEX; }
INDEX FindSectorAroundPoint( INDEX iWorld, P_POINT p ) { GETWORLD( iWorld ); struct { INDEX iWorld; P_POINT p; } data; data.iWorld = iWorld; data.p = p; // hmm no spacetree now? //return FindPointInSpace( world->spacetree, p, PointWithinSingle ); return DoForAllSectors( world->sectors, FlatlandPointWithinLoopSingle, &data ) - 1; }
static uintptr_t CPROC DeleteAName( PNAME name, INDEX iWorld ) { GETWORLD( iWorld ); int l; if( name ) { if( name->name ) { for( l = 0; l < name->lines; l++ ) Release( name->name[l].name ); Release( name->name ); name->name = NULL; } DeleteFromSet( NAME, world->names, name ); } return 0; }
int CPROC CheckWallInRect( uint32_t client_id, PWALL wall, PGROUPWALLSELECTINFO psi ) { GETWORLD(psi->iWorld); _POINT p1, p2; PORTHOAREA rect = psi->rect; // shorter pointer if( wall->iLine == INVALID_INDEX ) { PSECTOR sector = GetSector( wall->iSector ); Log( "Line didn't exist..." ); if( sector ) { PNAME name = GetName( sector->iName ); Log( "Sector exists..." ); if( name && name[0].name ) Log1( "Wall in Sector %s does not have a line", name[0].name ); else Log( "Sector referenced does not have a name" ); } else Log( "Wall should not be active... WHY is it?!" ); } else { PFLATLAND_MYLINESEG line = GetLine( wall->iLine ); addscaled( p1, line->r.o, line->r.n, line->dFrom ); addscaled( p2, line->r.o, line->r.n, line->dTo ); if( !PointInRect( p1, rect) || !PointInRect( p2, rect) ) { return 0; } else { if( psi->ppwalls ) { psi->ppwalls[psi->nwalls++] = GetWallIndex( wall ); SrvrBalanceALine( client_id, psi->iWorld, wall->iLine ); } else psi->nwalls++; } } return 0; // abort immediate... }
int MarkSelectedSectors( INDEX iWorld, PORTHOAREA rect, INDEX **sectorarray, int *sectorcount ) { GETWORLD( iWorld ); SECTORSELECTINFO si; si.rect = rect; si.nsectors = 0; si.ppsectors = NULL; si.iWorld = iWorld; if( rect->w < 0 ) { rect->x += rect->w; rect->w = -rect->w; } if( rect->h < 0 ) { rect->y += rect->h; rect->h = -rect->h; } Log( "Marking Sectors" ); DoForAllSectors( world->sectors, CheckSectorInRect, (uintptr_t)&si ); if( si.nsectors ) { Log1( "Found %d sectors in range", si.nsectors ); if( sectorcount ) *sectorcount = si.nsectors; if( sectorarray ) { *sectorarray = (INDEX*)Allocate( sizeof( INDEX ) * si.nsectors ); si.ppsectors = *sectorarray; si.nsectors = 0; DoForAllSectors( world->sectors, CheckSectorInRect, (uintptr_t)&si ); } return TRUE; } else { if( sectorcount ) *sectorcount = si.nsectors; if( sectorarray ) *sectorarray = NULL; } return FALSE; }
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 ValidateWorldLinks( INDEX iWorld ) { GETWORLD(iWorld); int status = TRUE; int nLines; PFLATLAND_MYLINESEG *pLines; int nWalls; PWALL *pWalls; int nSectors; PSECTOR *pSectors; int nNames; PNAME *pNames; pSectors = GetLinearSectorArray( world->sectors, &nSectors ); pWalls = GetLinearWallArray( world->walls, &nWalls ); pLines = GetLinearLineArray( world->lines, &nLines ); pNames = GetLinearNameArray( world->names, &nNames ); { int n, m, refcount; for( n = 0; n < nLines; n++ ) { refcount = 0; for( m = 0; m < nWalls; m++ ) { if( GetLine( pWalls[m]->iLine ) == pLines[n] ) { if( pWalls[m]->iWallInto != INVALID_INDEX ) { refcount++; if( refcount == 2 ) { //pLines[n] = NULL; break; } } } else { //pLines[n] = NULL; break; } } if( m == nWalls ) { status = FALSE; Log1( "Line %08x is unreferenced... deleting now.", pLines[n] ); DeleteLine( world->lines, pLines[n] ); pLines[n] = NULL; } } for( n = 0; n < nWalls; n++ ) { if( !pWalls[n] ) continue; for( m = 0; m < nLines; m++ ) { if( GetLine( pWalls[n]->iLine ) == pLines[m] ) { // if this line is shared - remove the other reference to it. /* if( pWalls[n]->wall_into ) { int i; for( i = 0; i < nWalls; i++ ) { if( pWalls[i] == pWalls[n]->wall_into ) pWalls[i] = NULL; } } pLines[m] = NULL; // clear line reference... */ break; } } if( m == nLines ) { status = FALSE; Log3( "Wall %08x in Sector %d referenced line %08x that does not exist", pWalls[n], GetSector( pWalls[n]->iSector )->iName, pWalls[n]->iLine ); } } for( n = 0; n < nLines; n++ ) { int count = 0; if( !pLines[n]->refcount ) Log( "Line exists with no reference count" ); for( m = 0; m < nWalls; m++ ) { if( GetLine( pWalls[m]->iLine ) == pLines[n] ) { count++; } } if( count != pLines[n]->refcount ) { Log2( "Line reference count of %d does not match actual %d" , pLines[n]->refcount , count ); } } for( n = 0; n < nSectors; n++ ) { PWALL pStart, pCur; int priorend = TRUE; if( pSectors[n]->iName != INVALID_INDEX ) { int i; for( i = 0; i < nNames; i++ ) { if( GetName( pSectors[n]->iName ) == pNames[i] ) break; } if( i == nNames ) { Log2( "Name %08x referenced by Sector %d does not exist", pSectors[n]->iName, n ); } } pCur = pStart = GetWall( pSectors[n]->iWall ); do { if( pCur->iLine == INVALID_INDEX ) { Log1( "Wall in sector %d has an invalid line def", pSectors[n]->iName ); } for( m = 0; m < nWalls; m++ ) { if( pWalls[m] == pCur ) break; } if( m == nWalls ) { status = FALSE; Log4( "Sector %*.*s referenced wall %08x that does not exist", GetName( pSectors[n]->iName )->name[0].length, GetName( pSectors[n]->iName )->name[0].length, GetName( pSectors[n]->iName )->name[0].name, pCur ); } // code goes here.... if( priorend ) { priorend = pCur->flags.wall_start_end; pCur = GetWall( pCur->iWallStart ); } else { priorend = pCur->flags.wall_end_end; pCur = GetWall( pCur->iWallEnd ); } }while( pCur != pStart ); } } Release( pLines ); Release( pWalls ); Release( pSectors ); Release( pNames ); return status; }
void DeleteTextures( INDEX iWorld ) { GETWORLD( iWorld ); ForAllTextures( iWorld, DeleteATexture, (uintptr_t)iWorld ); DeleteSet( (GENERICSET**)&world->textures ); }
void DeleteName( INDEX iWorld, INDEX iName ) { GETWORLD( iWorld ); DeleteAName( GetName( iWorld ), iWorld ); }