Beispiel #1
0
int main(int argc, char** argv)
{
  fillTriangle();
  for (int row = rows-2; row >= 0; --row)
    for (int col = 0; col <= row; ++col)
      setMaxSum(col,row);
  std::cout << triangle[0][0] << std::endl;
}
Beispiel #2
0
main (void)
{
  initGraph ();

  /* 背景 */
  floodFill (320, 240, BLACK, LIGHTBLUE);
  waitButtonPress ();

  /* 頭 */
  fillEllipse (320, 250, 230, 160, WHITE);

  /* 耳 */
  fillTriangle (130, 40, 90, 250, 250, 92, WHITE);
  fillTriangle (530, 40, 530, 250, 390, 92, WHITE);
  waitButtonPress ();

  /* 目 */
  fillEllipse (200, 290, 15, 20, BLACK);
  fillEllipse (195, 282, 8, 6, WHITE);
  fillEllipse (440, 290, 15, 20, BLACK);
  fillEllipse (435, 282, 8, 6, WHITE);
  waitButtonPress ();

  /* 鼻 */
  fillEllipse (320, 330, 24, 15, YELLOW);
  fillEllipse (315, 322, 9, 6, WHITE);
  waitButtonPress ();

  /* ひげ */
  drawLine (125, 280, 40, 275, BLACK);
  drawLine (130, 300, 50, 305, BLACK);
  drawLine (140, 320, 40, 335, BLACK);

  drawLine (515, 280, 600, 275, BLACK);
  drawLine (510, 300, 590, 305, BLACK);
  drawLine (500, 320, 600, 335, BLACK);
  waitButtonPress ();

  /* リボン */
  fillTriangle (465, 160, 415, 70, 365, 160, RED);
  fillTriangle (465, 160, 515, 250, 565, 160, RED);
  fillCircle (465, 160, 20, RED);
  waitButtonPress ();

  closeGraph ();
}
Beispiel #3
0
main (void)
{
  initGraph ();

  /* 背景 */
  floodFill (320, 240, BLACK, LIGHTBLUE);
  waitButtonPress ();

  /* 頭 */
  fillEllipse (320, 240, 240, 180, WHITE);

  /* 耳 */
  fillEllipse (480, 140, 60, 80, WHITE);
  fillEllipse (160, 140, 60, 80, WHITE);
  waitButtonPress ();

  /* 目 */
  fillEllipse (200, 300, 15, 20, BLACK);
  fillEllipse (440, 300, 15, 20, BLACK);
  waitButtonPress ();

  /* 鼻 */
  fillEllipse (320, 340, 10, 14, YELLOW);
  setLineWidth (2);
  waitButtonPress ();

  /* ひげ */
  drawLine (125, 300, 40, 305, BLACK);
  drawLine (130, 320, 50, 330, BLACK);
  drawLine (140, 340, 40, 355, BLACK);

  drawLine (515, 300, 600, 305, BLACK);
  drawLine (510, 320, 590, 330, BLACK);
  drawLine (500, 340, 600, 355, BLACK);
  waitButtonPress ();

  /* リボン */
  fillTriangle (480, 160, 430, 70, 380, 160, RED);
  fillTriangle (480, 160, 530, 250, 580, 160, RED);
  fillCircle (480, 160, 20, RED);
  waitButtonPress ();

  closeGraph ();
}
Beispiel #4
0
void testfilltriangles()
{
    fillScreen(BLACK);
    uint16_t i;
    for (i=width()/2; i>10; i-=5)
    {
        fillTriangle(width()/2, height()/2-i,
            width()/2-i, height()/2+i,
            width()/2+i, height()/2+i, 
            Color565(0, i, i));
        drawTriangle(width()/2, height()/2-i,
            width()/2-i, height()/2+i,
            width()/2+i, height()/2+i, Color565(i, i, 0));    
    }
}
void SmartMatrix::fillTriangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3,
  const rgb24& outlineColor, const rgb24& fillColor) {
    fillTriangle(x1, y1, x2, y2, x3, y3, fillColor);
    drawTriangle(x1, y1, x2, y2, x3, y3, outlineColor);
}
Beispiel #6
0
void PUParticle3DQuadRender::render(Renderer* renderer, const Mat4 &transform, ParticleSystem3D* particleSystem)
{
    //batch and generate draw
    const ParticlePool &particlePool = particleSystem->getParticlePool();
    if (!_isVisible || particlePool.empty())
        return;

    if (_vertexBuffer == nullptr) {
        GLsizei stride = sizeof(VertexInfo);
        _vertexBuffer = VertexBuffer::create(stride, 4 * particleSystem->getParticleQuota());
        if (_vertexBuffer == nullptr)
        {
            CCLOG("PUParticle3DQuadRender::render create vertex buffer failed");
            return;
        }
        _vertexBuffer->retain();
    }

    if (_indexBuffer == nullptr) {
        _indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, 6 * particleSystem->getParticleQuota());
        if (_indexBuffer == nullptr)
        {
            CCLOG("PUParticle3DQuadRender::render create index buffer failed");
            return;
        }
        _indexBuffer->retain();
    }
    const ParticlePool::PoolList &activeParticleList = particlePool.getActiveDataList();
    if (_vertices.size() < activeParticleList.size() * 4)
    {
        _vertices.resize(activeParticleList.size() * 4);
        _indices.resize(activeParticleList.size() * 6);
    }

    auto camera = Camera::getVisitingCamera();
    auto cameraMat = camera->getNodeToWorldTransform();


    //for (auto iter : activeParticleList){
    //    iter->depthInView = -(viewMat.m[2] * iter->positionInWorld.x + viewMat.m[6] * iter->positionInWorld.y + viewMat.m[10] * iter->positionInWorld.z + viewMat.m[14]);
    //}

    //std::sort(activeParticleList.begin(), activeParticleList.end(), compareParticle3D);
    Vec3 right(cameraMat.m[0], cameraMat.m[1], cameraMat.m[2]);
    Vec3 up(cameraMat.m[4], cameraMat.m[5], cameraMat.m[6]);
    Vec3 backward(cameraMat.m[8], cameraMat.m[9], cameraMat.m[10]);

    Mat4 pRotMat;
    Vec3 position; //particle position
    int vertexindex = 0;
    int index = 0;
    int offsetX,offsetY;
    getOriginOffset(offsetX, offsetY);

    if (_type == PERPENDICULAR_COMMON) {
        up = _commonUp;
        up.normalize();
        Vec3::cross(up, _commonDir, &right);
        right.normalize();
        backward = _commonDir;
    } else if (_type == ORIENTED_COMMON) {
        up = _commonDir;
        up.normalize();
        Vec3::cross(up, backward, &right);
        right.normalize();
    }

    for (auto iter : activeParticleList)
    {
        auto particle = static_cast<PUParticle3D *>(iter);
        determineUVCoords(particle);
        if (_type == ORIENTED_SELF) {
            Vec3 direction = particle->direction;
            //transform.transformVector(particle->direction, &direction);
            up = direction;
            up.normalize();
            Vec3::cross(direction, backward, &right);
            right.normalize();
        } else if (_type == PERPENDICULAR_SELF) {
            Vec3 direction = particle->direction;
            //transform.transformVector(particle->direction, &direction);
            direction.normalize();
            //up = PUUtil::perpendicular(direction);
            //up.normalize();
            Vec3::cross(_commonUp, direction, &right);
            right.normalize();
            Vec3::cross(direction, right, &up);
            up.normalize();
            backward = direction;
        } else if (_type == ORIENTED_SHAPE) {
            up.set(particle->orientation.x, particle->orientation.y, particle->orientation.z);
            up.normalize();
            Vec3::cross(up, backward, &right);
            right.normalize();
        }
        Vec3 halfwidth = particle->width * 0.5f * right;
        Vec3 halfheight = particle->height * 0.5f * up;
        Vec3 offset = halfwidth * offsetX + halfheight * offsetY;
        //transform.transformPoint(particle->position, &position);
        position = particle->position;

        if (_rotateType == TEXTURE_COORDS) {
            float costheta = cosf(-particle->zRotation);
            float sintheta = sinf(-particle->zRotation);
            Vec2 texOffset = 0.5f * (particle->lb_uv + particle->rt_uv);
            Vec2 val;
            val.set((particle->lb_uv.x - texOffset.x), (particle->lb_uv.y - texOffset.y));
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex, (position + (-halfwidth - halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->rt_uv.x - texOffset.x, particle->lb_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 1, (position + (halfwidth - halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->lb_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 2, (position + (-halfwidth + halfheight + offset)), particle->color, val + texOffset);

            val.set(particle->rt_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
            val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
            fillVertex(vertexindex + 3, (position + (halfwidth + halfheight + offset)), particle->color, val + texOffset);
        } else {
            Mat4::createRotation(backward, -particle->zRotation, &pRotMat);
            fillVertex(vertexindex    , (position + pRotMat * (- halfwidth - halfheight + offset)), particle->color, particle->lb_uv);
            fillVertex(vertexindex + 1, (position + pRotMat * (halfwidth - halfheight + offset)), particle->color, Vec2(particle->rt_uv.x, particle->lb_uv.y));
            fillVertex(vertexindex + 2, (position + pRotMat * (-halfwidth + halfheight + offset)), particle->color, Vec2(particle->lb_uv.x, particle->rt_uv.y));
            fillVertex(vertexindex + 3, (position + pRotMat * (halfwidth + halfheight + offset)), particle->color, particle->rt_uv);
        }

        fillTriangle(index, vertexindex, vertexindex + 1, vertexindex + 3);
        fillTriangle(index + 3, vertexindex, vertexindex + 3, vertexindex + 2);

        //_posuvcolors[vertexindex].position = (position + (- halfwidth - halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex].color = particle->color;
        //_posuvcolors[vertexindex].uv.set(val.x + texOffset.x, val.y + texOffset.y);

        //val.set(particle->rt_uv.x - texOffset.x, particle->lb_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 1].position = (position + (halfwidth - halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 1].color = particle->color;
        //_posuvcolors[vertexindex + 1].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //val.set(particle->lb_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 2].position = (position + (- halfwidth + halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 2].color = particle->color;
        //_posuvcolors[vertexindex + 2].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //val.set(particle->rt_uv.x - texOffset.x, particle->rt_uv.y - texOffset.y);
        //val.set(val.x * costheta - val.y * sintheta, val.x * sintheta + val.y * costheta);
        //_posuvcolors[vertexindex + 3].position = (position + (halfwidth + halfheight + halfwidth * offsetX + halfheight * offsetY));
        //_posuvcolors[vertexindex + 3].color = particle->color;
        //_posuvcolors[vertexindex + 3].uv.set(val.x + texOffset.x, val.y + texOffset.y);
        //
        //
        //_indexData[index] = vertexindex;
        //_indexData[index + 1] = vertexindex + 1;
        //_indexData[index + 2] = vertexindex + 3;
        //_indexData[index + 3] = vertexindex;
        //_indexData[index + 4] = vertexindex + 3;
        //_indexData[index + 5] = vertexindex + 2;

        index += 6;
        vertexindex += 4;

    }

    _vertices.erase(_vertices.begin() + vertexindex, _vertices.end());
    _indices.erase(_indices.begin() + index, _indices.end());

    if (!_vertices.empty() && !_indices.empty()) {
        _vertexBuffer->updateVertices(&_vertices[0], vertexindex/* * sizeof(_posuvcolors[0])*/, 0);
        _indexBuffer->updateIndices(&_indices[0], index/* * sizeof(unsigned short)*/, 0);

        _stateBlock->setBlendFunc(particleSystem->getBlendFunc());

        GLuint texId = (_texture ? _texture->getName() : 0);
        _meshCommand->init(0,
                           texId,
                           _glProgramState,
                           _stateBlock,
                           _vertexBuffer->getVBO(),
                           _indexBuffer->getVBO(),
                           GL_TRIANGLES,
                           GL_UNSIGNED_SHORT,
                           index,
                           transform,
                           Node::FLAGS_RENDER_AS_3D);
        _meshCommand->setSkipBatching(true);
        _meshCommand->setTransparent(true);
        _glProgramState->setUniformVec4("u_color", Vec4(1,1,1,1));
        renderer->addCommand(_meshCommand);
    }
}
void ArduRCT_Graphics::_executeMacroCommand(ardurct_graphicsMacroCommand_t *mc, int16_t x, int16_t y, uint16_t scaleMul, uint16_t scaleDiv) {
    uint8_t group = mc->cmd & GRAPHICS_MACRO_CMD_GROUP_MASK;

    // presets
    if (group == GRAPHICS_MACRO_CMD_GROUP_PRESET) {
        if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_FOREGROUND) _mForegroundColor = mc->color;
        else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_BACKGROUND) _mBackgroundColor = mc->color;
        else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_THICKNESS) {
            _mThickness = mc->param[GRAPHICS_MACRO_PARAM_THICKNESS];
            _mIsThicknessScalable = mc->param[GRAPHICS_MACRO_PARAM_THICKNESS_IS_SCALABLE] != 0;
        } else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_ERASE) fillScreen(_mBackgroundColor);
        else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_FONT) {
            _mFontSize = mc->param[GRAPHICS_MACRO_PARAM_FONT_SIZE];
            _mIsFontBold = (mc->param[GRAPHICS_MACRO_PARAM_FONT_IS_BOLD] != 0);
            _mIsFontOverlay = (mc->param[GRAPHICS_MACRO_PARAM_FONT_IS_OVERLAY] != 0);
        } else if (mc->cmd == GRAPHICS_MACRO_CMD_PRESET_SCALE) {
            _mScaleMul = mc->param[GRAPHICS_MACRO_PARAM_SCALE_MUL];
            _mScaleDiv = 1;
            if ((mc->nbParams > 1) && (mc->param[GRAPHICS_MACRO_PARAM_SCALE_DIV] != 0)) _mScaleDiv = mc->param[GRAPHICS_MACRO_PARAM_SCALE_DIV];
        }
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.println("preset");    
#endif
        return;
    }
    
    int32_t sMul = _mScaleMul;
    sMul = sMul * (scaleMul == 0 ? 1 : scaleMul);
    int32_t sDiv = _mScaleDiv;
    sDiv = sDiv * (scaleDiv == 0 ? 1 : scaleDiv);
    int32_t sX = mc->param[GRAPHICS_MACRO_PARAM_X1];
    sX = sX * sMul/sDiv + x;
    int32_t sY = mc->param[GRAPHICS_MACRO_PARAM_Y1];        
    sY = sY * sMul/sDiv + y;        
    int32_t sThickness = _mThickness;
    if (_mIsThicknessScalable) sThickness = sThickness * sMul/sDiv;    
    
    // lines
    if (group == GRAPHICS_MACRO_CMD_GROUP_LINE) {
        int32_t sX2, sY2;
        if (mc->nbParams < 2) return;
        if (mc->cmd == GRAPHICS_MACRO_CMD_LINE) {
            if (mc->nbParams > 2) {
                sX2 = mc->param[GRAPHICS_MACRO_PARAM_X2];
                sX2 = x + sX2 * sMul/sDiv;
                sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y2];
                sY2 = y + sY2 * sMul/sDiv;
                // p2 becomes the end point
                _mX = mc->param[GRAPHICS_MACRO_PARAM_X2];
                _mY = mc->param[GRAPHICS_MACRO_PARAM_Y2];
            } else {
                sX2 = sX;
                sY2 = sY;
                sX = _mX;
                sX = x + sX * sMul/sDiv;
                sY = _mY;    
                sY = y + sY * sMul/sDiv;    
                // p1 becomes the end point
                _mX = mc->param[GRAPHICS_MACRO_PARAM_X1];
                _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1];
            }
        } else {
            // delta values
            if (mc->nbParams > 2) {
                // p2 = p1+delta
                sX2 = mc->param[GRAPHICS_MACRO_PARAM_X1] + mc->param[GRAPHICS_MACRO_PARAM_X2];
                sX2 = x + sX2 * sMul/sDiv;
                sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y1] + mc->param[GRAPHICS_MACRO_PARAM_Y2];
                sY2 = y + sY2 * sMul/sDiv;
                // p1+delta becomes the end point
                _mX = mc->param[GRAPHICS_MACRO_PARAM_X1] + mc->param[GRAPHICS_MACRO_PARAM_X2];
                _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1] + mc->param[GRAPHICS_MACRO_PARAM_Y2];
            } else {
                // p2 = old_point+delta
                sX2 = _mX + mc->param[GRAPHICS_MACRO_PARAM_X1];
                sX2 = x + sX2 * sMul/sDiv;
                sY2 = _mY + mc->param[GRAPHICS_MACRO_PARAM_Y1];
                sY2 = y + sY2 * sMul/sDiv;
                sX = _mX;
                sX = x + sX * sMul/sDiv;
                sY = _mY;    
                sY = y + sY * sMul/sDiv;    
                // old_point+delta  becomes the end point
                _mX += mc->param[GRAPHICS_MACRO_PARAM_X1];
                _mY += mc->param[GRAPHICS_MACRO_PARAM_Y1];
            }
            
        }
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("line "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); 
            Serial.print(sX2); Serial.print(" "); Serial.println(sY2);
#endif
        drawLine(sX, sY, sX2, sY2, _mForegroundColor, sThickness, false);
        return;
    }    
    
    // arcs
    if (group == GRAPHICS_MACRO_CMD_GROUP_ARC) {
        if (mc->nbParams < 1) return;
        boolean reversed = (mc->cmd == GRAPHICS_MACRO_CMD_ARC_REVERSED) || (mc->cmd == GRAPHICS_MACRO_CMD_ARC_FILLED_REVERSED);
        int32_t sRadius = 0;
        if (mc->nbParams == 1) {
            sRadius = mc->param[GRAPHICS_MACRO_PARAM_ARC_1];
            sRadius = sRadius * sMul/sDiv;
            int32_t sArcStartX = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], !reversed, true);
            int32_t sArcStartY = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], !reversed, false);
            int32_t sArcEndX = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, true);
            int32_t sArcEndY = _getArcEnd(sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, false);
            sX = _mX;
            sX = x + sX * sMul/sDiv - sArcStartX;
            sY = _mY;
            sY = y + sY * sMul/sDiv - sArcStartY;
            _mX += sArcEndX - sArcStartX;
            _mY += sArcEndY - sArcStartY;

        } else if (mc->nbParams == 3) {
            sRadius = mc->param[GRAPHICS_MACRO_PARAM_ARC_3];
            sRadius = sRadius * sMul/sDiv;
            _mX = mc->param[GRAPHICS_MACRO_PARAM_X1] + _getArcEnd(mc->param[GRAPHICS_MACRO_PARAM_ARC_3], mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, true);
            _mY = mc->param[GRAPHICS_MACRO_PARAM_Y1] + _getArcEnd(mc->param[GRAPHICS_MACRO_PARAM_ARC_3], mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], reversed, false);
        } else return;
        if ((mc->cmd == GRAPHICS_MACRO_CMD_ARC_REVERSED) || (mc->cmd == GRAPHICS_MACRO_CMD_ARC)) 
            drawArc(sX, sY, sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], _mForegroundColor, sThickness, false);
        else fillArc(sX, sY, sRadius, mc->param[GRAPHICS_MACRO_PARAM_ARC_OCTANT], _mForegroundColor, false);            
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("arc "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.println(sRadius);
#endif
        return;
    }
    
    // circles
    if (group == GRAPHICS_MACRO_CMD_GROUP_CIRCLE) {
        // we need at least 3 parameters
        if (mc->nbParams < 3) return;
        int32_t sRadius = mc->param[GRAPHICS_MACRO_PARAM_RADIUS];
        sRadius = sRadius * sMul/sDiv;
        if (mc->cmd == GRAPHICS_MACRO_CMD_CIRCLE) drawCircle(sX, sY, sRadius, _mForegroundColor, sThickness, false);
        else fillCircle(sX, sY, sRadius, _mForegroundColor, false);
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("circle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.println(sRadius);
#endif
        return;
    }
    
    // rectangles
    if (group == GRAPHICS_MACRO_CMD_GROUP_RECTANGLE) {
        // we need at least 4 parameters
        if (mc->nbParams < 4) return;
        int32_t sWidth = mc->param[GRAPHICS_MACRO_PARAM_WIDTH];
        sWidth = sWidth * sMul/sDiv;
        int32_t sHeight = mc->param[GRAPHICS_MACRO_PARAM_HEIGHT];
        sHeight = sHeight * sMul/sDiv;
        if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE) drawRectangle(sX, sY, sWidth, sHeight, _mForegroundColor, sThickness, false);
        else if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_FILLED) fillRectangle(sX, sY, sWidth, sHeight, _mForegroundColor, false);
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("rectangle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.print(sWidth); Serial.print(" "); Serial.println(sHeight);
#endif
        // we need at least 1 more parameter to display the rounded rectangle
        if (mc->nbParams < 5) return;
        int32_t sRadius = mc->param[GRAPHICS_MACRO_PARAM_ROUNDING];
        sRadius = sRadius * sMul/sDiv;
        if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_ROUNDED) drawRoundedRectangle(sX, sY, sWidth, sHeight, sRadius, _mForegroundColor, sThickness, false);
        else if (mc->cmd == GRAPHICS_MACRO_CMD_RECTANGLE_ROUNDED_FILLED) fillRoundedRectangle(sX, sY, sWidth, sHeight, sRadius, _mForegroundColor, false);
        return;
    }
    
    // triangles
    if (group == GRAPHICS_MACRO_CMD_GROUP_TRIANGLE) {
        // we need at least 6 parameters
        if (mc->nbParams < 6) return;
        int32_t sX2 = mc->param[GRAPHICS_MACRO_PARAM_X2];
        sX2 = x + sX2 * sMul/sDiv;
        int32_t sY2 = mc->param[GRAPHICS_MACRO_PARAM_Y2];
        sY2 = y + sY2 * sMul/sDiv;
        int32_t sX3 = mc->param[GRAPHICS_MACRO_PARAM_X3];
        sX3 = x + sX3 * sMul/sDiv;
        int32_t sY3 = mc->param[GRAPHICS_MACRO_PARAM_Y3];
        sY3 = y + sY3 * sMul/sDiv;
        if (mc->cmd == GRAPHICS_MACRO_CMD_TRIANGLE) drawTriangle(sX, sY, sX2, sY2, sX3, sY3, _mForegroundColor, sThickness, false);
        else if (mc->cmd == GRAPHICS_MACRO_CMD_TRIANGLE_FILLED) fillTriangle(sX, sY, sX2, sY2, sX3, sY3, _mForegroundColor, false);
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("triangle "); Serial.print(sX); Serial.print(" "); Serial.print(sY); Serial.print(" "); Serial.print(sX2); Serial.print(" "); Serial.print(sY2); 
            Serial.print(" "); Serial.print(sX3); Serial.print(" "); Serial.println(sY3);
#endif
        return;
    }
        
    // strings
    if (mc->cmd == GRAPHICS_MACRO_CMD_STRING) {
        if (mc->nbParams < 2) return;
        int bc = _backgroundColor;
        if (!_mIsFontOverlay) setBackgroundColor(_mBackgroundColor);
        drawString((char *)mc->text, sX, sY, _mForegroundColor, _mFontSize, _mIsFontBold, _mIsFontOverlay, false);
        if (!_mIsFontOverlay) setBackgroundColor(bc);
#ifdef GRAPHICS_MACRO_DEBUG
        Serial.print("text "); Serial.println((char *)mc->text);
#endif

        return;
    }
    
    // executes
    if (group == GRAPHICS_MACRO_CMD_GROUP_EXECUTE) {
        if (mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER] >= GRAPHICS_MACRO_MAX_NUMBER) return;
        // read the length in the EEPROM allocation table
        int length = eeprom_read_uint8_t(mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER]);
        if (length == 0xFF) return;
        // read the EEPROM pointers table to get the start
        int start = GRAPHICS_MACRO_MAX_NUMBER + mc->param[GRAPHICS_MACRO_PARAM_MACRO_NUMBER] * GRAPHICS_MACRO_MAX_SIZE;
        // get the compressed macro
        uint8_t buffer[GRAPHICS_MACRO_MAX_SIZE];
        uint8_t i=0;
        while (i < length) {
            buffer[i] = eeprom_read_uint8_t(start+i);
            i++;
        }
        buffer[i] = 0;
        ardurct_graphicsMacroCommand_t emc;
        // uncompress the macro commands and execute them
        if (mc->cmd == GRAPHICS_MACRO_CMD_EXECUTE_WITH_RESET) _initializeMacros();
        i = 0;
        while (i < length) {
            int8_t len = _uncompressMacroCommand(buffer, i, &emc);
            if (len == GRAPHICS_MACRO_FORMAT_ERROR) return;
            _executeMacroCommand(&emc, x, y, scaleMul, scaleDiv);
            i = len;
        }
    }
}