diff --git a/.gitignore b/.gitignore
index 9956744767c3cea2ff6cb7181a0dce4eedc39539..553ebd940d06590ce62057ea7be8631770e14671 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
 # This file is used to ignore files which are generated
 # ----------------------------------------------------------------------------
-build-MiniMatrixRPi-Desktop_Qt_5_12_2_GCC_64bit-Debug
+build-MiniMatrixRPi-Desktop_Qt_5_11_3_GCC_64bit-Debug
 *~
 *.autosave
 *.a
diff --git a/MiniMatrixRPi/FileBrowser.qml b/MiniMatrixRPi/FileBrowser.qml
new file mode 100644
index 0000000000000000000000000000000000000000..470209eb2b399b67ec62bf16cac8c83c88366c0c
--- /dev/null
+++ b/MiniMatrixRPi/FileBrowser.qml
@@ -0,0 +1,395 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+import QtQuick 2.11
+import Qt.labs.folderlistmodel 2.1
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+
+Rectangle {
+    id: fileBrowser
+    color: "transparent"
+    z: 4
+
+    property string folder
+    property bool shown: loader.sourceComponent
+
+    signal fileSelected(string file)
+
+    function selectFile(file) {
+        if (file !== "") {
+            folder = loader.item.folders.folder
+            fileBrowser.fileSelected(file)
+        }
+        loader.sourceComponent = undefined
+    }
+
+    Loader {
+        id: loader
+    }
+
+    function show() {
+        loader.sourceComponent = fileBrowserComponent
+        loader.item.parent = fileBrowser
+        loader.item.anchors.fill = fileBrowser
+        loader.item.folder = fileBrowser.folder
+    }
+
+    Component {
+        id: fileBrowserComponent
+
+        Rectangle {
+            id: root
+            color: "black"
+            property bool showFocusHighlight: false
+            property variant folders: folders1
+            property variant view: view1
+            property alias folder: folders1.folder
+            property color textColor: "white"
+
+            FolderListModel {
+                id: folders1
+                folder: folder
+            }
+
+            FolderListModel {
+                id: folders2
+                folder: folder
+            }
+
+            SystemPalette {
+                id: palette
+            }
+
+            Component {
+                id: folderDelegate
+
+                Rectangle {
+                    id: wrapper
+                    function launch() {
+                        var path = "file://";
+                        if (filePath.length > 2 && filePath[1] === ':') // Windows drive logic, see QUrl::fromLocalFile()
+                            path += '/';
+                        path += filePath;
+                        if (folders.isFolder(index))
+                            down(path);
+                        else
+                            fileBrowser.selectFile(path)
+                    }
+                    width: root.width
+                    height: itemHeight
+                    color: "transparent"
+
+                    Rectangle {
+                        id: highlight; visible: false
+                        anchors.fill: parent
+                        color: palette.highlight
+                        gradient: Gradient {
+                            GradientStop { id: t1; position: 0.0; color: palette.highlight }
+                            GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+                        }
+                    }
+
+                    Item {
+                        width: itemHeight; height: itemHeight
+                        Image {
+                            source: "qrc:/images/icon_Folder.png"
+                            fillMode: Image.PreserveAspectFit
+                            anchors.fill: parent
+                            anchors.margins: scaledMargin
+                            visible: folders.isFolder(index)
+                        }
+                    }
+
+                    Text {
+                        id: nameText
+                        anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+                        text: fileName
+                        anchors.leftMargin: itemHeight + scaledMargin
+                        font.pixelSize: fontSize
+                        color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor
+                        elide: Text.ElideRight
+                    }
+
+                    MouseArea {
+                        id: mouseRegion
+                        anchors.fill: parent
+                        onPressed: {
+                            root.showFocusHighlight = false;
+                            wrapper.ListView.view.currentIndex = index;
+                        }
+                        onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+                    }
+
+                    states: [
+                        State {
+                            name: "pressed"
+                            when: mouseRegion.pressed
+                            PropertyChanges { target: highlight; visible: true }
+                            PropertyChanges { target: nameText; color: palette.highlightedText }
+                        }
+                    ]
+                }
+            }
+
+            ListView {
+                id: view1
+                anchors.top: titleBar.bottom
+                anchors.bottom: cancelButton.top
+                x: 0
+                width: parent.width
+                model: folders1
+                delegate: folderDelegate
+                highlight: Rectangle {
+                    color: palette.highlight
+                    visible: root.showFocusHighlight && view1.count != 0
+                    gradient: Gradient {
+                        GradientStop { id: t11; position: 0.0; color: palette.highlight }
+                        GradientStop { id: t22; position: 1.0; color: Qt.lighter(palette.highlight) }
+                    }
+                    width: view1.currentItem == null ? 0 : view1.currentItem.width
+                }
+                highlightMoveVelocity: 1000
+                pressDelay: 100
+                focus: true
+                state: "current"
+                states: [
+                    State {
+                        name: "current"
+                        PropertyChanges { target: view1; x: 0 }
+                    },
+                    State {
+                        name: "exitLeft"
+                        PropertyChanges { target: view1; x: -root.width }
+                    },
+                    State {
+                        name: "exitRight"
+                        PropertyChanges { target: view1; x: root.width }
+                    }
+                ]
+                transitions: [
+                    Transition {
+                        to: "current"
+                        SequentialAnimation {
+                            NumberAnimation { properties: "x"; duration: 250 }
+                        }
+                    },
+                    Transition {
+                        NumberAnimation { properties: "x"; duration: 250 }
+                        NumberAnimation { properties: "x"; duration: 250 }
+                    }
+                ]
+                Keys.onPressed: root.keyPressed(event.key)
+            }
+
+            ListView {
+                id: view2
+                anchors.top: titleBar.bottom
+                anchors.bottom: parent.bottom
+                x: parent.width
+                width: parent.width
+                model: folders2
+                delegate: folderDelegate
+                highlight: Rectangle {
+                    color: palette.highlight
+                    visible: root.showFocusHighlight && view2.count != 0
+                    gradient: Gradient {
+                        GradientStop { id: t11; position: 0.0; color: palette.highlight }
+                        GradientStop { id: t22; position: 1.0; color: Qt.lighter(palette.highlight) }
+                    }
+                    width: view1.currentItem == null ? 0 : view1.currentItem.width
+                }
+                highlightMoveVelocity: 1000
+                pressDelay: 100
+                states: [
+                    State {
+                        name: "current"
+                        PropertyChanges { target: view2; x: 0 }
+                    },
+                    State {
+                        name: "exitLeft"
+                        PropertyChanges { target: view2; x: -root.width }
+                    },
+                    State {
+                        name: "exitRight"
+                        PropertyChanges { target: view2; x: root.width }
+                    }
+                ]
+                transitions: [
+                    Transition {
+                        to: "current"
+                        SequentialAnimation {
+                            NumberAnimation { properties: "x"; duration: 250 }
+                        }
+                    },
+                    Transition {
+                        NumberAnimation { properties: "x"; duration: 250 }
+                    }
+                ]
+                Keys.onPressed: root.keyPressed(event.key)
+            }
+
+            Button {
+                id: cancelButton
+                width: itemWidth
+                height: itemHeight
+                //background: "#353535"
+                anchors { bottom: parent.bottom; right: parent.right; margins: 5 * scaledMargin }
+                text: "Cancel"
+                //anchors.horizontalCenter: Text.horizontalCenter
+                onClicked: fileBrowser.selectFile("")
+            }
+
+            Keys.onPressed: {
+                root.keyPressed(event.key);
+                if (event.key === Qt.Key_Return || event.key === Qt.Key_Select || event.key === Qt.Key_Right) {
+                    view.currentItem.launch();
+                    event.accepted = true;
+                } else if (event.key === Qt.Key_Left) {
+                    up();
+                }
+            }
+
+            // titlebar
+            Rectangle {
+                color: "black"
+                width: parent.width;
+                height: itemHeight
+                id: titleBar
+
+                Rectangle {
+                    id: upButton
+                    width: titleBar.height
+                    height: titleBar.height
+                    color: "transparent"
+                    anchors.left: parent.left
+                    anchors.verticalCenter: parent.verticalCenter
+                    anchors.margins: scaledMargin
+
+                    Image { anchors.fill: parent; anchors.margins: scaledMargin; source: "qrc:/images/icon_BackArrow.png" }
+                    MouseArea { id: upRegion; anchors.fill: parent; onClicked: up() }
+                    states: [
+                        State {
+                            name: "pressed"
+                            when: upRegion.pressed
+                            PropertyChanges { target: upButton; color: palette.highlight }
+                        }
+                    ]
+                }
+
+                Text {
+                    anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+                    anchors.leftMargin: 10; anchors.rightMargin: 4
+                    text: folders.folder
+                    color: "white"
+                    elide: Text.ElideLeft; horizontalAlignment: Text.AlignLeft; verticalAlignment: Text.AlignVCenter
+                    font.pixelSize: fontSize
+                }
+            }
+
+            Rectangle {
+                color: "#353535"
+                width: parent.width
+                height: 1
+                anchors.top: titleBar.bottom
+            }
+
+            function down(path) {
+                if (folders == folders1) {
+                    view = view2
+                    folders = folders2;
+                    view1.state = "exitLeft";
+                } else {
+                    view = view1
+                    folders = folders1;
+                    view2.state = "exitLeft";
+                }
+                view.x = root.width;
+                view.state = "current";
+                view.focus = true;
+                folders.folder = path;
+            }
+
+            function up() {
+                var path = folders.parentFolder;
+                if (path.toString().length === 0 || path.toString() === 'file:')
+                    return;
+                if (folders == folders1) {
+                    view = view2
+                    folders = folders2;
+                    view1.state = "exitRight";
+                } else {
+                    view = view1
+                    folders = folders1;
+                    view2.state = "exitRight";
+                }
+                view.x = -root.width;
+                view.state = "current";
+                view.focus = true;
+                folders.folder = path;
+            }
+
+            function keyPressed(key) {
+                switch (key) {
+                    case Qt.Key_Up:
+                    case Qt.Key_Down:
+                    case Qt.Key_Left:
+                    case Qt.Key_Right:
+                        root.showFocusHighlight = true;
+                    break;
+                    default:
+                        // do nothing
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/MiniMatrixRPi/browser.cpp b/MiniMatrixRPi/browser.cpp
index ee895096438b77e8944bc3f525ef68dea25027da..c67207c5a55c668d828eb4df7d0086fed301e4cc 100644
--- a/MiniMatrixRPi/browser.cpp
+++ b/MiniMatrixRPi/browser.cpp
@@ -1,10 +1,10 @@
 #include "browser.h"
 
-Browser::Browser(QString path)
+Browser::Browser(QQuickItem* parent) : QQuickItem(parent)
 {
-    QDir newDirectory(path);
-    currentDirectory = newDirectory;
-    ListDir();
+//    QDir newDirectory(path);
+//    currentDirectory = newDirectory;
+//    ListDir();
 }
 
 void Browser::ChDir(QString relPath)
diff --git a/MiniMatrixRPi/browser.h b/MiniMatrixRPi/browser.h
index 0cdf7d200d2096eaf0d475a741f9ea3b9502f570..9dd1cb26f66e08d8ddbfe9d38f5b45b2126193ae 100644
--- a/MiniMatrixRPi/browser.h
+++ b/MiniMatrixRPi/browser.h
@@ -3,14 +3,16 @@
 #include <QDir>
 #include <QString>
 #include <QStringList>
+#include <QQuickItem>
 
-class Browser
+class Browser : public QQuickItem
 {
 private:
     QDir currentDirectory;
     QStringList subdirs;
 public:
-    Browser(QString path);
+//    Browser(QString path);
+    Browser(QQuickItem* parent = nullptr);
     void ChDir(QString relPath);
     void ListDir();
 };
diff --git a/MiniMatrixRPi/main.cpp b/MiniMatrixRPi/main.cpp
index 85cd24d0deab0ad59c5a7dd408a8a37bd06843a0..c25191c393d5bb78b2defb220f9d357568a390ef 100644
--- a/MiniMatrixRPi/main.cpp
+++ b/MiniMatrixRPi/main.cpp
@@ -19,7 +19,8 @@ int main(int argc, char *argv[])
     Animation anim;
     anim.openFile("../asdasd.qp4");
 
-    Browser browser("../");
+
+    //Browser browser("../");
     return app.exec();
 }
 
diff --git a/MiniMatrixRPi/main.qml b/MiniMatrixRPi/main.qml
index 94d56e24d3ecb77b2aeb37dad0d08a08597d879c..cf9aa7578474785c4847f3109adb1ca94762625e 100644
--- a/MiniMatrixRPi/main.qml
+++ b/MiniMatrixRPi/main.qml
@@ -1,19 +1,24 @@
-import QtQuick 2.9
+import QtQuick 2.11
 import QtQuick.Window 2.2
-import QtQuick.Controls 2.5
+import QtQuick.Controls 2.4
 
 Window {
     visible: true
     width: Screen.desktopAvailableWidth
     height: Screen.desktopAvailableHeight
-    flags: Qt.FramelessWindowHint
+    //flags: Qt.FramelessWindowHint
     color: "#666666"
     title: qsTr("Mini Mátrix")
+
     Flickable {
         width: Screen.desktopAvailableWidth * 0.75
         height: Screen.desktopAvailableHeight * 0.8
         contentWidth: Screen.desktopAvailableWidth * 0.75
         anchors {horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: parent.height*0.1}
+        FileBrowser{
+
+        }
 
     }
+
 }
diff --git a/MiniMatrixRPi/qml.qrc b/MiniMatrixRPi/qml.qrc
index 5f6483ac33f1881cc59e080e69bb033ebe2a7829..26376340cd2bc07fdb97b1bc5abe0b244b52c217 100644
--- a/MiniMatrixRPi/qml.qrc
+++ b/MiniMatrixRPi/qml.qrc
@@ -1,5 +1,6 @@
 <RCC>
     <qresource prefix="/">
         <file>main.qml</file>
+        <file>FileBrowser.qml</file>
     </qresource>
 </RCC>
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/MiniMatrixRPi.pro b/MiniMatrixRPi_widgets/MiniMatrixRPi/MiniMatrixRPi.pro
new file mode 100644
index 0000000000000000000000000000000000000000..d494dc0d5d8cdc0ad9715fb0cbad8b96ce709cff
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/MiniMatrixRPi.pro
@@ -0,0 +1,46 @@
+QT       += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+    animation.cpp \
+    animhandler.cpp \
+    filebrowser.cpp \
+    main.cpp \
+    mainwindow.cpp \
+    mxemu.cpp \
+    mxframe.cpp \
+    spiframe.cpp \
+    spisender.cpp
+
+HEADERS += \
+    animation.h \
+    animhandler.h \
+    color.hpp \
+    filebrowser.h \
+    mainwindow.h \
+    mxemu.h \
+    mxframe.h \
+    spiframe.h \
+    spisender.h
+
+FORMS += \
+    mainwindow.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..996e5eeb858b331b9e50402c7e0f81a9b0be01b1
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.cpp
@@ -0,0 +1,108 @@
+#include "animation.h"
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+Animation::Animation()
+{
+}
+
+void Animation::openFile(const std::string& filepath)
+{
+    std::ifstream file;
+    file.open(filepath); //open the input file
+    if (!file.fail())
+    {
+        frames.clear();
+        frameId = 0;
+
+        std::stringstream strStream;
+        strStream << file.rdbuf(); //read the file
+        std::string filestr = strStream.str(); //str holds the content of the file
+        file.close();
+
+        size_t start = 0;
+        while (1) {
+            size_t begin = filestr.find("frame(", start);
+            size_t end = filestr.find(")", begin) + 1;
+            if (begin == string::npos || end == string::npos)
+                break;
+            start = end;
+            frames.push_back(MxFrame(filestr.substr(begin, end - begin)));
+        }
+    }
+}
+
+bool Animation::eof() const
+{
+    return frameId >= frames.size();
+}
+
+MxFrame Animation::nextFrame()
+{
+    if (!eof()) {
+        return frames[frameId++];
+    } else {
+        return MxFrame();
+    }
+}
+
+MxFrame Animation::getCurrentFrame() const
+{
+    if (!eof()) {
+        return frames[frameId];
+    } else {
+        return MxFrame();
+    }
+}
+
+uint32_t Animation::getCurrentTime() const
+{
+    uint32_t t = 0;
+    if (frameId == 0) return 0;
+    for (uint32_t i = 0; i < frameId - 1; i++) {
+        t += frames[i].length;
+    }
+    return t;
+}
+
+uint32_t Animation::getTimeLength() const
+{
+    uint32_t t = 0;
+    for (uint32_t i = 0; i < frames.size(); i++) {
+        t += frames[i].length;
+    }
+    return t;
+}
+
+uint32_t Animation::getFrameNum() const
+{
+    return static_cast<uint32_t>(frames.size());
+}
+
+uint32_t Animation::getFrameId() const
+{
+    return frameId;
+}
+
+uint32_t Animation::setFrameId(uint32_t id)
+{
+    frameId = id < frames.size() ? id : frames.size();
+    return frameId;
+}
+
+//returns: (time_param) - (actual beginning time of set frame)
+uint32_t Animation::seek(uint32_t time_ms)
+{
+    uint32_t t = 0;
+    uint32_t i = 0;
+    for (i = 0; i < frames.size(); i++) {
+        if (t + frames[i].length > time_ms)
+            break;
+        t += frames[i].length;
+    }
+    frameId = i;
+    return time_ms - t;
+}
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc4992ced40c6e11ed810b76788d78dbce71e150
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/animation.h
@@ -0,0 +1,31 @@
+#ifndef ANIMATION_H
+#define ANIMATION_H
+
+//#include <QFile>
+//#include <QString>
+#include <vector>
+#include <string>
+#include "mxframe.h"
+#include "spiframe.h"
+#include <tuple>
+
+class Animation
+{
+private:
+    std::vector<MxFrame> frames;
+    uint32_t frameId = 0;
+public:
+    Animation();
+    void openFile(const std::string& filepath);
+    MxFrame nextFrame();
+    MxFrame getCurrentFrame() const;
+    uint32_t getCurrentTime() const;
+    bool eof() const;
+    uint32_t getTimeLength() const;
+    uint32_t getFrameNum() const;
+    uint32_t getFrameId() const;
+    uint32_t setFrameId(uint32_t id);
+    uint32_t seek(uint32_t time_ms);
+};
+
+#endif // ANIMATION_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55a9136c3044e0c585f0cfe9eb13031916c2a1db
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.cpp
@@ -0,0 +1,96 @@
+#include "animhandler.h"
+#include "QString"
+#include "QThread"
+
+void AnimHandler::start_slot()
+{
+    nextmode = Mode::RUN;
+}
+void AnimHandler::pause()
+{
+    nextmode = Mode::PAUSE;
+}
+void AnimHandler::stop()
+{
+    nextmode = Mode::STOP;
+}
+void AnimHandler::enableExit()
+{
+    exitThread = true;
+}
+
+void AnimHandler::run() {
+    qDebug() << "STARTED BITCHES";
+    int cnt = 0;
+    int curframelen = 0;
+    while (!exitThread) {
+        if (nextmode != mode)
+        {
+            mode = nextmode;
+            switch (mode) {
+            case STOP:
+                cnt = 0;
+                anim.seek(0);
+                emit progressUpdate(0);
+                qDebug() << "Stopped";
+                emit onStopped(); break;
+            case RUN:
+                qDebug() << "Run";
+                emit onStarted(); break;
+            case PAUSE:
+                qDebug() << "Paused";
+                emit onPaused(); break;
+            }
+        }
+        switch (mode) {
+        case STOP: break;
+        case PAUSE: break;
+        case RUN:
+            if (cnt > 0) cnt--;
+            emit progressUpdate(anim.getCurrentTime() + (curframelen - cnt));
+            if (cnt <= 0)
+            {
+                if (anim.eof())
+                {
+                    mode = STOP;
+                    nextmode = mode;
+                    anim.seek(0);
+                    emit onStopped();
+                    break;
+                }
+                else if (spisender.canSend())
+                {
+                    MxFrame nextframe = anim.nextFrame();
+                    cnt = nextframe.length;
+                    curframelen = nextframe.length;
+                    spisender.sendFrame(SpiFrame(nextframe));
+                    emit updateFrame(nextframe);
+                }
+            }
+            break;
+        }
+        usleep(1000);
+    }
+    qDebug() << "KÖRTE";
+    emit resultReady("ALMA");
+}
+
+AnimHandler::AnimHandler() : QThread(), spisender(26)
+{
+}
+
+void AnimHandler::openFile(const std::string filepath) {
+    nextmode = Mode::STOP;
+    anim.openFile(filepath);
+    emit onFileOpened(filepath);
+    MxFrame empty;
+    emit updateFrame(empty);
+}
+
+uint32_t AnimHandler::getAnimTimeLen() const
+{
+    return anim.getTimeLength();
+}
+
+
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..42d1dd8b312e3e154e77adf12b8013002d78164f
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/animhandler.h
@@ -0,0 +1,67 @@
+#ifndef ANIMHANDLER_H
+#define ANIMHANDLER_H
+
+#include <QThread>
+#include <QDebug>
+#include <QFile>
+#include <cstring>
+#include "animation.h"
+#include "spisender.h"
+
+enum Mode {STOP=0, RUN, PAUSE};
+class AnimHandler: public QThread
+{
+    Q_OBJECT
+    void run() override;
+private:
+    uint32_t progress = 0;
+    std::atomic<bool> exitThread {false};
+    enum Mode mode = STOP;
+    std::atomic<enum Mode> nextmode {STOP};
+    std::atomic<bool> changemode {false};
+    Animation anim;
+    SpiSender spisender;
+
+public:
+    AnimHandler();
+    void openFile(const std::string filepath);
+    uint32_t getAnimTimeLen() const;
+
+public slots:
+    void start_slot();
+    void pause();
+    void stop();
+    void enableExit();
+
+signals:
+    void onPaused();
+    void onStarted();
+    void onStopped();
+    void onFileOpened(const std::string filepath);
+    void updateFrame(MxFrame& frame);
+    void progressUpdate(uint32_t progress);
+    void resultReady(const QString &result);
+};
+
+class Alma: public QObject
+{
+    Q_OBJECT
+AnimHandler* animhandler;
+public:
+    Alma() {
+        animhandler = new AnimHandler;
+        connect(this, &Alma::exit, animhandler, &AnimHandler::enableExit);
+        animhandler->start();
+        emit exit();
+    }
+
+    ~Alma() {
+    }
+
+signals:
+    void exit();
+};
+
+
+
+#endif // ANIMHANDLER_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/color.hpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/color.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f41e3433a5e0d6e60879ee306dbc23e013fe0e1
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/color.hpp
@@ -0,0 +1,15 @@
+#include "stdint.h"
+
+struct Color
+{
+    constexpr Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255)
+        : r(r), g(g), b(b), a(a)
+    {}
+    Color() : r(0), g(0), b(0)
+    {}
+
+     uint8_t r;
+     uint8_t g;
+     uint8_t b;
+     uint8_t a;
+};
\ No newline at end of file
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f8d8d5def9fde098010213b47db54859f10792a4
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.cpp
@@ -0,0 +1,164 @@
+#include <filebrowser.h>
+#include <sstream>
+#include <QDir>
+#include <QDebug>
+#include <QDialog>
+#include <QScrollBar>
+
+using namespace std;
+FileBrowser::FileBrowser( QWidget *parent)
+        : QWidget(parent)
+{
+
+    scrollArea = new QScrollArea( this );
+    scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
+    scrollArea->setWidgetResizable( true );
+    scrollArea->setGeometry( 10, 10, 400, 400 );
+
+    QWidget *widget = new QWidget();
+    scrollArea->setWidget( widget );
+    widget->setMaximumWidth(scrollArea->width()-20);
+
+    layout = new QVBoxLayout();
+    widget->setLayout( layout );
+    layout->setAlignment(Qt::AlignTop);
+
+    for (int i = 0; i < 10; i++)
+    {
+        QPushButton *button = new QPushButton( QString( "%1" ).arg( i ) );
+        layout->addWidget( button );
+    }
+
+    setPath("/home/tomi/Documents/minimatrixrpi");
+}
+
+FileBrowser::~FileBrowser()
+{
+}
+
+void FileBrowser::update()
+{
+//    return;
+    QLayoutItem* item;
+    while ( ( item = layout->takeAt( 0 ) ) != NULL )
+    {
+        delete item->widget();
+        delete item;
+    }
+
+    buttons.clear();
+    if (canCd(getCdUp()))
+    {
+        buttons.push_back(new QPushButton(".."));
+        layout->addWidget(buttons.back());
+        connect(buttons.back(), SIGNAL(clicked()), this, SLOT(backClicked()));
+    }
+    vector<string> dirs = getDirs(path);
+    for (int i = 0; i < dirs.size(); i++) {
+        buttons.push_back(new QPushButton(dirs[i].c_str()));
+        layout->addWidget(buttons.back());
+        connect(buttons.back(), SIGNAL(clicked()), this, SLOT(dirClicked()));
+    }
+    vector<string> files= getFiles(path);
+    for (int i = 0; i < files.size(); i++) {
+        buttons.push_back(new QPushButton(files[i].c_str()));
+        layout->addWidget(buttons.back());
+        connect(buttons.back(), SIGNAL(clicked()), this, SLOT(fileClicked()));
+        QPalette pal = buttons.back()->palette();
+        pal.setColor(QPalette::Button, QColor(Qt::cyan));
+        buttons.back()->setAutoFillBackground(true);
+        buttons.back()->setPalette(pal);
+        buttons.back()->update();
+    }
+
+    for (int i = 0; i < buttons.size(); i++)
+    {
+        buttons[i]->setStyleSheet("Text-align:left");
+    }
+    scrollArea->verticalScrollBar()->setValue(0);
+}
+
+vector<string> FileBrowser::getDirs(string path)
+{
+    vector<string> files;
+    QDir directory(path.c_str());
+    QStringList images = directory.entryList(QStringList() << "*",QDir::Dirs | QDir::NoDotAndDotDot);
+    foreach(QString filename, images) {
+        files.push_back(filename.toStdString());
+    }
+    return files;
+}
+
+vector<string> FileBrowser::getFiles(string path)
+{
+    vector<string> files;
+    QDir directory(path.c_str());
+    QStringList images = directory.entryList(QStringList() << "*.qp4", QDir::Files);
+    foreach(QString filename, images) {
+        files.push_back(filename.toStdString());
+    }
+    return files;
+}
+
+void FileBrowser::dirClicked()
+{
+    QPushButton* bt = (QPushButton*)sender();
+    string newpath = path + "/" + bt->text().toStdString();
+    qDebug() << newpath.c_str();
+    setPath(newpath);
+}
+
+void FileBrowser::backClicked()
+{
+    string newPath = getCdUp();
+    qDebug() << newPath.c_str();
+    if (canCd(newPath))
+        setPath(newPath);
+}
+
+void FileBrowser::fileClicked()
+{
+    QPushButton* bt = (QPushButton*)sender();
+    qDebug() << "File: " << bt->text().toStdString().c_str();
+    const string filepath = path + "/" + bt->text().toStdString();
+    fileSelected(filepath);
+}
+
+void FileBrowser::setPath(std::string newpath)
+{
+    path = newpath;
+    update();
+}
+
+const string FileBrowser::getPath()
+{
+    return this->path;
+}
+
+string FileBrowser::getCdUp() const
+{
+    QDir dir(path.c_str());
+    dir.cdUp();
+    return dir.cleanPath(dir.path()).toStdString();
+}
+
+bool FileBrowser::canCd(string path) const
+{
+    if (allowedFolders.size() == 0) return true;
+    QDir dir(path.c_str());
+    string apath = dir.absolutePath().toStdString();
+    for (size_t i = 0; i < allowedFolders.size(); i++) {
+        if (apath.rfind(allowedFolders[i], 0) == 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+
+
+
+
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.h
new file mode 100644
index 0000000000000000000000000000000000000000..10b170ec8e1b8a3f57705b47373722e4916d5802
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/filebrowser.h
@@ -0,0 +1,48 @@
+#ifndef FILEBROWSER_H
+#define FILEBROWSER_H
+
+#include <QWidget>
+#include <QPushButton>
+#include <QListWidget>
+#include <QScrollArea>
+#include <QVBoxLayout>
+#include <vector>
+#include <string>
+
+class FileBrowser : public QWidget
+{
+    Q_OBJECT
+private:
+    std::vector<QPushButton*> buttons;
+    QScrollArea* scrollArea;
+    QListWidget* listWidget;
+    QVBoxLayout* layout;
+    std::string path;
+    std::string lastpath;
+    std::string namefilter;
+    bool canCd(std::string path) const;
+    std::string getCdUp() const;
+
+public:
+    std::vector<std::string> allowedFolders;
+
+    FileBrowser( QWidget *parent = nullptr);
+    ~FileBrowser();
+    void update();
+    void setPath(std::string newpath);
+    const std::string getPath();
+    std::vector<std::string> getFiles(std::string dir);
+    std::vector<std::string> getDirs(std::string dir);
+
+public slots:
+    void backClicked();
+    void dirClicked();
+    void fileClicked();
+
+signals:
+    void fileSelected(const std::string filepath);
+};
+
+#endif // FILEBROWSER_H
+
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/main.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef15677543d5cc55a3dc4ea6fb5bdecfd41b73ad
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/main.cpp
@@ -0,0 +1,24 @@
+#include "mainwindow.h"
+#include "animhandler.h"
+#include "filebrowser.h"
+
+#include <QApplication>
+#include <QScrollArea>
+#include <QVBoxLayout>
+#include <QDebug>
+#include <QPushButton>
+#include <vector>
+#include <cstring>
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    MainWindow w;
+    w.show();
+    AnimHandler animh;
+    animh.openFile("/home/tomi/Documents/minimatrixrpi/MiniMatrixRPi_widgets/MiniMatrixRPi/asdasd.qp4");
+
+    return a.exec();
+}
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfa68d1a5247e61deeea54a37c3a50e115489e61
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.cpp
@@ -0,0 +1,64 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include <stdint.h>
+
+MainWindow::MainWindow(QWidget *parent)
+    : QDialog(parent)
+    , ui(new Ui::MainWindow)
+{
+    ui->setupUi(this);
+
+    btRun = new QPushButton("Run", this);
+    btPause = new QPushButton("Pause", this);
+    btStop = new QPushButton("Stop", this);
+    ui->gridLayout->addWidget(btRun, 0, 0);
+    ui->gridLayout->addWidget(btPause, 0, 1);
+    ui->gridLayout->addWidget(btStop, 0, 2);
+
+    fb = new FileBrowser();
+    animhandler = new AnimHandler();
+    animhandler->start();
+    //animhandler->openFile("/home/tomi/Documents/minimatrixrpi/asdasd.qp4");
+    mxemu = new MxEmu();
+
+    progressbar = new QProgressBar(this);
+    progressbar->setRange(0,100);
+    progressbar->setValue(10);
+    progressbar->setTextVisible(false);
+
+    fb->allowedFolders.push_back("/home/tomi/Documents/minimatrixrpi");
+    fb->update();
+    ui->gridLayout->addWidget(fb, 1, 0, 1, 2);
+    ui->gridLayout->addWidget(mxemu, 1, 2);
+    ui->gridLayout->addWidget(progressbar, 2, 0, 1, 3);
+
+    qRegisterMetaType<uint32_t>("uint32_t");
+    qRegisterMetaType<MxFrame>("MxFrame&");
+    connect(btRun, SIGNAL(clicked()), animhandler, SLOT(start_slot()));
+    connect(btPause, SIGNAL(clicked()), animhandler, SLOT(pause()));
+    connect(btStop, SIGNAL(clicked()), animhandler, SLOT(stop()));
+    connect(animhandler, &AnimHandler::updateFrame, mxemu, &MxEmu::updateFrame);
+    connect(fb, &FileBrowser::fileSelected, animhandler, &AnimHandler::openFile);
+    connect(animhandler, &AnimHandler::progressUpdate, this, &MainWindow::progressupdate);
+    connect(animhandler, &AnimHandler::onFileOpened, this, &MainWindow::fileopened);
+}
+
+void MainWindow::fileopened(const std::string filepath)
+{
+    qDebug() << "File opened: " << filepath.c_str();
+    progressbar->setValue(0);
+    progressbar->setMaximum(animhandler->getAnimTimeLen());
+    progressbar->update();
+}
+
+void MainWindow::progressupdate(uint32_t t)
+{
+    progressbar->setValue(t);
+    progressbar->update();
+}
+
+MainWindow::~MainWindow()
+{
+    delete ui;
+}
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..573798e71acda967eb8d8d577c61d433bb1ae5a6
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.h
@@ -0,0 +1,40 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "filebrowser.h"
+#include "animhandler.h"
+#include "mxemu.h"
+#include "mxframe.h"
+#include <QListWidget>
+#include <QDialog>
+#include <QProgressBar>
+#include <QPushButton>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QDialog
+{
+    Q_OBJECT
+
+public:
+    MainWindow(QWidget *parent = nullptr);
+    ~MainWindow();
+
+public slots:
+    void fileopened(const std::string filepath);
+    void progressupdate(uint32_t t);
+
+private:
+    Ui::MainWindow *ui;
+    AnimHandler *animhandler;
+    FileBrowser *fb;
+    QProgressBar *progressbar;
+    MxEmu *mxemu;
+    QPushButton *btRun;
+    QPushButton *btPause;
+    QPushButton *btStop;
+
+};
+#endif // MAINWINDOW_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.ui b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..e47c684759478b654a3d1a9835ae165ecdc9e001
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mainwindow.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QDialog" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="font">
+   <font>
+    <family>Sans Serif</family>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="gridLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>781</width>
+     <height>581</height>
+    </rect>
+   </property>
+   <layout class="QGridLayout" name="gridLayout"/>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6ea4ba10243d6735738aafd17b0998e8e8866a6d
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.cpp
@@ -0,0 +1,59 @@
+#include <QtGui>
+#include "mxemu.h"
+
+MxEmu::MxEmu(QWidget *parent) : QWidget(parent)
+{
+    for (int y = 0; y < 26; y++) {
+        for (int x = 0; x < 32; x++) {
+            frame.pixels[y][x] = Color(255,255,255);
+        }
+    }
+}
+
+QSize MxEmu::minimumSizeHint() const
+{
+    return QSize(100, 100);
+}
+
+QSize MxEmu::sizeHint() const
+{
+    return QSize(100, 200);
+}
+
+void MxEmu::paintEvent(QPaintEvent * /* event */)
+{
+    const int pixSize = 5;
+    const int vWindowMargin = 8;
+    const int hWindowMargin = 2;
+    const int vPixNum = 26;
+    const int hPixNum = 32;
+    const int windowBorderWidth = 1;
+    const int fullWidth = hPixNum * pixSize + 3 * hPixNum / 2 * windowBorderWidth + (hPixNum/2 + 1) * hWindowMargin;
+    const int fullHeight = vPixNum * pixSize + 3 * vPixNum / 2 * windowBorderWidth + (vPixNum/2 + 1) * vWindowMargin;
+
+    QPainter painter(this);
+    painter.setPen(QColor(0,0,0));
+    painter.setBrush(QColor(80,80,80));
+    painter.drawRect(0,0,fullWidth+1,fullHeight+1);
+
+    QPen pen(QColor(0,0,0));
+    pen.setWidth(windowBorderWidth);
+    if (windowBorderWidth <= 0) pen.setStyle(Qt::PenStyle::NoPen);
+    painter.setPen(pen);
+    for (int y = 0; y < 26; y++) {
+        for (int x = 0; x < 32; x++) {
+            Color c = frame.pixels[y][x];
+            painter.setBrush(QColor(c.r, c.g, c.b, c.a));
+            int x0 = 1+hWindowMargin * (x/2+1) + x*pixSize + (x + x/2) * windowBorderWidth;
+            int y0 = 1+vWindowMargin * (y/2+1) + y*pixSize + (y + y/2) * windowBorderWidth;
+
+            painter.drawRect(x0, y0, pixSize+windowBorderWidth, pixSize+windowBorderWidth);
+        }
+    }
+}
+
+void MxEmu::updateFrame(MxFrame& frame)
+{
+    this->frame = frame;
+    update();
+}
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9f1b39853049a3470639f16f903ece4ce24cc6a
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxemu.h
@@ -0,0 +1,28 @@
+#ifndef MXEMU_H
+#define MXEMU_H
+
+#include <QWidget>
+#include "mxframe.h"
+
+class MxEmu : public QWidget
+{
+    Q_OBJECT
+private:
+    MxFrame frame;
+public:
+    MxEmu(QWidget *parent = nullptr);
+
+    QSize minimumSizeHint() const override;
+    QSize sizeHint() const override;
+
+protected:
+    void paintEvent(QPaintEvent *event) override;
+
+public slots:
+    void updateFrame(MxFrame& frame);
+
+signals:
+
+};
+
+#endif // MXEMU_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d8cdacfc94817f73c0108aaf8a255f8092d3d53
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.cpp
@@ -0,0 +1,80 @@
+#include "mxframe.h"
+#include <cwctype> 
+#include <algorithm>
+
+using namespace std;
+
+vector<string> explode(const string& s, const char& c)
+{
+    string buff("");
+    vector<string> v;
+
+    for(auto n:s)
+    {
+        if(n != c) buff+=n; else
+        if(n == c && buff != "") { v.push_back(buff); buff = ""; }
+    }
+    if(buff != "") v.push_back(buff);
+
+    return v;
+}
+
+Color MxFrame::qp4strToColor(const string& str)
+{
+    uint64_t col;
+    if (str.find("0x") == 0)
+    {
+        col = stoul(str.substr(2).c_str(), nullptr, 16);
+    }
+    else {
+        col = stoul(str.c_str(), nullptr, 0);
+    }
+    uint8_t blue = (col >> 0) & 0xFF;
+    uint8_t green = (col >> 8) & 0xFF;
+    uint8_t red = (col >> 16) & 0xFF;
+    uint8_t alpha = (col >> 24) & 0xFF;
+    return Color(red, green, blue, 255);
+}
+
+MxFrame::MxFrame(Color initcolor)
+{
+    length = 0;
+    for (int y = 0; y < 26; y++) {
+        for (int x = 0; x < 32; x++) {
+            pixels[y][x] = initcolor;
+        }
+    }
+}
+
+vector<string> splitstr(const string& str, const string& delimiter)
+{
+    vector<string> strs;
+    size_t pos = 0;
+    size_t lastpos = 0;
+    while ((pos = str.find(delimiter, lastpos)) != std::string::npos) {
+        strs.push_back(str.substr(lastpos, pos - lastpos));
+        lastpos = pos+1;
+    }
+    return strs;
+}
+
+// frame({pix1, pix2, ...},1000)
+MxFrame::MxFrame(const string &import)
+{
+    size_t posBegin = import.find('{');
+    size_t posEnd = import.find('}');
+    string line = import.substr(posBegin+1, posEnd - posBegin-1);
+    line.erase(remove_if(line.begin(), line.end(), iswspace), line.end());
+    vector<string> data = splitstr(line, ",");
+    for(size_t i = 0; i < data.size() && i < 26*32; i++)
+    {
+        size_t y = i / 32;
+        size_t x = i % 32;
+        pixels[y][x] = qp4strToColor(data[i]);
+    }
+    size_t lastcomma = import.rfind(',');
+    size_t lastbracket = import.rfind(')');
+    this->length = strtoul(import.substr(lastcomma+1,lastbracket-lastcomma-1).c_str(),nullptr,10);
+}
+
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f7b99fed00072f79729a88b06fac9225a1b6a4d
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/mxframe.h
@@ -0,0 +1,19 @@
+#ifndef MXFRAME_H
+#define MXFRAME_H
+
+#include <vector>
+#include "color.hpp"
+#include <string>
+
+class MxFrame
+{
+private:
+    Color qp4strToColor(const std::string& str);
+public:
+    MxFrame(Color initcolor = Color(0,0,0));
+    MxFrame(const std::string& import);
+    Color pixels[26][32];
+    uint32_t length;
+};
+
+#endif // MXFRAME_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9b1e8c89907a6214b9b90a6adb5d48b70cb20e0
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.cpp
@@ -0,0 +1,55 @@
+#include "spiframe.h"
+
+bool SpiFrame::LedCoordToPixel(const MxFrame &mxframe, int bitpos,
+                               int colorbit, enum eColor color, int column)
+{
+    int y = 2*bitpos;
+    int x = column;
+    if (column >= 32)
+    {
+        x = 63 - column;
+        y = bitpos + 1;
+    }
+
+
+    if (color == RED)
+    {
+        return mxframe.pixels[x][y].r & (1 << colorbit);
+    }
+    else if (color == GREEN)
+    {
+        return mxframe.pixels[x][y].g & (1 << colorbit);
+    }
+    else if (color == BLUE)
+    {
+        return mxframe.pixels[x][y].b & (1 << colorbit);
+    }
+    return false;
+}
+
+SpiFrame::SpiFrame()
+{
+
+}
+
+SpiFrame::SpiFrame(const MxFrame& mxframe)
+{
+    this->length = mxframe.length;
+    for (int i = 0; i < 64*24; i++) {
+        data[i] = 0;
+    }
+    for (int column = 0; column < 64; column++) {
+        for (int bitpos = 0; bitpos < 13; bitpos++) {
+            for (int colorbit = 0; colorbit < 8; colorbit++) {
+                data[column * 24 + colorbit] |=
+                        (LedCoordToPixel(mxframe, bitpos, colorbit, RED, column) ? 1 : 0) << bitpos;
+                data[column * 24 + colorbit + 8] |=
+                        (LedCoordToPixel(mxframe, bitpos, colorbit, GREEN, column) ? 1 : 0) << bitpos;
+                data[column * 24 + colorbit + 16] |=
+                        (LedCoordToPixel(mxframe, bitpos, colorbit, BLUE, column) ? 1 : 0) << bitpos;
+            }
+        }
+    }
+}
+
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.h
new file mode 100644
index 0000000000000000000000000000000000000000..7478439afde771dd460dac5ffd6864d07b3cf5a1
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/spiframe.h
@@ -0,0 +1,21 @@
+#ifndef SPIFRAME_H
+#define SPIFRAME_H
+
+#include <stdint.h>
+#include "mxframe.h"
+
+class SpiFrame
+{
+private:
+    enum eColor {RED, GREEN, BLUE};
+    bool LedCoordToPixel(const MxFrame &mxframe, int bitpos, int colorbit, enum eColor color, int column);
+    bool PixelToLedCoord(int x, int y, enum eColor color);
+
+public:
+    SpiFrame();
+    SpiFrame(const MxFrame& mxframe);
+    uint16_t data[64 * 24];
+    uint32_t length;
+};
+
+#endif // SPIFRAME_H
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.cpp b/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..27f314803aec2bc5eca1e1f6c87302180f0bee49
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.cpp
@@ -0,0 +1,46 @@
+#include "spisender.h"
+#include "unistd.h"
+
+SpiSender::SpiSender(int readyPin): readyPin(readyPin)
+{
+//    gpioInitialise();
+//    gpioSetMode(readyPin, PI_INPUT);
+//    uint32_t flags = (1 << 20);
+//    spiHandle = spiOpen(0, 4000000, flags);
+}
+
+int SpiSender::getReadyPin() const
+{
+    return readyPin;
+}
+
+bool SpiSender::sendFrame(const SpiFrame &frame, bool waitReady) const
+{
+    uint8_t* data = static_cast<uint8_t*>(malloc(64*24*2 + 4));
+    data[0] = 0x55;
+    data[1] = 0x55;
+    data[2] = static_cast<uint8_t>(frame.length >> 8);
+    data[3] = static_cast<uint8_t>(frame.length);
+    for (size_t i = 0; i < 64*24; i++) {
+        size_t j = 2 * i + 4;
+        data[j] = frame.data[i] >> 8;
+        data[j + 1] = static_cast<uint8_t>(frame.data[i]);
+    }
+    if (waitReady)
+    {
+        while(!canSend()) usleep(1000);
+        //spiWrite(spiHandle, (char*)data, 64*24*2 + 4);
+    }
+    else if (canSend()) {
+//        spiWrite(spiHandle, (char*)data, 64*24*2 + 4);
+        return true;
+    }
+    return false;
+}
+
+bool SpiSender::canSend() const
+{
+    //return gpioRead(26);
+    return true;
+}
+
diff --git a/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.h b/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e2a293b28f7d75ae2fcc033bc606368d12cee13
--- /dev/null
+++ b/MiniMatrixRPi_widgets/MiniMatrixRPi/spisender.h
@@ -0,0 +1,22 @@
+#ifndef SPISENDER_H
+#define SPISENDER_H
+
+#include "spiframe.h"
+#include "stdint.h"
+//#include <pigpio.h>
+
+class SpiSender
+{
+private:
+    int readyPin;
+    int spiHandle;
+
+public:
+    SpiSender(int readyPin);
+    int getReadyPin() const;
+    bool sendFrame(const SpiFrame& frame, bool waitReady = false) const;
+    bool canSend() const;
+};
+
+
+#endif // SPISENDER_H
diff --git a/asdasd.qp4 b/asdasd.qp4
index 394779ac2fb5e30d5e68fdf754d0fe7952f36bfa..3b2fc3a02afd1ab8b7170725a20cae3c4a4a8f12 100755
--- a/asdasd.qp4
+++ b/asdasd.qp4
@@ -33,7 +33,35 @@ frame({
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-},1000)
+},2000)
+frame({
+0xffffffff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffff00ff,
+0xffffffff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xffffffff,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+},2000)
 endclip()
 
 rootclip("main")
diff --git a/oszlopok.qp4 b/oszlopok.qp4
new file mode 100644
index 0000000000000000000000000000000000000000..3c0e5e006b37bc5d51ff5d44061d21fc4f7aa092
--- /dev/null
+++ b/oszlopok.qp4
@@ -0,0 +1,69 @@
+-- __animeditor__
+meta({
+audio="",
+team="",
+title="",
+year=2019})
+
+beginclip(32,26,"main")
+for i=1,200 do
+frame({
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,
+},1000)
+frame({
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,0xffff0000,0xffff0000,0,0,
+},1000)
+end
+endclip()
+
+rootclip("main")
diff --git a/spi_test.cpp b/spi_test.cpp
index a42c545124b19f47cc70649b53384690b72c9b52..3d72b1b5d6e40aafa78745feb3c52090c590957b 100644
--- a/spi_test.cpp
+++ b/spi_test.cpp
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
   // cout << "GPIO OK" << endl;
 
   ures[0] = 0x55;
-  ures[1] = 0x55;  
+  ures[1] = 0x55;
   ures[2] = 0;
   ures[3] = 2;
   uint32_t tmp = 4;
diff --git a/test_anim/.vscode/c_cpp_properties.json b/test_anim/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000000000000000000000000000000000000..33fc24db0f94d8220c3cc0b4f04ed21be3c1bf01
--- /dev/null
+++ b/test_anim/.vscode/c_cpp_properties.json
@@ -0,0 +1,16 @@
+{
+    "configurations": [
+        {
+            "name": "Linux",
+            "includePath": [
+                "${workspaceFolder}"
+            ],
+            "defines": [],
+            "compilerPath": "/usr/bin/clang",
+            "cStandard": "c11",
+            "cppStandard": "c++17",
+            "intelliSenseMode": "clang-x64"
+        }
+    ],
+    "version": 4
+}
\ No newline at end of file
diff --git a/test_anim/animation.cpp b/test_anim/animation.cpp
index 43fbd311d9ffb100d052bdb5bde3a12f2b819707..56b8856fc6cb766c1afeafdb29c6ebf6c4aba9d5 100644
--- a/test_anim/animation.cpp
+++ b/test_anim/animation.cpp
@@ -1,6 +1,11 @@
 #include "animation.h"
+#include <fstream>
+#include <iostream>
+#include <sstream> //std::stringstream
 //#include <QTextStream>
 
+using namespace std;
+
 Animation::Animation()
 {
 
@@ -8,22 +13,27 @@ Animation::Animation()
 
 void Animation::openFile(const std::string& filepath)
 {
-    QFile file(filepath);
-    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
+    std::ifstream file;
+    file.open(filepath); //open the input file
+    if (!file.fail())
     {
         frames.clear();
         frameId = 0;
-        QString filestr = file.readAll();
+
+        std::stringstream strStream;
+        strStream << file.rdbuf(); //read the file
+        std::string filestr = strStream.str(); //str holds the content of the file
+        file.close();
+
         int start = 0;
         while (1) {
-            int begin = filestr.indexOf("frame(", start);
-            int end = filestr.indexOf(")", begin) + 1;
+            int begin = filestr.find("frame(", start);
+            int end = filestr.find(")", begin) + 1;
             if (begin == -1 || end == -1)
                 break;
             start = end;
-            frames.push_back(MxFrame(filestr.mid(begin, end - begin)));
+            frames.push_back(MxFrame(filestr.substr(begin, end - begin)));
         }
-        file.close();
     }
 }
 
diff --git a/test_anim/animation.h b/test_anim/animation.h
index 9e9a4727acf7b0d1af676e43126b08bc90151bab..2b80b038f120f5da2e0f9294b446c95844201789 100644
--- a/test_anim/animation.h
+++ b/test_anim/animation.h
@@ -1,9 +1,10 @@
 #ifndef ANIMATION_H
 #define ANIMATION_H
 
-#include <QFile>
-#include <QString>
+//#include <QFile>
+//#include <QString>
 #include <vector>
+#include <string>
 #include "mxframe.h"
 #include "spiframe.h"
 #include <tuple>
@@ -15,7 +16,7 @@ private:
     uint32_t frameId = 0;
 public:
     Animation();
-    void openFile(const QString filepath);
+    void openFile(const std::string& filepath);
     MxFrame nextFrame();
     bool eof();
 };
diff --git a/test_anim/mxframe.cpp b/test_anim/mxframe.cpp
index 66b932b3d4ec591f4404a74c0150c7ce4253745b..bef6e3884250d912df782e65d512d1f0a51611cf 100644
--- a/test_anim/mxframe.cpp
+++ b/test_anim/mxframe.cpp
@@ -1,4 +1,5 @@
 #include "mxframe.h"
+#include <cwctype> 
 #include <algorithm>
 
 using namespace std;