/**
 * Find next angle at side
 *
 * @param side     Side of angle
 * @param angle    Return at success found angle
 *
 * @return true, if angle found
 *
 */
bool ObjectPosSelector::NextSideAngle(UsedAreaSide side, float& angle)
{
    // next possible angle
    m_stepAngle[side] += (m_searchedForReqHAngle + 0.01);

    // prevent jump to another side
    if (m_stepAngle[side] > M_PI_F)
        return false;

    // no used area anymore on this side
    if (m_nextUsedAreaItr[side] == m_UsedAreaLists[side].end())
    {
        angle = m_stepAngle[side] * SignOf(side);
        return true;
    }

    // Already occupied and no better found
    if ((m_searchPosFor && m_nextUsedAreaItr[side]->second.occupyingObj == m_searchPosFor) ||
            // Next occupied is too far away
            (m_stepAngle[side] + m_searchedForReqHAngle < m_nextUsedAreaItr[side]->first - m_nextUsedAreaItr[side]->second.angleOffset))
    {
        angle = m_stepAngle[side] * SignOf(side);
        return true;
    }

    // angle set at first possible pos after passed m_nextUsedAreaItr
    m_stepAngle[side] = m_nextUsedAreaItr[side]->first + m_nextUsedAreaItr[side]->second.angleOffset;

    ++m_nextUsedAreaItr[side];

    return false;
}
/**
 * Check searcher circle not intercepting with used circle
 *
 * @param usedArea Used circle as projection to searcher distance circle in angles form
 * @param side     Side of used circle
 * @param angle    Checked angle
 *
 * @return true, if used circle not intercepted with searcher circle in terms projection angles
 */
bool ObjectPosSelector::CheckAngle(UsedArea const& usedArea, UsedAreaSide side, float angle) const
{
    float used_angle = usedArea.first * SignOf(side);
    float used_offset = usedArea.second;

    return fabs(used_angle - angle) > used_offset;
}
/**
 * Find next angle at side
 *
 * @param side     Side of angle
 * @param angle    Return at success found angle
 *
 * @return true, if angle found
 *
 */
bool ObjectPosSelector::NextSideAngle(UsedAreaSide side, float& angle)
{
    // next possible angle
    m_stepAngle[side] += (m_searcherHalfSize + 0.01);

    // prevent jump to another side
    if (m_stepAngle[side] > M_PI_F)
        return false;

    // update angle at attempt jump after next used area
    while (m_stepAngle[side] <= M_PI_F && m_stepAngle[side] + m_searcherHalfSize >= m_nextUsedAreaStart[side])
    {
        // no used area for pass
        if (m_nextUsedAreaItr[side] == m_UsedAreaLists[side].end())
        {
            m_stepAngle[side] = M_PI_F + m_searcherHalfSize;// prevent continue search at side
            return false;
        }

        // angle set at first possible pos after passed m_nextUsedAreaItr
        m_stepAngle[side] = m_nextUsedAreaItr[side]->first + m_nextUsedAreaItr[side]->second;

        ++m_nextUsedAreaItr[side];
        UpdateNextAreaStart(side);
    }

    angle = m_stepAngle[side] * SignOf(side);

    // if next node not allow use selected angle, mark and fail
    return CheckSideAngle(side, m_stepAngle[side]);
}
/**
 * Check searcher circle not intercepting with used circle
 *
 * @param usedArea Used circle as projection to searcher distance circle in angles form
 * @param side     Side of used circle
 * @param angle    Checked angle
 *
 * @return true, if used circle not intercepted with searcher circle in terms projection angles
 */
bool ObjectPosSelector::CheckAngle(UsedArea const& usedArea, UsedAreaSide side, float angle) const
{
    float used_angle = usedArea.first * SignOf(side);
    float used_offset = usedArea.second.angleOffset;

    return fabs(used_angle - angle) > used_offset || (m_searchPosFor && usedArea.second.occupyingObj == m_searchPosFor);
}
Beispiel #5
0
int WriteFloat(FormatPrintTarget* target,
               const PrintSpecification& spec,
               const char* length,
               T value)
{
    if (!spec.SpecifierMatch("aefgAEFG")) {
        LOG(DFATAL) << "Invalid print specifier '" << spec.specifier
                    << "' for unsigned integral type";
        return -1;
    }

    char buf[4096];
    char specifier = spec.specifier != 'v' ? spec.specifier : 'g';
    char format[16];
    if (spec.has_precision()) {
        snprintf(format, sizeof(format), "%%.%d%s%c",
                 std::min(spec.precision, 16), length, specifier);
    } else {
        if (spec.flags.sharp)
            snprintf(format, sizeof(format), "%%.6%s%c", length, specifier);
        else
            snprintf(format, sizeof(format), "%%%s%c", length, specifier);
    }
    char* digits = buf;
    int n = snprintf(buf, sizeof(buf), format, value);
    if (buf[0] == '-') {
        ++digits;
        --n;
    }
    char sign = SignOf(spec, value < 0);
    int leading_zeros = 0;
    int padding_zeros = 0;
    return WriteNumberString(target, spec, sign, NULL, 0, leading_zeros,
                             buf, n, padding_zeros, NULL, 0);
}
Beispiel #6
0
static void AdjustForBuggyXinerama(int &_xrel, int &_yrel)
{
	/* Linux has buggy multiple screen support which causes the
	   mouse events to be all screwed up */

	// Xinerama offset
	static int offsetX = 0, offsetY = 0;
	static int screenW = 0, screenH = 0;
	static int frameCount = 0;

	if (screenW != g_app->m_renderer->ScreenW() ||
		screenH != g_app->m_renderer->ScreenH()) {
		// Resolution changed

		screenW = g_app->m_renderer->ScreenW();
		screenH = g_app->m_renderer->ScreenH();

		// We want to skip the first few mouse events
		// As we can get some funny behaviour after a resolution change
		frameCount = 3;
	}
	
	if (frameCount >= 0)
		frameCount--;
	
	if (frameCount == 0) {
		// Guess Xinerama offset
		int hypot = sqrt(_xrel*_xrel + _yrel*_yrel);
		if (hypot >= 550) {
			offsetX = (_xrel + SignOf(_xrel)*32) / 64 * 64;
			offsetY = (_yrel + SignOf(_yrel)*32) / 64 * 64;
		}
		else {
			offsetX = 0;
			offsetY = 0;
		}
		AppDebugOut("XINERAMA offset guess: %d, %d\n", offsetX, offsetY);
	}

	_xrel -= offsetX;
	_yrel -= offsetY;
}
/**
 * Find next angle in used area, that used if no angle found in free area with LoS
 *
 * @param angle    Return at success found angle
 *
 * @return true, if angle found
 */
bool ObjectPosSelector::NextUsedAngle(float& angle)
{
    if (m_nextUsedAreaItr[USED_POS_PLUS] == m_UsedAreaLists[USED_POS_PLUS].end() &&
        m_nextUsedAreaItr[USED_POS_MINUS] == m_UsedAreaLists[USED_POS_MINUS].end())
        return false;

    // ++ direction less updated
    if (m_nextUsedAreaItr[USED_POS_PLUS] != m_UsedAreaLists[USED_POS_PLUS].end() &&
        (m_nextUsedAreaItr[USED_POS_MINUS] == m_UsedAreaLists[USED_POS_MINUS].end() ||
         m_nextUsedAreaItr[USED_POS_PLUS]->first <= m_nextUsedAreaItr[USED_POS_MINUS]->first))
    {
        angle = m_nextUsedAreaItr[USED_POS_PLUS]->first * SignOf(USED_POS_PLUS);
        ++m_nextUsedAreaItr[USED_POS_PLUS];
    }
    else
    {
        angle = m_nextUsedAreaItr[USED_POS_MINUS]->first * SignOf(USED_POS_MINUS);
        ++m_nextUsedAreaItr[USED_POS_MINUS];
    }

    return true;
}
Beispiel #8
0
static int WriteSigned(FormatPrintTarget* target,
                       const PrintSpecification& spec, Type value)
{
    if (!spec.SpecifierMatch("idxXo")) {
        LOG(DFATAL) << "Invalid print specifier '" << spec.specifier
                    << "' for signed integral type";
        return -1;
    }

    char buf[64];
    char* digits = buf;
    int n = 0;
    switch (spec.specifier) {
    case 'i':
    case 'd':
    case 'v':
        n = WriteIntegerToBuffer(value, buf) - buf;
        if (buf[0] == '-') {
            ++digits;
            --n;
        }
        break;
    case 'x':
        n = UnsignedToString<16>(ToUnsigned(value), buf, "0123456789abcdef") - buf;
        break;
    case 'X':
        n = UnsignedToString<16>(ToUnsigned(value), buf, "0123456789ABCDEF") - buf;
        break;
    case 'o':
        n = UnsignedToString<8>(ToUnsigned(value), buf, "01234567") - buf;
        break;
    }

    int leading_zeros = 0;
    if (spec.has_precision()) {
        // Special case: Output empty digits for 0 if prec is 0
        if (value == 0 && spec.precision == 0)
            n = 0;
        if (spec.precision > n)
            leading_zeros = spec.precision - n;
    }
    const char* prefix = PrefixOf(spec, value == 0);
    char sign = SignOf(spec, value < 0);
    return WriteNumberString(target, spec, sign, prefix, strlen(prefix),
                             leading_zeros, digits, n, 0, NULL, 0);
}