Exemplo n.º 1
0
/**
   Render a division line for land placement

   @painter QPainter object
 */
void TableZone::paintLandDivider(QPainter *painter){
    painter->setPen(QColor(255, 255, 255, 40));
    qreal separatorY = 2 * (CARD_HEIGHT + 20 + PADDING_Y) + BOX_LINE_WIDTH - PADDING_Y / 2;
    if (isInverted())
        separatorY = height - separatorY;
    painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
}
Exemplo n.º 2
0
void ScrollBar::moveSlider(double min, double max)
{
    const int sliderTicks = qRound((max - min) / 
        (d_maxBase - d_minBase) * d_baseTicks);

    // setRange initiates a valueChanged of the scrollbars
    // in some situations. So we block
    // and unblock the signals.

    blockSignals(true);

    setRange(sliderTicks / 2, d_baseTicks - sliderTicks / 2);
    int steps = sliderTicks / 200;
    if ( steps <= 0 )
        steps = 1;

    setSingleStep(steps);
    setPageStep(sliderTicks);

    int tick = mapToTick(min + (max - min) / 2);
    if ( isInverted() )
        tick = d_baseTicks - tick;

    setSliderPosition(tick);
    blockSignals(false);
}
Exemplo n.º 3
0
QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
{
    qreal x = mapPoint.x() - MARGIN_X;
    qreal y = mapPoint.y();
/*    if (isInverted())
        y = height - y;
*/    y -= BOX_LINE_WIDTH;
    
    if (x < 0)
        x = 0;
    else if (x > width - CARD_WIDTH - MARGIN_X)
        x = width - CARD_WIDTH - MARGIN_X;
    if (y < 0)
        y = 0;
    else if (y > height - CARD_HEIGHT)
        y = height - CARD_HEIGHT;
    
    int resultY = round(y / (CARD_HEIGHT + PADDING_Y + 20));
    if (isInverted())
        resultY = 2 - resultY;

    int baseX = -1;
    qreal oldTempX = 0, tempX = 0;
    do {
        ++baseX;
        oldTempX = tempX;
        tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + PADDING_X;
    } while (tempX < x + 1);
    
    qreal xdiff = x - oldTempX;
    int resultX = baseX * 3 + qMin((int) floor(xdiff * 3 / CARD_WIDTH), 2);
    return QPoint(resultX, resultY);
}
Exemplo n.º 4
0
QPointF TableZone::mapFromGrid(QPoint gridPoint) const
{
    qreal x, y;

    // Start with margin plus stacked card offset
    x = MARGIN_LEFT + (gridPoint.x() % 3) * STACKED_CARD_OFFSET_X;

    // Add in width of card stack plus padding for each column
    for (int i = 0; i < gridPoint.x() / 3; ++i)
    {
        const int key = getCardStackMapKey(i, gridPoint.y());
        x += cardStackWidth.value(key, CARD_WIDTH) + PADDING_X;
    }
    
    if (isInverted())
        gridPoint.setY(TABLEROWS - 1 - gridPoint.y());
    
    // Start with margin plus stacked card offset
    y = MARGIN_TOP + (gridPoint.x() % 3) * STACKED_CARD_OFFSET_Y;

    // Add in card size and padding for each row
    for (int i = 0; i < gridPoint.y(); ++i)
        y += CARD_HEIGHT + PADDING_Y;

    return QPointF(x, y);
}
Exemplo n.º 5
0
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
    if (bgPixmap.isNull())
        painter->fillRect(boundingRect(), QColor(0, 0, 100));
    else
        painter->fillRect(boundingRect(), QBrush(bgPixmap));
    painter->setPen(QColor(255, 255, 255, 40));
    qreal separatorY = 2 * (CARD_HEIGHT + 20 + paddingY) + boxLineWidth - paddingY / 2;
    if (isInverted())
        separatorY = height - separatorY;
    painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
    
    if (active) {
        QColor color1(255, 255, 255, 150);
        QColor color2(255, 255, 255, 0);
        QLinearGradient grad1(0, 0, 0, 1);
        grad1.setCoordinateMode(QGradient::ObjectBoundingMode);
        grad1.setColorAt(0, color1);
        grad1.setColorAt(1, color2);
        painter->fillRect(QRectF(0, 0, width, boxLineWidth), QBrush(grad1));
        
        grad1.setFinalStop(1, 0);
        painter->fillRect(QRectF(0, 0, boxLineWidth, height), QBrush(grad1));
        
        grad1.setStart(0, 1);
        grad1.setFinalStop(0, 0);
        painter->fillRect(QRectF(0, height - boxLineWidth, width, boxLineWidth), QBrush(grad1));
        
        grad1.setStart(1, 0);
        painter->fillRect(QRectF(width - boxLineWidth, 0, boxLineWidth, height), QBrush(grad1));
    }
}
Exemplo n.º 6
0
    void buttonStateChanged(ButtonWidget &, ButtonWidget::State state)
    {
        switch (state)
        {
        case ButtonWidget::Up:
            if (!isInverted())
            {
                setAuxBorderColorf(style().colors().colorf("accent"));
                aux->setTextModulationColorf(style().colors().colorf("accent"));
            }
            else
            {
                setAuxBorderColorf(style().colors().colorf("inverted.accent"));
                aux->setTextModulationColorf(style().colors().colorf("inverted.accent"));
            }
            break;

        case ButtonWidget::Hover:
            if (!isInverted())
            {
                setAuxBorderColorf(style().colors().colorf("text"));
                aux->setTextModulationColorf(style().colors().colorf("text"));
            }
            else
            {
                setAuxBorderColorf(style().colors().colorf("inverted.text"));
                aux->setTextModulationColorf(style().colors().colorf("inverted.text"));
            }
            break;

        case ButtonWidget::Down:
            if (!isInverted())
            {
                setAuxBorderColorf(style().colors().colorf(""),
                                   style().colors().colorf("inverted.background"));
                aux->setTextModulationColorf(style().colors().colorf("inverted.text"));
            }
            else
            {
                setAuxBorderColorf(style().colors().colorf(""),
                                   style().colors().colorf("background"));
                aux->setTextModulationColorf(style().colors().colorf("text"));
            }
            break;
        }
    }
Exemplo n.º 7
0
static void orientLoci(Locus * loci, IDnum locusCount)
{
	IDnum index;

	for (index = 0; index < locusCount; index++) {
		if (isInverted(getLocus(loci, index)))
			revert(getLocus(loci, index));
	}
}
Exemplo n.º 8
0
/**
   Render a division line for land placement

   @painter QPainter object
 */
void TableZone::paintLandDivider(QPainter *painter){
    // Place the line 2 grid heights down then back it off just enough to allow
    // some space between a 3-card stack and the land area.
    qreal separatorY = MARGIN_TOP + 2 * (CARD_HEIGHT + PADDING_Y) - STACKED_CARD_OFFSET_Y / 2;
    if (isInverted())
        separatorY = height - separatorY;
    painter->setPen(QColor(255, 255, 255, 40));
    painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY));
}
Exemplo n.º 9
0
void ScrollBar::sliderRange(int value, double &min, double &max) const
{
    if ( isInverted() )
        value = d_baseTicks - value;

    const int visibleTicks = pageStep();

    min = mapFromTick(value - visibleTicks / 2);
    max = mapFromTick(value + visibleTicks / 2);
}
Exemplo n.º 10
0
/*!
   Mouse press event handler
   \param event Mouse event
*/
void QwtSlider::mousePressEvent( QMouseEvent *event )
{
    if ( isReadOnly() )
    {
        event->ignore();
        return;
    }

    const QPoint pos = event->pos();

    if ( isValid() && d_data->sliderRect.contains( pos ) )
    {
        if ( !handleRect().contains( pos ) )
        {
            const int markerPos = transform( value() );

            d_data->stepsIncrement = pageSteps();

            if ( d_data->orientation == Qt::Horizontal )
            {
                if ( pos.x() < markerPos )
                    d_data->stepsIncrement = -d_data->stepsIncrement;
            }
            else
            {
                if ( pos.y() < markerPos )
                    d_data->stepsIncrement = -d_data->stepsIncrement;
            }

            if ( isInverted() )
                d_data->stepsIncrement = -d_data->stepsIncrement;

            const double v = value();
            incrementValue( d_data->stepsIncrement );

            if ( v != value() )
            {
                if ( isTracking() )
                    Q_EMIT valueChanged( value() );
                else
                    d_data->pendingValueChange = true;

                Q_EMIT sliderMoved( value() );
            }

            d_data->timerTick = false;
            d_data->repeatTimerId = startTimer( qMax( 250, 2 * updateInterval() ) );

            return;
        }
    }

    QwtAbstractSlider::mousePressEvent( event );
}
Exemplo n.º 11
0
 void updateStyle()
 {
     if (isInverted())
     {
         applyInvertedStyle();
     }
     else
     {
         applyNormalStyle();
     }
 }
Exemplo n.º 12
0
QPointF TableZone::mapFromGrid(QPoint gridPoint) const
{
    qreal x, y;
    x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0;
    for (int i = 0; i < gridPoint.x() / 3; ++i)
        x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX;
    
    if (isInverted())
        gridPoint.setY(2 - gridPoint.y());
    
    y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10;
/*    
    if (isInverted())
        y = height - CARD_HEIGHT - y;
*/    
    return QPointF(x, y);
}
Exemplo n.º 13
0
QPointF TableZone::mapFromGrid(QPoint gridPoint) const
{
    qreal x, y;
    x = MARGIN_X + (gridPoint.x() % 3) * CARD_WIDTH / 3.0;
    for (int i = 0; i < gridPoint.x() / 3; ++i)
        x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + PADDING_X;
    
    if (isInverted())
        gridPoint.setY(2 - gridPoint.y());
    
    y = BOX_LINE_WIDTH + gridPoint.y() * (CARD_HEIGHT + PADDING_Y + 20) + (gridPoint.x() % 3) * 10;
/*    
    if (isInverted())
        y = height - CARD_HEIGHT - y;
*/    
    return QPointF(x, y);
}
Exemplo n.º 14
0
QPoint TableZone::mapToGrid(const QPointF &mapPoint) const
{
    // Begin by calculating the y-coordinate of the grid space, which will be
    // used for the x-coordinate.

    // Offset point by the margin amount to reference point within grid area.
    int y = mapPoint.y() - MARGIN_TOP;

    // Below calculation effectively rounds to the nearest grid point.
    const int gridPointHeight = CARD_HEIGHT + PADDING_Y;
    int gridPointY = (y + gridPointHeight / 2) / gridPointHeight;

    gridPointY = clampValidTableRow(gridPointY);

    if (isInverted())
        gridPointY = TABLEROWS - 1 - gridPointY;

    // Calculating the x-coordinate of the grid space requires adding up the
    // widths of each card stack along the row.

    // Offset point by the margin amount to reference point within grid area.
    int x = mapPoint.x() - MARGIN_LEFT;

    // Maximum value is a card width from the right margin, referenced to the
    // grid area.
    const int xMax = width - MARGIN_LEFT - MARGIN_RIGHT - CARD_WIDTH;

    int xStack = 0;
    int xNextStack = 0;
    int nextStackCol = 0;
    while ((xNextStack <= x) && (xNextStack <= xMax)) { 
        xStack = xNextStack;
        const int key = getCardStackMapKey(nextStackCol, gridPointY);
        xNextStack += cardStackWidth.value(key, CARD_WIDTH) + PADDING_X;
        nextStackCol++;
    }
    int stackCol = qMax(nextStackCol - 1, 0);

    // Have the stack column, need to refine to the grid column.  Take the
    // difference between the point and the stack point and divide by stacked
    // card offsets.
    int xDiff = x - xStack;
    int gridPointX = stackCol * 3 + qMin(xDiff / STACKED_CARD_OFFSET_X, 2);

    return QPoint(gridPointX, gridPointY);
}
Exemplo n.º 15
0
void ScrollBar::moveSlider(double min, double max)
{
  if (mLogScale)
    {
      min = log(min);
      max = log(max);
    }

  int sliderTicks;
  sliderTicks = qRound((max - min) /
                       (d_maxBase - d_minBase) * d_baseTicks);

  // setRange initiates a valueChanged of the scrollbars
  // in some situations. So we block
  // and unblock the signals.

  blockSignals(true);

  setRange(sliderTicks / 2, d_baseTicks - sliderTicks / 2);
  int steps = sliderTicks / 200;

  if (steps <= 0)
    steps = 1;

#if QT_VERSION < 0x040000
  setSteps(steps, sliderTicks);
#else
  setSingleStep(steps);
  setPageStep(sliderTicks);
#endif

  int tick;
  tick = mapToTick(min + (max - min) / 2);

  if (isInverted())
    tick = d_baseTicks - tick;

#if QT_VERSION < 0x040000
  directSetValue(tick);
  rangeChange();
#else
  setSliderPosition(tick);
#endif
  blockSignals(false);
}
Exemplo n.º 16
0
/*!
  Handles key events

  QwtAbstractSlider handles the following keys:

  - Qt::Key_Left\n
    Add/Subtract singleSteps() in direction to lowerBound();
  - Qt::Key_Right\n
    Add/Subtract singleSteps() in direction to upperBound();
  - Qt::Key_Down\n
    Subtract singleSteps(), when invertedControls() is false
  - Qt::Key_Up\n
    Add singleSteps(), when invertedControls() is false
  - Qt::Key_PageDown\n
    Subtract pageSteps(), when invertedControls() is false
  - Qt::Key_PageUp\n
    Add pageSteps(), when invertedControls() is false
  - Qt::Key_Home\n
    Set the value to the minimum()
  - Qt::Key_End\n
    Set the value to the maximum()

  \param event Key event
  \sa isReadOnly()
*/
void QwtAbstractSlider::keyPressEvent( QKeyEvent *event )
{
    if ( isReadOnly() )
    {
        event->ignore();
        return;
    }

    if ( !d_data->isValid || d_data->isScrolling )
        return;

    int numSteps = 0;
    double value = d_data->value;

    switch ( event->key() )
    {
        case Qt::Key_Left:
        {
            numSteps = -static_cast<int>( d_data->singleSteps );
            if ( isInverted() )
                numSteps = -numSteps;

            break;
        }
        case Qt::Key_Right:
        {
            numSteps = d_data->singleSteps;
            if ( isInverted() )
                numSteps = -numSteps;

            break;
        }
        case Qt::Key_Down:
        {
            numSteps = -static_cast<int>( d_data->singleSteps );
            if ( d_data->invertedControls )
                numSteps = -numSteps;
            break;
        }
        case Qt::Key_Up:
        {
            numSteps = d_data->singleSteps;
            if ( d_data->invertedControls )
                numSteps = -numSteps;

            break;
        }
        case Qt::Key_PageUp:
        {
            numSteps = d_data->pageSteps;
            if ( d_data->invertedControls )
                numSteps = -numSteps;
            break;
        }
        case Qt::Key_PageDown:
        {
            numSteps = -static_cast<int>( d_data->pageSteps );
            if ( d_data->invertedControls )
                numSteps = -numSteps;
            break;
        }
        case Qt::Key_Home:
        {
            value = minimum();
            break;
        }
        case Qt::Key_End:
        {
            value = maximum();
            break;
        }
        default:;
        {
            event->ignore();
        }
    }

    if ( numSteps != 0 )
    {
        value = incrementedValue( d_data->value, numSteps );
    }

    if ( value != d_data->value )
    {
        d_data->value = value;
        sliderChange();

        Q_EMIT sliderMoved( d_data->value );
        Q_EMIT valueChanged( d_data->value );
    }
}
Exemplo n.º 17
0
String DateInterval::format(CStrRef format_spec) {
  StringBuffer s;
  for(int i = 0; i < format_spec.length(); i++) {
    const int MAXLEN = 22; // 64bit signed int string length, plus terminating \0
    char buf[MAXLEN];
    int l;
    char c = format_spec.charAt(i);

    if (c != '%') {
      s.append(c);
      continue;
    }
    i++;
    if (i == format_spec.length()) {
      // End of format, use literal % and finish
      s.append(c);
      break;
    }
    c = format_spec.charAt(i);

    switch(c) {
      case 'Y': l = snprintf(buf, MAXLEN, "%02lld", getYears()); break;
      case 'y': l = snprintf(buf, MAXLEN, "%lld",   getYears()); break;

      case 'M': l = snprintf(buf, MAXLEN, "%02lld", getMonths()); break;
      case 'm': l = snprintf(buf, MAXLEN, "%lld",   getMonths()); break;

      case 'D': l = snprintf(buf, MAXLEN, "%02lld", getDays()); break;
      case 'd': l = snprintf(buf, MAXLEN, "%lld",   getDays()); break;

      case 'H': l = snprintf(buf, MAXLEN, "%02lld", getHours()); break;
      case 'h': l = snprintf(buf, MAXLEN, "%lld",   getHours()); break;

      case 'I': l = snprintf(buf, MAXLEN, "%02lld", getMinutes()); break;
      case 'i': l = snprintf(buf, MAXLEN, "%lld",   getMinutes()); break;

      case 'S': l = snprintf(buf, MAXLEN, "%02lld", getSeconds()); break;
      case 's': l = snprintf(buf, MAXLEN, "%lld",   getSeconds()); break;

      case 'a':
        if (haveTotalDays()) {
          l = snprintf(buf, MAXLEN, "%lld", getTotalDays());
        } else {
          l = snprintf(buf, MAXLEN, "(unknown)");
        }
        break;

      case 'R':
        l = snprintf(buf, MAXLEN, "%c", isInverted() ? '-' : '+'); break;
      case 'r':
        l = snprintf(buf, MAXLEN, "%s", isInverted() ? "-" : "");  break;

      case '%':
      default:
        l = 0;
        s.append('%');
        break;
    }

    if (l > 0) {
      s.append(buf, l);
    }
  }
  return s.detach();
}
Exemplo n.º 18
0
std::string Component::getString() {
	// This will hold our return value
	std::string sentence;

	int componentId = _type.getId();

	if (isInverted()) {
		sentence += "do NOT ";
	}

	SpecifierPtr sp1 = getSpecifier(Specifier::FIRST_SPECIFIER);
	SpecifierPtr sp2 = getSpecifier(Specifier::SECOND_SPECIFIER);

	if (componentId == ComponentType::COMP_KILL().getId()) {
		// First add the verb
		sentence += "kill";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_KO().getId()) {
		// First add the verb
		sentence += "knockout";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_AI_FIND_ITEM().getId()) {
		// First add the verb
		sentence += "let AI find item:";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_AI_FIND_BODY().getId()) {
		sentence += "let AI find body:";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";

		sentence += " (amount: " + getArgument(0) + ")";
	}
	else if (componentId == ComponentType::COMP_ALERT().getId()) {
		sentence += "alert";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";

		// Add the alert level info
		sentence += " " + getArgument(0) + " times to a minimum alert level of " + getArgument(1);
	}
	else if (componentId == ComponentType::COMP_DESTROY().getId()) {
		sentence += "destroy";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_ITEM().getId()) {
		sentence += "acquire";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_PICKPOCKET().getId()) {
		sentence += "pickpocket";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_LOCATION().getId()) {
		sentence += "let the target";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";

		sentence += " be at location";
		sentence += (sp2) ? (" " + sp2->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_INFO_LOCATION().getId()) {
		sentence += "let the target";

		// Add the Specifier details, if any
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";

		sentence += " be at info_location";
		sentence += (sp2) ? (" " + sp2->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_CUSTOM_ASYNC().getId()) {
		sentence += "controlled by external script";
	}
	else if (componentId == ComponentType::COMP_CUSTOM_CLOCKED().getId()) {
		sentence += "call the script function ";
		sentence += getArgument(0);
	}
	else if (componentId == ComponentType::COMP_DISTANCE().getId()) {
		sentence += "let the entities " + getArgument(0);
		sentence += " and " + getArgument(1) + " get closer than ";
		sentence += getArgument(2) + " units";
	}
	else if (componentId == ComponentType::COMP_READABLE_OPENED().getId())
	{
		sentence += "open the readable ";
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_READABLE_CLOSED().getId())
	{
		sentence += "close the readable ";
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}
	else if (componentId == ComponentType::COMP_READABLE_PAGE_REACHED().getId())
	{
		sentence += "view page " + getArgument(0) + " of readable ";
		sentence += (sp1) ? (" " + sp1->getSentence(*this)) : "";
	}

	if (getClockInterval() > 0) {
		sentence += " (check interval: " + string::to_string(getClockInterval()) + " seconds)";
	}

	// Convert the first character of the sentence to upper case
	if (!sentence.empty()) {
		std::string c(sentence.begin(), sentence.begin()+1);
		sentence[0] = string::to_upper_copy(c)[0];

		// Append a full stop at the end of the sentence
		if (sentence[sentence.length() - 1] != '.') {
			sentence.append(".");
		}
	}

	// Replace all double-space characters with one single space
	string::replace_all(sentence, "  ", " ");

    return sentence;
}
Exemplo n.º 19
0
/**
 * Main program.
 */
int main()
{   
    uchar i, errorCode;
    uint8_t oldRunning = 0, running;

    /* Disable the watchdog */
    MCUSR = 0;
    wdt_disable();

    /* Read the serial number from flash */
    readSerial();
  
    /* Read the flash checksum from EEPROM */
    readFlashChecksum();

    /* Initialize USB and enable global interrupts */
    initUSB();

    /* First initialize the PWM so all LEDs are off. */
    pwmInit(prescalingIndex);
    pwmSet(CHANNEL0, 0, 0);
    pwmSet(CHANNEL1, 0, 0);
    pwmSet(CHANNEL2, 0, 0);
    pwmSet(CHANNEL3, 0, 0);
    pwmSet(CHANNEL4, 0, 0);
    pwmSet(CHANNEL5, 0, 0);

    /* Initialize the blinks memory from eeprom */
    eeprom_busy_wait();
    eeprom_read_block(memory, (uint8_t*) 1, BLINKS_MEM_SIZE);

    /* Make sure bits 7 is cleared and bit 6 is set */
    memory[0] &= 0x7f;
    memory[0] |= 0x40;

    /* Initialize blinks */
    blinksScript.data = BLINKS_SCRIPT(memory);
    blinksScript.size = BLINKS_SCRIPT_SIZE;
    errorCode = 1;

    /* Infinite program loop */
    i = 0;
    uint16_t shutdown = 0;
    while ((memory[0] & 0x40) || (--shutdown))
    {
        /* Re-init PWM if needed */
        if (prescalingIndex != getPrescalingIndex())
        {
            prescalingIndex = getPrescalingIndex();
            pwmInit(prescalingIndex);
        }
        
        /* Process USB events */
        usbPoll();

        /* Execute special commands */
        switch (command)
        {
            case CMD_SAVE:
                eeprom_busy_wait();
                eeprom_write_block(memory, (uint8_t*) 1, BLINKS_MEM_SIZE);
                break;
        }
        command = 0;

        /* Reset script when running flag has changed or an error occurred */
        running = BLINKS_FLAGS(memory) & BLINKS_FLAG_RUNNING;
        if (running != oldRunning || errorCode)
        {
            errorCode = blinksReset(blinksScript);
            oldRunning = running;
        }

        /* Execute next step in program when program is running an no error
           occurred. */
        if (running && !errorCode)
            errorCode = blinksStep(blinksScript);
        
        /* Apply channel values */
        if (!errorCode)
        {
            unsigned char outputs = blinksCountOutputs(blinksScript);
            unsigned char invert = isInverted();
            if (outputs > 0) pwmSet(CHANNEL0, blinksGetOutput(blinksScript, 0), invert);
            if (outputs > 1) pwmSet(CHANNEL1, blinksGetOutput(blinksScript, 1), invert);
            if (outputs > 2) pwmSet(CHANNEL2, blinksGetOutput(blinksScript, 2), invert);
            if (outputs > 3) pwmSet(CHANNEL3, blinksGetOutput(blinksScript, 3), invert);
            if (outputs > 4) pwmSet(CHANNEL4, blinksGetOutput(blinksScript, 4), invert);
            if (outputs > 5) pwmSet(CHANNEL5, blinksGetOutput(blinksScript, 5), invert);
        }

        /* When this loop has been executed for 100 times then
           mark the flash as OK */
        if ((flashChecksum != FLASH_CHECKSUM) && (i < 100))
        {
            i++;
            if (i == 100)
            {
                flashChecksum = FLASH_CHECKSUM;
                writeFlashChecksum();
            }
        }
    }

    enterBootloader();

    return 0;
}