diff --git a/OBJECTS b/OBJECTS index 5f8ba0d..b8c836d 100644 --- a/OBJECTS +++ b/OBJECTS @@ -1,7 +1,7 @@ TARGET = main SRC = hal.cpp main.cpp example.cpp buttons.cpp -SRC += gfx/Screen.cpp gfx/Canvas.cpp gfx/Font.cpp gfx/Layout.cpp gfx/Buffer.cpp +SRC += gfx/screen.cpp gfx/canvas.cpp gfx/font.cpp gfx/layout.cpp gfx/buffer.cpp SRC += fonts/basic_5x4.cpp diff --git a/inc/buttons.h b/inc/buttons.h index 1ff106d..549cdea 100644 --- a/inc/buttons.h +++ b/inc/buttons.h @@ -2,30 +2,27 @@ // Created by jedi on 11/6/18. // -#pragma once - -namespace micromenu { - - enum direction { - I_LEFT = 0, - I_RIGHT, - I_UP, - I_DOWN - }; - - class buttons { - private: - static void onPush(direction id, bool state); - - public: - bool raw[4] = {false, false, false, false}; - bool last[4] = {false, false, false, false}; - - void poll(); - }; +#ifndef MGL_DMXMENU_INPUT_H +#define MGL_DMXMENU_INPUT_H - extern buttons input; + +#define I_LEFT 0 +#define I_RIGHT 1 +#define I_UP 2 +#define I_DOWN 3 -} +class buttons { +private: + void onPush(int id, bool state); +public: + bool raw[4]={false,false, false, false}; + bool last[4]={false,false, false, false}; + void poll(); +}; + + +extern buttons input; + +#endif //MGL_DMXMENU_INPUT_H diff --git a/inc/example.h b/inc/example.h index 88bfdea..7486609 100644 --- a/inc/example.h +++ b/inc/example.h @@ -2,38 +2,33 @@ #ifndef _EXAMPLE_H_ #define _EXAMPLE_H_ -#include "gfx/Canvas.h" +#include "gfx/canvas.h" #include "node.h" -using canvas = micromenu::Canvas; -using node = micromenu::node; -using value = micromenu::value; - class menu : public node { - public: - template - explicit menu(Args ... ns) : node(ns...) { - } +public: + template + menu(Args ... ns) : node(ns...) { + } - void render(canvas &c) override; + void render(canvas &c); }; class fooValue : public value { - public: - fooValue(const char *str, int val) : value(str, val, 32, 48) { - } +public: + fooValue(const char* str, int val) : value(str, val, 32, 48) { + } - void render(canvas &c) override; + void render(canvas &c); }; -class blubValue : public value { - public: - template - explicit blubValue(Args ... ns) : value(ns..., 64, 96) { - } - - void render(canvas &c) override; +class blubValue : public value{ +public: + template + blubValue(Args ... ns) : value(ns..., 64, 96) { + } + void render(canvas& c); }; #endif diff --git a/inc/fonts/basic_5x4.h b/inc/fonts/basic_5x4.h index 72d17da..a011b45 100644 --- a/inc/fonts/basic_5x4.h +++ b/inc/fonts/basic_5x4.h @@ -2,11 +2,11 @@ // Created by jedi on 11/2/18. // -#pragma once +#ifndef MGL_DMXMENU_BASIC_5X4_H +#define MGL_DMXMENU_BASIC_5X4_H -#include "gfx/Font.h" +#include "gfx/font.h" -namespace micromenu { - extern Font basic_5x4; -} +extern font basic_5x4; +#endif //MGL_DMXMENU_BASIC_5X4_H diff --git a/inc/gfx/Buffer.h b/inc/gfx/Buffer.h deleted file mode 100644 index be4a46d..0000000 --- a/inc/gfx/Buffer.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Created by jedi on 11/2/18. -// - - -#include -#include - -namespace micromenu { - - enum bufferBlocks { - _1bit = 1, _2bit = 2, _4bit = 4, _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32 - }; - - template - class Buffer { - private: - int *ptr_; - int size_; - constexpr static const int block_ = 8 * sizeof(int); - public: - Buffer(int size) : size_(size) { - ptr_ = (int *) malloc(size * N / 8); - } - - int get(int i) { - if(i >= size_) return 0; - return ptr_[i * N / block_] & ((1 << N) - 1) << (i * N % block_); - } - - int getBlock(int i) { - if(i >= size_) return 0; - return ptr_[i * N / block_]; - } - - void set(int i, int v) { - if(i < size_) { - ptr_[i * N / block_] &= ~(((1 << N) - 1) << (i * N % block_)); - ptr_[i * N / block_] |= (((1 << N) - 1) & v) << (i * N % block_); - } - } - - ~Buffer() { - free(ptr_); - } - }; - - template<> - int Buffer<_32bit>::get(int i); - - template<> - void Buffer<_32bit>::set(int i, int v); - -} \ No newline at end of file diff --git a/inc/gfx/Canvas.h b/inc/gfx/Canvas.h deleted file mode 100644 index 86ada3b..0000000 --- a/inc/gfx/Canvas.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by jedi on 11/1/18. -// - -#pragma once - -#include "hal/hal.h" -#include "gfx/Font.h" -#include "fonts/basic_5x4.h" -#include "gfx/Buffer.h" - -namespace micromenu { - - class Screen; - - class Canvas { - private: - const int width_; - const int height_; - Buffer<_1bit> buffer_; - - void draw_onto_(Screen &); - - public: - Canvas(int w, int h); - - void clear(); - - void draw(int x, int y, bool inv = false); - - void print(int x, int y, const char *str, bool inv = false, Font & = basic_5x4); - - void print(int x, int y, char *str, bool inv = false, Font & = basic_5x4); - - int getWidth(); - - int getHeight(); - - friend Screen; - }; - -} diff --git a/inc/gfx/Font.h b/inc/gfx/Font.h deleted file mode 100644 index 7352f43..0000000 --- a/inc/gfx/Font.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by jedi on 11/1/18. -// - -#pragma once - -namespace micromenu { - - class Canvas; - - class Font { - public: - typedef const bool raw_font[32][20]; - private: - raw_font &raw_data_; - public: - explicit Font(raw_font &) noexcept; - - void print(int x, int y, char c, Canvas &, bool inv = false); - - void print(int x, int y, char *str, Canvas &, bool inv = false); - - void print(int x, int y, const char *str, Canvas &, bool inv = false); - }; - -} - diff --git a/inc/gfx/Layout.h b/inc/gfx/Layout.h deleted file mode 100644 index 2bab30c..0000000 --- a/inc/gfx/Layout.h +++ /dev/null @@ -1,49 +0,0 @@ -// -// Created by jedi on 11/5/18. -// - -#pragma once - -#include "gfx/Canvas.h" -#include "gfx/Screen.h" - -namespace micromenu { - - class Layout { - class Slot { - private: - int pos_ = 0; - int size_ = 0; - Canvas *canvas_ = nullptr; - public: - node *content = nullptr; - friend Layout; - }; - - private: - const int maxwidth_; - const int maxheight_; - int allocated_ = 0; - Screen &screen_; - - int allocate_(node *, int); - - int expand_(int); - - int pack_(int); - - public: - static const int maxslots = 10; - Slot slots[maxslots]; - node *cursor = nullptr; - - explicit Layout(Screen &s) noexcept: maxwidth_(s.getWidth()), maxheight_(s.getHeight()), screen_(s) { - - } - - int apply(node *); - - void render(); - }; - -} diff --git a/inc/gfx/Screen.h b/inc/gfx/Screen.h deleted file mode 100644 index da244b4..0000000 --- a/inc/gfx/Screen.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// Created by jedi on 11/1/18. -// - -#pragma once - -#include "hal/hal.h" -#include "gfx/Canvas.h" - -namespace micromenu { - - class Screen { - private: - const int width_; - const int height_; - - public: - explicit Screen(int w, int h) noexcept; - - void draw(int x, int y); - - void draw(int x, int y, Canvas &c); - - void print(int x, int y, const char *str, Font & = basic_5x4); - - void print(int x, int y, char *str, Font & = basic_5x4); - - [[nodiscard]] int getWidth() const{ - return width_; - } - - [[nodiscard]] int getHeight() const{ - return height_; - } - - }; - -} diff --git a/inc/gfx/buffer.h b/inc/gfx/buffer.h new file mode 100644 index 0000000..364508f --- /dev/null +++ b/inc/gfx/buffer.h @@ -0,0 +1,50 @@ +// +// Created by jedi on 11/2/18. +// + +#ifndef MGL_DMXMENU_BUFFER_1_H +#define MGL_DMXMENU_BUFFER_1_H + + +#include +#include + +enum bufferBlocks{ + _1bit = 1, _2bit = 2, _4bit = 4, _8bit = 8, _16bit = 16, _24bit = 24, _32bit = 32 +}; + +template +class buffer { +private: + int *ptr_; + int size_; + constexpr static const int block_ = 8 * sizeof(int); +public: + buffer(int size) : size_(size) { + ptr_ = (int *) malloc(size * N / 8); + } + + int get(int i) { + if (i >= size_) return 0; + return ptr_[i*N/block_] & ((1< +int buffer<_32bit>::get(int i); + +template <> +void buffer<_32bit>::set(int i, int v); + +#endif //MGL_DMXMENU_BUFFER_1_H diff --git a/inc/gfx/canvas.h b/inc/gfx/canvas.h new file mode 100644 index 0000000..d055f13 --- /dev/null +++ b/inc/gfx/canvas.h @@ -0,0 +1,42 @@ +// +// Created by jedi on 11/1/18. +// + +#ifndef MGL_DMXMENU_CANVAS_H +#define MGL_DMXMENU_CANVAS_H + +#include "hal/hal.h" +#include "gfx/font.h" +#include "fonts/basic_5x4.h" +#include "gfx/buffer.h" + +class screen; + +class canvas { +private: + const int width_; + const int height_; + buffer<_1bit> buffer_; + + void draw_onto_(screen &); + +public: + canvas(int w, int h); + + void clear(); + + void draw(int x, int y); + + void print(int x, int y, const char *str, font & = basic_5x4); + + void print(int x, int y, char *str, font & = basic_5x4); + + int getWidth(); + + int getHeight(); + + friend screen; +}; + + +#endif //MGL_DMXMENU_CANVAS_H diff --git a/inc/gfx/font.h b/inc/gfx/font.h new file mode 100644 index 0000000..7b2dfaa --- /dev/null +++ b/inc/gfx/font.h @@ -0,0 +1,22 @@ +// +// Created by jedi on 11/1/18. +// + +#ifndef MGL_DMXMENU_FONT_H +#define MGL_DMXMENU_FONT_H + +class canvas; + +class font { +public: + typedef const bool raw_font[32][20]; +private: + raw_font& raw_data_; +public: + font(raw_font&); + void print(int x, int y, char c, canvas&); + void print(int x, int y, char* str, canvas&); + void print(int x, int y, const char* str, canvas&); +}; + +#endif //MGL_DMXMENU_FONT_H diff --git a/inc/gfx/layout.h b/inc/gfx/layout.h new file mode 100644 index 0000000..0de8ff8 --- /dev/null +++ b/inc/gfx/layout.h @@ -0,0 +1,51 @@ +// +// Created by jedi on 11/5/18. +// + +#ifndef MGL_DMXMENU_LAYOUT_H +#define MGL_DMXMENU_LAYOUT_H + +#include "gfx/canvas.h" +#include "gfx/screen.h" + +class layout { + class Slot { + private: + int pos_ = 0; + int size_ = 0; + canvas *canvas_ = nullptr; + public: + node *content = nullptr; + friend layout; + }; + +private: + const int maxwidth_; + const int maxheight_; + int allocated_; + screen& screen_; + + int allocate_(node *, int); + + int expand_(int); + + int pack_(int); + + +public: + static const int maxslots = 10; + Slot slots[maxslots]; + node *cursor; + + layout(screen& s) : maxwidth_(s.getWidth()), maxheight_(s.getHeight()), screen_(s) { + + } + + int apply(node *); + + void render(); +}; + + + +#endif //MGL_DMXMENU_LAYOUT_H diff --git a/inc/gfx/screen.h b/inc/gfx/screen.h new file mode 100644 index 0000000..d6e2d7e --- /dev/null +++ b/inc/gfx/screen.h @@ -0,0 +1,34 @@ +// +// Created by jedi on 11/1/18. +// + +#ifndef MGL_DMXMENU_SCREEN_H +#define MGL_DMXMENU_SCREEN_H + +#include "hal/hal.h" +#include "gfx/canvas.h" + +class screen { +private: + const int width_; + const int height_; + +public: + screen(int w, int h); + + void draw(int x, int y); + + void draw(int x, int y, canvas &c); + + void print(int x, int y, const char *str, font & = basic_5x4); + + void print(int x, int y, char *str, font & = basic_5x4); + + int getWidth(); + + int getHeight(); + +}; + + +#endif //MGL_DMXMENU_SCREEN_H diff --git a/inc/hal/hal.h b/inc/hal/hal.h index cb752ea..53c0818 100644 --- a/inc/hal/hal.h +++ b/inc/hal/hal.h @@ -3,12 +3,11 @@ #define _HAL_H_ -void debug(int); void debug(const char* str); void hal_init_screen(int w, int h); + void hal_poll_input(bool *ptr); -void hal_clear(); -void hal_draw(int x, int y, int b); +void hal_draw(int x, int y); void hal_render(); void render(); diff --git a/inc/node.h b/inc/node.h index e4a7fdf..429434a 100644 --- a/inc/node.h +++ b/inc/node.h @@ -2,84 +2,82 @@ // Created by jedi on 11/5/18. // -#pragma once +#ifndef MGL_DMXMENU_NODE_H +#define MGL_DMXMENU_NODE_H -#include "gfx/Canvas.h" +#include "gfx/canvas.h" -namespace micromenu { +class node { +private: + node *parent_ = nullptr; + node *child_ = nullptr; + node *cursor_ = nullptr; + node *next_ = nullptr; - class node { - private: - node *parent_ = nullptr; - node *child_ = nullptr; - node *cursor_ = nullptr; - node *next_ = nullptr; + void addNodes(bool b) { + } - void addNodes(bool b) { - } + template + void addNodes(bool b, node *n, Us ... ns) { + next_ = n; + next_->parent_ = parent_; + next_->addNodes(!b, ns...); + } - template - void addNodes(bool b, node *n, Us ... ns) { - next_ = n; - next_->parent_ = parent_; - next_->addNodes(!b, ns...); - } +public: + const char *title_ = 0; + const int minsize; + const int maxsize; - public: - const char *title_ = 0; - const int minsize; - const int maxsize; + virtual void render(canvas &c) = 0; - virtual void render(Canvas &c) = 0; + explicit node(int min = 24, int max = 48) : next_(nullptr), child_(nullptr), parent_(nullptr), minsize(min), + maxsize(max) { + } - explicit node(int min = 24, int max = 48) : next_(nullptr), child_(nullptr), parent_(nullptr), minsize(min), - maxsize(max) { - } + explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max), next_(nullptr), + child_(nullptr), + parent_(nullptr) { + } - explicit node(const char *t, int min = 24, int max = 48) : title_(t), minsize(min), maxsize(max), - next_(nullptr), - child_(nullptr), - parent_(nullptr) { - } + template + node(const char *t, node *n, Args ... ns) : title_(t), minsize(24), maxsize(48) { + child_ = n; + cursor_ = n; + n->parent_ = this; + child_->addNodes(true, ns...); + } - template - node(const char *t, node *n, Args ... ns) : title_(t), minsize(24), maxsize(48) { - child_ = n; - cursor_ = n; - n->parent_ = this; - child_->addNodes(true, ns...); - } + node *getChild() { + return child_; + } - node *getChild() { - return child_; - } + node *getNext() { + return next_; + } - node *getNext() { - return next_; - } + node *getCursor() { + return cursor_; + } - node *getCursor() { - return cursor_; - } + node *getParent() { + return parent_; + } - node *getParent() { - return parent_; - } - - void setCursor(node *c) { - cursor_ = c; - } - }; + void setCursor(node *c) { + cursor_ = c; + } +}; - class value : public node { - public: - const char *header; - int state; +class value: public node { +public: + const char *header; + int state; - value(const char *t, int val, int min = 64, int max = 96) : node(t, min, max), header(t), state(val) { - } - }; + value(const char *t, int val, int min = 64, int max = 96) : node(t, min, max), header(t), state(val) { + } +}; -} \ No newline at end of file +#endif //MGL_DMXMENU_NODE_H diff --git a/linux.Makefile b/linux.Makefile index ab30fb0..f6f1ca3 100644 --- a/linux.Makefile +++ b/linux.Makefile @@ -8,8 +8,7 @@ OBJ = $(SRC_PATH:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) REMOVEDIR = rm -rf CFLAGS += -std=gnu99 -CXXFLAGS += -std=gnu++20 -LDFLAGS = +CXXFLAGS += -std=c++17 CFLAGS += -I$(INCDIR) -DLINUX @@ -25,7 +24,7 @@ all: $(OBJDIR)/$(TARGET) .PRECIOUS: $(OBJ) $(OBJDIR)/$(TARGET): $(OBJ) | $(OBJDIR) @echo link $^ - $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + @$(CXX) $(LDFLAGS) -o $@ $^ $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) @echo compile $< diff --git a/src/buttons.cpp b/src/buttons.cpp index 514ecb5..cece779 100644 --- a/src/buttons.cpp +++ b/src/buttons.cpp @@ -5,18 +5,16 @@ #include "hal/hal.h" #include "buttons.h" -namespace micromenu { - buttons input; +buttons input; - void buttons::poll() { - hal_poll_input(raw); +void buttons::poll() { + hal_poll_input(raw); - for (int i = 0; i < 4; i++) { - if(raw[i] != last[i]) { - onPush(static_cast(i), raw[i]); - last[i] = raw[i]; - } + for(int i = 0; i < 4; i++){ + if(raw[i]!=last[i]){ + onPush(i, raw[i]); + last[i]=raw[i]; } } } \ No newline at end of file diff --git a/src/example.cpp b/src/example.cpp index dc916a6..6e9a444 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,15 +1,13 @@ -#include #include "buttons.h" #include "example.h" #include "node.h" -#include "gfx/Canvas.h" +#include "gfx/canvas.h" char peng[] = {' ', ' ', ' ', ' ', ' ', 0}; int j = 0; - void fooValue::render(canvas& c){ for(int i = 0; ititle_); - for(int i = 0; i < 6*len; i++){ - for(int j = 0; j < 7; j++) { - c.draw(2+i, 1+7*r+j); - } - } - c.print(3, 7 * r + 2, ptr->title_, true); - } else { - c.print(3, 7 * r + 2, ptr->title_); - } + node* ptr = getChild(); + while(ptr){ + c.print(3,6*r+2, ptr->title_); ptr = ptr->getNext(); r++; } diff --git a/src/fonts/basic_5x4.cpp b/src/fonts/basic_5x4.cpp index 32ef743..f761c3e 100644 --- a/src/fonts/basic_5x4.cpp +++ b/src/fonts/basic_5x4.cpp @@ -4,9 +4,7 @@ #include "fonts/basic_5x4.h" -namespace micromenu { - - const bool basic_5x4_raw[32][20] = { +const bool basic_5x4_raw[32][20] = { //0 {0,0,0,0, 0,0,0,0, @@ -169,8 +167,6 @@ namespace micromenu { 0,1,1,0, 1,0,0,0, 1,1,1,1}, - }; +}; - Font basic_5x4(basic_5x4_raw); - -} \ No newline at end of file +font basic_5x4(basic_5x4_raw); diff --git a/src/gfx/Font.cpp b/src/gfx/Font.cpp deleted file mode 100644 index 63d9495..0000000 --- a/src/gfx/Font.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Created by jedi on 11/1/18. -// - -#include "gfx/Font.h" -#include "gfx/Canvas.h" - - -namespace micromenu { - - Font::Font(raw_font &raw) noexcept : raw_data_(raw) { - } - - void Font::print(int x, int y, char l, Canvas &c, bool inv) { - int j = (l - ' ') % 32; - for (int x_ = 0; x_ < 4; x_++) - for (int y_ = 0; y_ < 5; y_++) - if(raw_data_[j][x_ + 4 * y_]) - c.draw(x + x_, y + y_, inv); - } - - void Font::print(int x, int y, char *str, Canvas &c, bool inv) { - for (int i = 0; str[i]; i++) { - print(x + i * 5, y, str[i], c, inv); - } - } - - void Font::print(int x, int y, const char *str, Canvas &c, bool inv) { - for (int i = 0; str[i]; i++) { - print(x + i * 5, y, str[i], c, inv); - } - } - -} \ No newline at end of file diff --git a/src/gfx/Layout.cpp b/src/gfx/Layout.cpp deleted file mode 100644 index 17f2ae1..0000000 --- a/src/gfx/Layout.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Created by jedi on 11/5/18. -// - -#include "node.h" -#include "gfx/Layout.h" - -namespace micromenu { - - void Layout::render() { - for (int j = 0; j < allocated_; j++) { - node *node_ptr; - node_ptr = slots[j].content; - if(node_ptr) { - slots[j].canvas_->clear(); - node_ptr->render(*slots[j].canvas_); - screen_.draw(slots[j].pos_, 0, *slots[j].canvas_); - } - } - } - - int Layout::apply(node *node) { - int rootslot = allocate_(node, maxslots); - int minsize = pack_(rootslot + 1); - expand_(minsize); - if(cursor == nullptr) - cursor = slots[rootslot].content->getCursor(); - return 0; - } - - int Layout::pack_(int usedslots) { - int minsum = 0; - int i; - for (i = 0; i < usedslots; i++) { - if(!slots[i].content) break; - if(minsum + slots[i].content->minsize > maxwidth_) break; - minsum += slots[i].content->minsize; - } - allocated_ = i; - return minsum; - } - - int Layout::expand_(int packedsize) { - int diff = maxwidth_ - packedsize; - int pos = 0; - for (int i = allocated_ - 1; i >= 0; i--) { - slots[i].pos_ = pos; - int size = slots[i].content->minsize + (diff * slots[i].content->minsize) / packedsize; - if(size > slots[i].content->maxsize) - size = slots[i].content->maxsize; - slots[i].size_ = size; - - delete slots[i].canvas_; - slots[i].canvas_ = new Canvas(size, maxheight_); - pos += size; - } - return 0; - } - - int Layout::allocate_(node *current, int depth) { - if(node *next = current->getCursor()) { - int i = allocate_(next, depth) + 1; - slots[i].content = current; - return i; - } else { - slots[0].content = current; - return 0; - } - } - -} \ No newline at end of file diff --git a/src/gfx/Screen.cpp b/src/gfx/Screen.cpp deleted file mode 100644 index 1febd8e..0000000 --- a/src/gfx/Screen.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// Created by jedi on 11/1/18. -// - -#include "gfx/Screen.h" - -namespace micromenu { - - Screen::Screen(int w, int h) noexcept: width_(w), height_(h) { - hal_init_screen(w, h); - } - - void Screen::draw(int x, int y, Canvas &c) { - for (int x_ = 0; x_ < c.getWidth(); x_++) - for (int y_ = 0; y_ < c.getHeight(); y_ += 8 * sizeof(int)) - hal_draw(x + x_, y + y_, c.buffer_.getBlock(x_ * c.getHeight() + y_)); - } - - - void Screen::print(int x, int y, const char *str, Font &f) { - //f.print(x, y, str); - } - - void Screen::print(int x, int y, char *str, Font &f) { - //f.print(x, y, str); - } - - -} \ No newline at end of file diff --git a/src/gfx/Buffer.cpp b/src/gfx/buffer.cpp similarity index 61% rename from src/gfx/Buffer.cpp rename to src/gfx/buffer.cpp index e1e6c95..153b80f 100644 --- a/src/gfx/Buffer.cpp +++ b/src/gfx/buffer.cpp @@ -2,16 +2,16 @@ // Created by jedi on 11/2/18. // -#include "gfx/Buffer.h" +#include "gfx/buffer.h" template <> -int Buffer<_32bit>::get(int i){ +int buffer<_32bit>::get(int i){ if (i >= size_) return 0; return ptr_[i]; } template <> -void Buffer<_32bit>::set(int i, int v) { +void buffer<_32bit>::set(int i, int v) { if (i < size_) ptr_[i] = v; } \ No newline at end of file diff --git a/src/gfx/canvas.cpp b/src/gfx/canvas.cpp index 0ee8358..3ff9fcc 100644 --- a/src/gfx/canvas.cpp +++ b/src/gfx/canvas.cpp @@ -2,39 +2,35 @@ // Created by jedi on 11/1/18. // -#include "gfx/Canvas.h" +#include "gfx/canvas.h" -namespace micromenu { +canvas::canvas(int w, int h) : width_(w), height_(h), buffer_(w*h) { + clear(); +} - Canvas::Canvas(int w, int h) : width_(w), height_(h), buffer_(w * h) { - clear(); - } +void canvas::clear() { + for (int x = 0; x < width_; x++) + for (int y = 0; y < height_; y++) + buffer_.set(x * height_ + y, false); +} - void Canvas::clear() { - for (int x = 0; x < width_; x++) - for (int y = 0; y < height_; y++) - buffer_.set(x * height_ + y, false); - } +void canvas::draw(int x, int y) { + if (y < height_ && x < width_) + buffer_.set(x * height_ + y, true); +} - void Canvas::draw(int x, int y, bool inv) { - if(y < height_ && x < width_) - buffer_.set(x * height_ + y, !inv); - } +void canvas::print(int x, int y, const char *str, font& f) { + f.print(x, y, str, *this); +} - void Canvas::print(int x, int y, const char *str, bool inv, Font &f) { - f.print(x, y, str, *this, inv); - } +void canvas::print(int x, int y, char *str, font& f) { + f.print(x, y, str, *this); +} - void Canvas::print(int x, int y, char *str, bool inv, Font &f) { - f.print(x, y, str, *this, inv); - } - - int Canvas::getWidth() { - return width_; - } - - int Canvas::getHeight() { - return height_; - } +int canvas::getWidth(){ + return width_; +} +int canvas::getHeight(){ + return height_; } \ No newline at end of file diff --git a/src/gfx/font.cpp b/src/gfx/font.cpp new file mode 100644 index 0000000..5049fd9 --- /dev/null +++ b/src/gfx/font.cpp @@ -0,0 +1,31 @@ +// +// Created by jedi on 11/1/18. +// + +#include "gfx/font.h" +#include "gfx/canvas.h" + + + +font::font(raw_font& raw ):raw_data_(raw){ +} + +void font::print(int x, int y, char l, canvas& c) { + int j = (l - ' ') % 32; + for (int x_ = 0; x_ < 4; x_++) + for (int y_ = 0; y_ < 5; y_++) + if (raw_data_[j][x_ + 4 * y_]) + c.draw(x + x_, y + y_); +} + +void font::print(int x, int y, char* str, canvas& c) { + for (int i = 0; str[i]; i++) { + print(x + i * 5,y,str[i],c); + } +} + +void font::print(int x, int y, const char* str, canvas& c) { + for (int i = 0; str[i]; i++) { + print(x + i * 5,y,str[i],c); + } +} \ No newline at end of file diff --git a/src/gfx/layout.cpp b/src/gfx/layout.cpp new file mode 100644 index 0000000..7632851 --- /dev/null +++ b/src/gfx/layout.cpp @@ -0,0 +1,66 @@ +// +// Created by jedi on 11/5/18. +// + +#include "node.h" +#include "gfx/layout.h" + +void layout::render() { + for (int j = 0; j < allocated_; j++) { + node *node_ptr; + if (node_ptr = slots[j].content) { + slots[j].canvas_->clear(); + node_ptr->render(*slots[j].canvas_); + screen_.draw(slots[j].pos_, 0, *slots[j].canvas_); + } + } +} + +int layout::apply(node* node) { + int rootslot = allocate_(node, maxslots); + int minsize = pack_(rootslot + 1); + expand_(minsize); + if (cursor == nullptr) + cursor = slots[rootslot].content->getCursor(); + return 0; +} + +int layout::pack_(int usedslots) { + int minsum = 0; + int i; + for (i = 0; i < usedslots; i++) { + if (!slots[i].content) break; + if (minsum + slots[i].content->minsize > maxwidth_) break; + minsum += slots[i].content->minsize; + } + allocated_ = i; + return minsum; +} + +int layout::expand_(int packedsize) { + int diff = maxwidth_ - packedsize; + int pos = 0; + for (int i = allocated_ - 1; i >= 0; i--) { + slots[i].pos_ = pos; + int size = slots[i].content->minsize + (diff * slots[i].content->minsize) / packedsize; + if (size > slots[i].content->maxsize) + size = slots[i].content->maxsize; + slots[i].size_ = size; + if(slots[i].canvas_) + delete slots[i].canvas_; + slots[i].canvas_ = new canvas(size, maxheight_); + pos += size; + } + return 0; +} + +int layout::allocate_(node* current, int depth) { + if (node* next = current->getCursor()) { + int i = allocate_(next, depth) + 1; + slots[i].content = current; + return i; + } else { + slots[0].content = current; + return 0; + } +} \ No newline at end of file diff --git a/src/gfx/screen.cpp b/src/gfx/screen.cpp new file mode 100644 index 0000000..2f491be --- /dev/null +++ b/src/gfx/screen.cpp @@ -0,0 +1,36 @@ +// +// Created by jedi on 11/1/18. +// + +#include "gfx/screen.h" + +screen::screen(int w, int h) : width_(w), height_(h) { + hal_init_screen(w,h); +} + +void screen::draw(int x, int y) { + hal_draw(x, y); +} + +void screen::draw(int x, int y, canvas &c) { + for (int x_ = 0; x_ < width_; x_++) + for (int y_ = 0; y_ < height_; y_++) + if (c.buffer_.get(x_ * height_ + y_)) + hal_draw(x + x_, y + y_); +} + +void screen::print(int x, int y, const char *str, font& f) { + //f.print(x, y, str); +} + +void screen::print(int x, int y, char *str, font& f) { + //f.print(x, y, str); +} + +int screen::getWidth(){ + return width_; +} + +int screen::getHeight(){ + return height_; +} \ No newline at end of file diff --git a/src/hal.cpp b/src/hal.cpp index 5f25083..37e98d9 100644 --- a/src/hal.cpp +++ b/src/hal.cpp @@ -8,18 +8,3 @@ #ifdef AVR #include "hal/avr.cpp" #endif - - -void debug(int n){ - const char hex[]="0123456789ABCDEF"; - char buf[]="0x00000000\n"; - buf[2]=hex[(n>>28)&0xF]; - buf[3]=hex[(n>>24)&0xF]; - buf[4]=hex[(n>>20)&0xF]; - buf[5]=hex[(n>>16)&0xF]; - buf[6]=hex[(n>>12)&0xF]; - buf[7]=hex[(n>>8)&0xF]; - buf[8]=hex[(n>>4)&0xF]; - buf[9]=hex[(n>>0)&0xF]; - debug(buf); -} \ No newline at end of file diff --git a/src/hal/avr.cpp b/src/hal/avr.cpp index 9e616fe..461f253 100644 --- a/src/hal/avr.cpp +++ b/src/hal/avr.cpp @@ -3,25 +3,24 @@ // #include "ssd1306.h" +#include "nano_gfx.h" #include "buttons.h" #include #include #include +uint8_t canvasData[128 * (32 / 8)]; +NanoCanvas canvas(128, 32, canvasData); + void hal_init_screen(int w, int h) { ssd1306_128x32_i2c_init(); - ssd1306_fillScreen( 0x00 ); DDRD = 0; PORTD |= (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5); } -void hal_draw(int x, int y, int b){ - ssd1306_putPixels(x, y, b&0xFF); - ssd1306_putPixels(x, y+8, b>>8); -} - -void hal_clear(){ +void hal_draw(int x, int y){ + canvas.putPixel(x, y); } @@ -37,7 +36,9 @@ void hal_poll_input(bool *ptr) { void hal_render() { while (true) { + ssd1306_fillScreen( 0x00 ); render(); + canvas.blt(0, 0); } } diff --git a/src/hal/linux.cpp b/src/hal/linux.cpp index ea95eec..1bcd475 100644 --- a/src/hal/linux.cpp +++ b/src/hal/linux.cpp @@ -35,20 +35,8 @@ void hal_init_screen(int width, int height){ } } -void hal_draw(int x, int y, int b) { - for (int i = 0; i < 8 *sizeof(int);i++) - if (b & (1 << i)) { - SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); - SDL_RenderDrawPoint(renderer, x, y + i); - }else{ - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); - SDL_RenderDrawPoint(renderer, x, y + i); - } -} - -void hal_clear(){ - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); - SDL_RenderClear(renderer); +void hal_draw(int x, int y){ + SDL_RenderDrawPoint(renderer, x, y); } @@ -58,6 +46,10 @@ void hal_render() { while (!quit) { + + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); render(); SDL_RenderPresent(renderer); } @@ -76,16 +68,16 @@ void hal_poll_input(bool *ptr) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_LEFT: - ptr[micromenu::I_LEFT] = true; + ptr[I_LEFT] = true; break; case SDLK_RIGHT: - ptr[micromenu::I_RIGHT] = true; + ptr[I_RIGHT] = true; break; case SDLK_UP: - ptr[micromenu::I_UP] = true; + ptr[I_UP] = true; break; case SDLK_DOWN: - ptr[micromenu::I_DOWN] = true; + ptr[I_DOWN] = true; break; case 'q': case 0x1b: //ESC @@ -97,16 +89,16 @@ void hal_poll_input(bool *ptr) { case SDL_KEYUP: switch (event.key.keysym.sym) { case SDLK_LEFT: - ptr[micromenu::I_LEFT] = false; + ptr[I_LEFT] = false; break; case SDLK_RIGHT: - ptr[micromenu::I_RIGHT] = false; + ptr[I_RIGHT] = false; break; case SDLK_UP: - ptr[micromenu::I_UP] = false; + ptr[I_UP] = false; break; case SDLK_DOWN: - ptr[micromenu::I_DOWN] = false; + ptr[I_DOWN] = false; break; } break; diff --git a/src/main.cpp b/src/main.cpp index 4a39933..a415d41 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,87 +1,110 @@ #include "hal/hal.h" #include "node.h" -#include "gfx/Layout.h" +#include "gfx/layout.h" + #include "example.h" -#include "gfx/Screen.h" -#include "gfx/Canvas.h" +#include "gfx/screen.h" +#include "gfx/canvas.h" #include "buttons.h" #ifdef LINUX - #include #include #include -extern SDL_Window *window; + +extern SDL_Window* window; extern SDL_Event event; extern SDL_Renderer *renderer; #endif -micromenu::Screen screen(128, 32); -micromenu::Layout layout(screen); -menu *root; +screen s(128,32); +layout l(s); +menu* root; -//using micromenu::menu; int main() { - root = new menu("", - new menu("baz", - new menu("x", - new fooValue("x x", 5), - new blubValue("xxx", 5) + root = new menu("", + new menu("foo", + new menu("baz", + new fooValue("I", 5), + new fooValue("II", 5), + new fooValue("III", 5), + new fooValue("IIII", 5) ), - new fooValue("I", 5), - new fooValue("II", 5), - new blubValue("III", 5), - new blubValue("IIII", 5) - ), - new menu("peng", - new fooValue("o", 5), - new fooValue("oo", 5), - new fooValue("o o", 5) - ) - ); + new menu("peng", + new fooValue("o", 5), + new fooValue("oo", 5), + new fooValue("o o", 5) + ), + new menu("x", + new fooValue("x x", 5), + new fooValue("xxx", 5) + ), + new menu("y", + new fooValue("y y", 5), + new fooValue("yyy", 5) + ) + ), + new menu("a", + new blubValue("a a", 5), + new blubValue("aa", 5), + new blubValue("aaa", 5) + ), + new menu("b", + new blubValue("b b", 5), + new blubValue("bb", 5), + new blubValue("bbb", 5) + ), + new menu("c", + new blubValue("c c", 5), + new blubValue("cc", 5), + new blubValue("ccc", 5) + ) + ); - hal_render(); - return 0; + hal_render(); + return 0; } -void render() { - layout.apply(root); - micromenu::input.poll(); - layout.render(); +void render(){ + l.apply(root); + input.poll(); + l.render(); } -void micromenu::buttons::onPush(direction dir, bool state) { - if(state) { - node *c; - if(dir == I_DOWN) { - c = layout.cursor; - node *parent = c->getParent(); - if((c = c->getNext()) || parent && (c = parent->getChild())) { - parent->setCursor(c); - layout.cursor = c; - } - } else if(dir == I_UP) { - // TODO implement - } else if(dir == I_RIGHT) { - c = layout.cursor; - c = c->getCursor(); - if(c) { - layout.cursor = c; - } - } else if(dir == I_LEFT) { - c = layout.cursor; - c = c->getParent(); - if(c) { - layout.cursor = c; - } - } - - } +void buttons::onPush(int id, bool state) { + if (state) { + node *c; + node *p; + switch (id) { + case I_DOWN: + c = l.cursor; + p = c->getParent(); + if ((c = c->getNext()) || p && (c = p->getChild())) { + p->setCursor(c); + l.cursor = c; + } + break; + case I_UP: + break; + case I_RIGHT: + c = l.cursor; + if (c = c->getCursor()) { + l.cursor = c; + } + break; + case I_LEFT: + c = l.cursor; + if (c = c->getParent()) { + l.cursor = c; + } + break; + } + } } \ No newline at end of file