static void PVExit (CPURegs* Regs) { Print (stderr, 1, "PVExit ($%02X)\n", Regs->AC); if (PrintCycles) { Print (stdout, 0, "%lu cycles\n", GetCycles ()); } exit (Regs->AC); }
//--------------------------------------------------------------------------- bool Team::lineOfSight(float startLocal, int32_t mCellRow, int32_t mCellCol, int32_t tCellRow, int32_t tCellCol, int32_t teamId, float extRad, bool checkVisibleBits) { #ifdef LAB_ONLY int64_t x = GetCycles(); #endif //----------------------------------------------------- // Once we allow teams to have alliances (for contacts, // etc.), simply set all nec. team bits in this mask... //TILE HACK... int32_t tileRow = tCellRow / 3; int32_t tileCol = tCellCol / 3; if((teamId < 0) || (teamId >= MAX_TEAMS)) //Not on any team. It can see everything! return true; if(checkVisibleBits) { uint8_t teamMask = 0x01 << teamId; uint8_t visbBits[4]; //---------------------------------------------------------------------------- // First check is simple. Is anyone within the magical line of sight radius? // If not, return false and move on. // If they are, you MUST check LOS between this object and the other one. bool losResult = false; visbBits[0] = Terrain::VisibleBits->getFlag(tileRow, tileCol); if(visbBits[0] & teamMask) losResult = true; if(!losResult) { visbBits[1] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol); if(visbBits[1] & teamMask) losResult = true; } if(!losResult) { visbBits[2] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol + 1); if(visbBits[2] & teamMask) losResult = true; } if(!losResult) { visbBits[3] = Terrain::VisibleBits->getFlag(tileRow, tileCol + 1); if(visbBits[3] & teamMask) losResult = true; } if(!losResult) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return losResult; } } if(useRealLOS) { //------------------------------------------------------------------------------------------ // Within magic radius. Check REAL LOS now. // Check is really simple. // Find deltaCellRow and deltaCellCol and iterate over them from source to dest. // If the magic line ever goes BELOW the terrainElevation PLUS localElevation return false. Stuff::Vector3D startPos, endPos; startPos.Zero(); endPos.Zero(); land->getCellPos(tCellRow, tCellCol, endPos); land->getCellPos(mCellRow, mCellCol, startPos); startPos.z += startLocal; Stuff::Vector3D deltaCellVec; deltaCellVec.y = tCellRow - mCellRow; deltaCellVec.x = tCellCol - mCellCol; deltaCellVec.z = 0.0f; float startHeight = startPos.z; float length = deltaCellVec.GetApproximateLength(); if(length > Stuff::SMALL) { float colLength = deltaCellVec.x / length; float rowLength = deltaCellVec.y / length; float heightLen = (endPos.z - startPos.z) / length; float lastCol = fabs(colLength * 2.0); float lastRow = fabs(rowLength * 2.0); float startCellRow = mCellRow; float startCellCol = mCellCol; float endCellRow = tCellRow; float endCellCol = tCellCol; Stuff::Vector3D currentPos = startPos; Stuff::Vector3D dist; dist.Subtract(endPos, currentPos); float remainingDist = dist.GetApproximateLength(); bool colDone = false, rowDone = false; while(!colDone || !rowDone) { if(fabs(startCellRow - endCellRow) > lastRow) //DO NOT INCLUDE LAST CELL!!!!! { startCellRow += rowLength; } else { // startCellRow = (endCellRow - lastRow); rowDone = true; } if(fabs(startCellCol - endCellCol) > lastCol) //DO NOT INCLUDE LAST CELL!!!!! { startCellCol += colLength; } else { // startCellCol = (endCellCol - lastCol); colDone = true; } startHeight += heightLen; int32_t startCellC = startCellCol; int32_t startCellR = startCellRow; land->getCellPos(startCellR, startCellC, currentPos); float localElev = (worldUnitsPerMeter * 4.0f * (float)GameMap->getLocalHeight(startCellR, startCellC)); currentPos.z += localElev; if(startHeight + startLocal < currentPos.z) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_RED, nullptr, -1); } #endif return false; } if(extRad > Stuff::SMALL) { dist.Subtract(endPos, currentPos); remainingDist = dist.GetApproximateLength(); if(remainingDist < extRad) break; } } } #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_GREEN, nullptr, -1); } #endif } #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return true; }
double sSysEnv::GetSeconds() const { return ( GetCycles() * FRecipCyclesPerSecond ); }
//--------------------------------------------------------------------------- bool Team::lineOfSight(float startLocal, int32_t mCellRow, int32_t mCellCol, float endLocal, int32_t tCellRow, int32_t tCellCol, int32_t teamId, float extRad, float startExtRad, bool checkVisibleBits) { #ifdef LAB_ONLY int64_t x = GetCycles(); #endif //----------------------------------------------------- // Once we allow teams to have alliances (for contacts, // etc.), simply set all nec. team bits in this mask... //TILE HACK... int32_t tileRow = tCellRow / 3; int32_t tileCol = tCellCol / 3; if((teamId < 0) || (teamId >= MAX_TEAMS)) //Not on any team. It can see everything! return true; #if 0 //Don't need to check this anymore. We do a distance check outside of this function. if(checkVisibleBits) { uint8_t teamMask = 0x01 << teamId; uint8_t visbBits[4]; //---------------------------------------------------------------------------- // First check is simple. Is anyone within the magical line of sight radius? // If not, return false and move on. // If they are, you MUST check LOS between this object and the other one. bool losResult = false; visbBits[0] = Terrain::VisibleBits->getFlag(tileRow, tileCol); if(visbBits[0] & teamMask) losResult = true; if(!losResult) { visbBits[1] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol); if(visbBits[1] & teamMask) losResult = true; } if(!losResult) { visbBits[2] = Terrain::VisibleBits->getFlag(tileRow + 1, tileCol + 1); if(visbBits[2] & teamMask) losResult = true; } if(!losResult) { visbBits[3] = Terrain::VisibleBits->getFlag(tileRow, tileCol + 1); if(visbBits[3] & teamMask) losResult = true; } if(!losResult) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return losResult; } } #endif if(useRealLOS) { //------------------------------------------------------------------------------------------ // Within magic radius. Check REAL LOS now. // Check is really simple. // Find deltaCellRow and deltaCellCol and iterate over them from source to dest. // If the magic line ever goes BELOW the terrainElevation PLUS localElevation return false. Stuff::Vector3D startPos, endPos; startPos.Zero(); endPos.Zero(); land->getCellPos(tCellRow, tCellCol, endPos); land->getCellPos(mCellRow, mCellCol, startPos); startPos.z += startLocal; endPos.z += endLocal; Stuff::Vector3D deltaCellVec; deltaCellVec.y = tCellRow - mCellRow; deltaCellVec.x = tCellCol - mCellCol; deltaCellVec.z = 0.0f; float startHeight = startPos.z; float length = deltaCellVec.GetApproximateLength(); length *= ACCURACY_ADJUST; if(length > Stuff::SMALL) { float colLength = (endPos.x - startPos.x) / length; float rowLength = (endPos.y - startPos.y) / length; float heightLen = (endPos.z - startPos.z) / (length + ACCURACY_ADJUST); Stuff::Vector3D currentPos = startPos; currentPos.z = land->getTerrainElevation(currentPos); int32_t maxDistIter = (length - 0.5f); int32_t maxTrees = 0; Stuff::Vector3D dist; dist.Subtract(endPos, currentPos); float remainingDist = dist.GetApproximateLength(); bool checkExtent = (extRad > Stuff::SMALL); bool checkStart = (startExtRad > Stuff::SMALL); extRad += HALF_CELL_DIST; for(size_t distIter = 0; distIter < maxDistIter; distIter++) { bool outsideStartRadius = true; if(checkStart) { Stuff::Vector3D distance; distance.Subtract(currentPos, startPos); distance.z = 0.0f; float dist = distance.GetApproximateLength(); if(dist <= startExtRad) outsideStartRadius = false; } startHeight += heightLen; int32_t curCellRow, curCellCol; land->worldToCell(currentPos, curCellRow, curCellCol); float localElev = (worldUnitsPerMeter * 4.0f * (float)GameMap->getLocalHeight(curCellRow, curCellCol)); float thisHeight = currentPos.z + localElev; //First, check if we are now inside the extent radius of the thing we are calcing LOS to. // If we are and we haven't returned false since we're here, we can see it!!!! if(checkExtent) { dist.Subtract(endPos, currentPos); remainingDist = dist.GetApproximateLength(); if(remainingDist <= extRad) break; } if(outsideStartRadius && (startHeight < thisHeight)) { bool isTree = false; if(GameMap->getForest(curCellRow, curCellCol)) { maxTrees++; isTree = true; } if(!isTree || (maxTrees >= MaxTreeLOSCellBlock)) { #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_RED, nullptr, -1); } #endif return false; } } currentPos.x += colLength; currentPos.y += rowLength; currentPos.z = land->getTerrainElevation(currentPos); } } #ifdef LAB_ONLY if(drawTerrainGrid) { Stuff::Vector3D realStart = startPos; Stuff::Vector4D lineStart, lineEnd; eye->projectZ(realStart, lineStart); eye->projectZ(endPos, lineEnd); debugLines[currentLineElement++] = new LineElement(lineStart, lineEnd, SD_GREEN, nullptr, -1); } #endif } #ifdef LAB_ONLY x = GetCycles() - x; MCTimeLOSCalc += x; #endif return true; }