~ruther/CTU-FEE-B0B35APO-Semestral-project

42bce0277ee778e4dbf452779f512152c630619e — František Boháček 4 years ago 853a1f5
docs: add code documentation
M image-viewer/include/coords.h => image-viewer/include/coords.h +40 -0
@@ 7,10 7,50 @@ typedef struct {
  int32_t y;
} coords_t;

/**
 * @brief Create coords with given x and y coordinates
 * 
 * @param x x coordinate
 * @param y y coordinate
 * @return coords_t 
 */
coords_t coords_create(int32_t x, int32_t y);

/**
 * @brief Get begin coords on screen of given image and scale
 * 
 * @param image 
 * @param zoom 
 * @return coords_t 
 */
coords_t coords_get_image_screen_beg_coord(
    image_t *image, image_zoom_t zoom);

/**
 * @brief Get end coords on screen of given image and scale
 * 
 * @param image 
 * @param zoom 
 * @return coords_t 
 */
coords_t coords_get_image_screen_end_coords(image_t *image, image_zoom_t zoom);

/**
 * @brief Map image coords to screen coords for given image and zoom 
 * 
 * @param image 
 * @param zoom 
 * @param image_coords 
 * @return coords_t 
 */
coords_t image_get_screen_coords(image_t *image, image_zoom_t zoom, coords_t image_coords);

/**
 * @brief Map screen coords to image coords for given image and zoom
 * 
 * @param image 
 * @param zoom 
 * @param screen_coords 
 * @return coords_t 
 */
coords_t image_get_image_coords(image_t *image, image_zoom_t zoom, coords_t screen_coords);

M image-viewer/include/cursor.h => image-viewer/include/cursor.h +40 -0
@@ 22,11 22,51 @@ typedef struct {
extern const display_pixel_t CURSOR_COLOR;
extern const display_pixel_t CURSOR_OUTLINE_COLOR;

/**
 * @brief Create cursor
 * 
 * @return cursor_t 
 */
cursor_t cursor_create();

/**
 * @brief Center cursor within region
 * 
 * @param cursor 
 * @param region within to center the cursor
 */
void cursor_center(cursor_t *cursor, image_region_t region);

/**
 * @brief Move cursor in given direction within region given
 * 
 * @param cursor 
 * @param region to move cursor within, if cursor is outside, move it inside
 * @param direction what direction to move cursor to
 * @param amount how many steps to move
 * @return true cursor was moved
 * @return false cursor was not moved
 */
bool cursor_move(cursor_t *cursor, image_region_t region, direction_t direction, int16_t amount);

/**
 * @brief Show cursor on display screen
 * 
 * @param cursor 
 * @param image image to map image coords to screen coords
 * @param zoom zoom to map image coords to screen coords
 * @param display 
 */
void cursor_show(cursor_t *cursor, image_t *image, image_zoom_t zoom, display_t *display);

/**
 * @brief Hide cursor shown on display
 * 
 * @param cursor 
 * @param image image to map image coords to screen coords
 * @param zoom zoom to map image coords to screen coords
 * @param display 
 */
void cursor_hide(cursor_t *cursor, image_t *image, image_zoom_t zoom, display_t *display);

#endif // __CURSOR_H__

M image-viewer/include/image.h => image-viewer/include/image.h +59 -0
@@ 53,22 53,81 @@ typedef struct {
  uint16_t height;
} image_region_t;

/**
 * @brief Create image with given path
 * 
 * @param path path to image file
 * @return image_t 
 */
image_t image_create(char *path);

/**
 * @brief Clean up image data
 * 
 * @param image 
 */
void image_destroy(image_t *image);

/**
 * @brief Get image pixel on coords
 * 
 * @param image 
 * @param x x coordinate of pixel
 * @param y y coordinate of pixel
 * @return display_pixel_t 
 */
display_pixel_t image_get_pixel(image_t *image, uint16_t x, uint16_t y);

/**
 * @brief Set image pixel on coords
 * 
 * @param image 
 * @param x x coords of pixel
 * @param y y coords of pixel
 * @param pixel pixel to set
 */
void image_set_pixel(image_t *image, uint16_t x, uint16_t y,
                     display_pixel_t pixel);

/**
 * @brief Create image region
 * 
 * @param x begin x coord
 * @param y begin y coord
 * @param width width of the region
 * @param height height of the region
 * @return image_region_t 
 */
image_region_t image_region_create(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
bool image_region_move_within(image_region_t *to_move, direction_t direction,
                              int amount, image_region_t *border);

/**
 * @brief Write image data to display data
 * 
 * @param image 
 * @param display 
 * @param scale 
 * @return image_zoom_t 
 */
image_zoom_t image_write_to_display(image_t *image, display_t *display,
                              image_zoom_t scale);

/**
 * @brief Get initial zoom to show whole image on the display
 * 
 * @param image 
 * @return image_zoom_t 
 */
image_zoom_t image_get_initial_zoom(image_t *image);

/**
 * @brief Get shown region from image and zoom
 * 
 * @param image 
 * @param zoom 
 * @return image_region_t 
 */
image_region_t image_get_zoom_region(image_t *image, image_zoom_t zoom);

#endif // __IMAGE_H__

M image-viewer/include/image_loader.h => image-viewer/include/image_loader.h +40 -0
@@ 5,15 5,55 @@

typedef void (*image_load_callback)(void *state, double process);

/**
 * @brief Load image from any supported types
 * 
 * @param image 
 * @param callback 
 * @param state 
 * @return image_error_t 
 */
image_error_t image_loader_load(image_t *image, image_load_callback callback, void *state);

/**
 * @brief Load image from ppm format
 * 
 * @param image 
 * @param callback 
 * @param state 
 * @return image_error_t 
 */
image_error_t image_loader_load_ppm(image_t *image,
                                    image_load_callback callback, void *state);

/**
 * @brief Load image from jpeg format
 * 
 * @param image 
 * @param callback 
 * @param state 
 * @return image_error_t 
 */
image_error_t image_loader_load_jpeg(image_t *image,
                                     image_load_callback callback, void *state);

/**
 * @brief Load image from png
 * 
 * @param image 
 * @param callback 
 * @param state 
 * @return image_error_t 
 */
image_error_t image_loader_load_png(image_t *image,
                                    image_load_callback callback, void *state);

/**
 * @brief Deduce image type from magic number
 * 
 * @param image 
 * @return image_error_t 
 */
image_error_t image_deduce_type(image_t *image);

#endif // __IMAGE_LOADER_H__

M image-viewer/include/image_viewer.h => image-viewer/include/image_viewer.h +26 -0
@@ 34,11 34,37 @@ typedef struct {
  image_error_t error;
} image_viewer_t;

/**
 * @brief Create image viewer
 * 
 * @param filename file with image
 * @param display display to show image on
 * @param logger logger to log to
 * @param ledstrip ledstrip to show loading progress and position in image
 * @return image_viewer_t 
 */
image_viewer_t image_viewer_create(char *filename, display_t *display, logger_t *logger, mzapo_ledstrip_t ledstrip);

/**
 * @brief Clean up image viewer data
 * 
 * @param viewer 
 */
void image_viewer_destroy(image_viewer_t *viewer);

/**
 * @brief Start render loop with handling input
 * 
 * @param viewer 
 * @param reg_knobs_base base address of reg knobs 
 */
void image_viewer_start_loop(image_viewer_t *viewer, void *reg_knobs_base);

/**
 * @brief Display image on display
 * 
 * @param viewer 
 */
void image_viewer_display_image(image_viewer_t *viewer);

#endif // __IMAGE_VIEWER_H__

M lib-gui/include/font.h => lib-gui/include/font.h +47 -0
@@ 40,14 40,61 @@ typedef struct {

typedef coords_t size2d_t;

/**
 * @brief Create font from given descriptor
 * 
 * @param descriptor 
 * @return font_t 
 */
font_t font_create(font_descriptor_t descriptor);

/**
 * @brief Get text dimensions for given font 
 * 
 * @param font 
 * @param text 
 * @return size2d_t 
 */
size2d_t font_measure_text(font_t *font, char *text);

/**
 * @brief Get font character for font from char
 * 
 * @param font 
 * @param c 
 * @return font_character_t 
 */
font_character_t font_get_character(font_t *font, char c);

/**
 * @brief Get whether font contains font character 
 * 
 * @param font 
 * @param c 
 * @return true character is in font 
 * @return false character is not in font
 */
bool font_contains_character(font_t *font, char c);

/**
 * @brief Fit text with ellipsis to get how many characters can be shown
 * 
 * @param font 
 * @param size 
 * @param text 
 * @param ellipsis 
 * @return uint16_t number of characters that can be fit
 */
uint16_t font_fit_ellipsis(font_t *font, size2d_t size, char *text, char *ellipsis);

/**
 * @brief Fit cut text without any ellipsis to get how many characters can be shown
 * 
 * @param font 
 * @param size 
 * @param text 
 * @return uint16_t 
 */
uint16_t font_fit_cut(font_t *font, size2d_t size, char *text);

extern font_descriptor_t font_rom8x16;

M lib-gui/include/gui.h => lib-gui/include/gui.h +154 -0
@@ 91,52 91,206 @@ struct gui_t {
  size2d_t size;
};

/**
 * @brief Create gui state
 * 
 * @param logger 
 * @param commands 
 * @param renderer 
 * @param pheripherals 
 * @return gui_t 
 */
gui_t gui_create(logger_t *logger, commands_t *commands,
                 renderer_t *renderer, mzapo_pheripherals_t *pheripherals);

/**
 * @brief Render all elements in gui
 * 
 * @param gui 
 */
void gui_render(gui_t *gui);

/**
 * @brief Update all elements in gui
 * 
 * @param gui 
 */
void gui_update(gui_t *gui);

/**
 * @brief Set gui active window
 * 
 * @param gui 
 * @param window 
 */
void gui_set_active_window(gui_t *gui, window_t *window);

// gui_window.c
/**
 * @brief Create new gui window
 * 
 * @param containers array of containers of static size
 * @param size maximal number of the containers
 * @return window_t 
 */
window_t gui_window_create(container_t *containers, uint16_t size);

/**
 * @brief Add container to window
 * 
 * @param window 
 * @param container 
 * @return container_t* 
 */
container_t *gui_window_add_container(window_t *window, container_t container);

// gui_container.c
/**
 * @brief Render all elements inside container
 * 
 * @param gui 
 * @param container 
 */
void gui_container_render(gui_t *gui, container_t *container);

/**
 * @brief Update all elements inside container
 * 
 * @param gui 
 * @param container 
 */
void gui_container_update(gui_t *gui, container_t *container);

// gui_component.c
/**
 * @brief Create gui component
 * 
 * @param x begin x coord
 * @param y begin y coord
 * @param w width
 * @param h height
 * @param render 
 * @param update 
 * @return component_t 
 */
component_t gui_component_create(int16_t x, int16_t y, uint16_t w, uint16_t h, render_function render, update_function update);

/**
 * @brief Check whether component is within screen so it may be rendered
 * 
 * @param gui 
 * @param container 
 * @param component 
 * @return true 
 * @return false 
 */
bool gui_is_component_visible(gui_t *gui, container_t *container,
                              component_t *component);

/**
 * @brief Render gui component
 * 
 * @param gui 
 * @param container 
 * @param component 
 */
void gui_component_render(gui_t *gui, container_t *container,
                          component_t *component);

/**
 * @brief Update gui component 
 * 
 * @param gui 
 * @param container 
 * @param component 
 */
void gui_component_update(gui_t *gui, container_t *container,
                          component_t *component);

/**
 * @brief Get absolute position of component
 * 
 * @param container 
 * @param component 
 * @return coords_t 
 */
coords_t gui_component_get_absolute_position(container_t *container,
                                             component_t *component);

/**
 * @brief Get position on screen
 * 
 * @param container 
 * @param component 
 * @return coords_t 
 */
coords_t gui_component_get_screen_position(container_t *container,
                                          component_t *component);

// gui_one_container.c
/**
 * @brief Create ONE container that holds only one component
 * 
 * @param x 
 * @param y 
 * @return container_t 
 */
container_t gui_one_container_create(int16_t x, int16_t y);

/**
 * @brief Set ONE container component
 * 
 * @param container 
 * @param component 
 * @return component_t* set component
 */
component_t *gui_one_container_set_component(container_t *container,
                                     component_t component);

/**
 * @brief Get ONE container component if it is set
 * 
 * @param container 
 * @return component_t* 
 */
component_t *gui_one_container_get_component(container_t *container);

/**
 * @brief Render ONE container
 * 
 * @param gui 
 * @param container 
 */
void gui_one_container_render(gui_t *gui, container_t *container);

/**
 * @brief Update ONE container
 * 
 * @param gui 
 * @param container 
 */
void gui_one_container_update(gui_t *gui, container_t *container);

// gui_group_container.c
/**
 * @brief Create GROUP container holding n components
 * 
 * @param x 
 * @param y 
 * @param components array of components of fixed size
 * @param components_size size of components
 * @return container_t 
 */
container_t gui_group_container_create(int16_t x, int16_t y, component_t *components, uint16_t components_size);

/**
 * @brief Add component to GROUP container
 * 
 * @param container 
 * @param component 
 * @return component_t*
 * @return NULL if container is full 
 */
component_t *gui_group_container_add_component(container_t *container,
                                       component_t component);


M lib-gui/include/gui_component_line.h => lib-gui/include/gui_component_line.h +25 -0
@@ 1,8 1,33 @@
#include "gui.h"

/**
 * @brief Create gui line component
 * 
 * @param color 
 * @param x base x coordinate
 * @param y base y coordinate
 * @param w width
 * @param h height
 * @return component_t 
 */
component_t gui_line_create(const display_pixel_t *color, int16_t x, int16_t y, int16_t w, int16_t h);

/**
 * @brief Render function of gui line component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_line_render(container_t *container, component_t *component,
                          gui_t *gui);

/**
 * @brief Update function of gui line component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_line_update(container_t *container, component_t *component,
                     gui_t *gui);

M lib-gui/include/gui_component_text.h => lib-gui/include/gui_component_text.h +25 -0
@@ 10,11 10,36 @@ typedef struct {
  display_pixel_t color;
} text_t;

/**
 * @brief Create text component
 * 
 * @param text 
 * @param x base x coordinate
 * @param y base y coordinate
 * @param w width
 * @param h height
 * @return component_t 
 */
component_t gui_text_create(text_t *text, int16_t x, int16_t y,
                            int16_t w, int16_t h);

/**
 * @brief Render function of gui text component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_text_render(container_t *container, component_t *component,
                     gui_t *gui);

/**
 * @brief Update function of gui text component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_text_update(container_t *container, component_t *component,
                     gui_t *gui);


M lib-gui/include/gui_component_text_view.h => lib-gui/include/gui_component_text_view.h +57 -0
@@ 17,20 17,77 @@ typedef struct {
  display_pixel_t color;
} multiline_text_t;

/**
 * @brief Create multiline text for state of text view
 * 
 * @param font 
 * @param color 
 * @param text 
 * @return multiline_text_t* 
 */
multiline_text_t *gui_multiline_text_create(font_t *font, display_pixel_t color,
                                            char *text);

/**
 * @brief Create text view component
 * 
 * @param gui 
 * @param text multiline text state
 * @param x base x coordinate
 * @param y base y coordinate
 * @return component_t 
 */
component_t gui_text_view_create(gui_t *gui, multiline_text_t *text, int16_t x,
                                 int16_t y);

/**
 * @brief Get number of lines scrolled from text view
 * 
 * @param component 
 * @return uint16_t 
 */
uint16_t gui_text_view_get_lines_scrolled(component_t *component);

/**
 * @brief Scroll text view by x, y
 * 
 * @param text_view 
 * @param x x coordinate to scroll by
 * @param y y coordinate to scroll by
 */
void gui_text_view_scroll(component_t *text_view, int32_t x, int32_t y);

/**
 * @brief Reset scroll to 0, 0
 * 
 * @param text_view 
 */
void gui_text_view_reset_scroll(component_t *text_view);

/**
 * @brief Full scroll to the end of file
 * 
 * @param text_view 
 */
void gui_text_view_full_scroll(component_t *text_view);

/**
 * @brief Render function of gui text view component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_text_view_render(container_t *container, component_t *component,
                          gui_t *gui);

/**
 * @brief Update function of gui text view component
 * 
 * @param container 
 * @param component 
 * @param gui 
 */
void gui_text_view_update(container_t *container, component_t *component,
                          gui_t *gui);


M lib-gui/include/renderer.h => lib-gui/include/renderer.h +86 -0
@@ 15,27 15,113 @@ struct renderer_t {
  uint16_t render_area_height;
};

/**
 * @brief Create renderer for given display
 * 
 * @param display 
 * @return renderer_t 
 */
renderer_t renderer_create(display_t *display);

/**
 * @brief Clear display data
 * 
 * @param renderer 
 */
void renderer_clear(renderer_t *renderer);

/**
 * @brief Render data to display
 * 
 * @param renderer 
 */
void renderer_render(renderer_t *renderer);

/**
 * @brief Render string on display char by char
 * 
 * @param renderer 
 * @param x begin x coord
 * @param y begin y coord
 * @param length length of the text to be rendered / or the whole text if 0 or greater than text length 
 * @param font 
 * @param text 
 * @param color 
 * @return size2d_t 
 */
size2d_t renderer_write_string(renderer_t *renderer, uint16_t x, uint16_t y,
                               uint16_t length, font_t *font, char *text, display_pixel_t color);

/**
 * @brief Render render one character
 * 
 * @param renderer 
 * @param x begin x coord
 * @param y begin y coord
 * @param font 
 * @param c character
 * @param color 
 * @return size2d_t 
 */
size2d_t renderer_write_char(renderer_t *renderer, uint16_t x, uint16_t y,
                             font_t *font, char c, display_pixel_t color);

/**
 * @brief Render filled rectangle
 * 
 * @param renderer 
 * @param x base x coord
 * @param y base y coord
 * @param width width of the rectangle
 * @param height height of the rectangle
 * @param color 
 */
void renderer_render_rectangle(renderer_t *renderer, uint16_t x, uint16_t y,
                               uint16_t width, uint16_t height, display_pixel_t color);

/**
 * @brief Render rectangle border
 * 
 * @param renderer 
 * @param x base x coord
 * @param y base y coord
 * @param width width of the rectangle
 * @param height height of the rectangle
 * @param color 
 */
void renderer_render_border(renderer_t *renderer, uint16_t x, uint16_t y,
                            uint16_t width, uint16_t height, display_pixel_t color);

/**
 * @brief Translate coordinate  system of the renderer
 * 
 * @param renderer 
 * @param x translate x coord
 * @param y translate y coord
 */
void renderer_translate(renderer_t *renderer, uint16_t x, uint16_t y);

/**
 * @brief Clear translation
 * 
 * @param renderer 
 */
void renderer_clear_translate(renderer_t *renderer);

/**
 * @brief Set draw area size so nothing is drawn outside
 * 
 * @param renderer 
 * @param width 
 * @param height 
 */
void renderer_set_draw_area(renderer_t *renderer, uint16_t width, uint16_t height);

/**
 * @brief Reset draw area
 * 
 * @param renderer 
 */
void renderer_reset_draw_area(renderer_t *renderer);

#endif // __RENDERER_H__

M lib-pheripherals/include/direction.h => lib-pheripherals/include/direction.h +8 -0
@@ 10,6 10,14 @@ typedef enum {
  RIGHT,
} direction_t;

/**
 * @brief Step direction by amount to direction
 * 
 * @param direction what direction to step
 * @param x where to save x value
 * @param y where to save y value
 * @param amount step size
 */
void direction_move_xy(direction_t direction, int32_t *x, int32_t *y, int16_t amount);

#endif // __DIRECTION_H__

M lib-pheripherals/include/display_utils.h => lib-pheripherals/include/display_utils.h +59 -0
@@ 46,17 46,76 @@ extern const display_pixel_t WHITE_PIXEL;

extern const raw_pixel_t DISPLAY_PIXEL_MAX;

/**
 * @brief Make display_pixel_t from raw_pixel_onebit_t
 * 
 * @param pixel pixel to convert
 * @param max maximum rgb values (brightness) of raw pixel to calculate display pixel value from
 * @return display_pixel_t 
 */
display_pixel_t raw_pixel_onebit_convert_to_display(raw_pixel_onebit_t pixel,
                                             raw_pixel_onebit_t max);

/**
 * @brief Make display_pixel_t from raw_pixel_t
 * 
 * @param pixel pixel to convert
 * @param max maximum rgb values (brightness) of raw pixel to calculate display pixel value from
 * @return display_pixel_t 
 */
display_pixel_t raw_pixel_convert_to_display(raw_pixel_t pixel, raw_pixel_t max);

/**
 * @brief Call initialize display sequence and return its data
 * @note With COMPUTER macro this will initialize SDL window
 * 
 * @param data Data along with memory address where display is stored
 * @return display_t 
 */
display_t display_init(display_data_t data);

/**
 * @brief Clear the screen and call destroy sequence
 * @note With COMPUTER macro this will close SDL window
 * 
 * @param display 
 */
void display_deinit(display_t *display);

/**
 * @brief Render data in display_t structure on the display
 * @note With COMPUTER macro this will render data on SDL window
 * 
 * @param display 
 */
void display_render(display_t *display);

/**
 * @brief Clear display data in memory and optionally render it
 * 
 * @param display
 * @param render whether to render or only clear data in memory 
 */
void display_clear(display_t *display, bool render);

/**
 * @brief Return display pixel set in memory on given position
 * 
 * @param display 
 * @param x x coordinate of pixel
 * @param y y coordinate of pixel
 * @return display_pixel_t pixel on given position
 */
display_pixel_t display_get_pixel(display_t *display, uint16_t x, uint16_t y);

/**
 * @brief Set pixel in memory on given position
 * 
 * @param display 
 * @param x x coordinate of pixel
 * @param y y coordinate of pixel
 * @param pixel pixel to set
 */
void display_set_pixel(display_t *display, uint16_t x, uint16_t y,
                       display_pixel_t pixel);


M lib-pheripherals/include/input.h => lib-pheripherals/include/input.h +33 -0
@@ 49,14 49,47 @@ typedef struct {
  rotation_encoders_t encoders;
} commands_t;

/**
 * @brief Create and initialize commands structure to use for handling input 
 * 
 * @param array of commands with lifetime at least as big as commands_t lifetime
 * @param size maximum number of commands in array
 * @param reg_knobs_base address of reg knobs in memory to get their data
 * @return commands_t 
 */
commands_t commands_create(command_t *array, uint8_t size,
                           void *reg_knobs_base);

/**
 * @brief Add new command to commands to handle input with 
 * 
 * @param commands 
 * @param type what type of input to look for
 * @param filter depending on the type this means either a char key or index of rotation encoder
 * @param fun function that will be called when correct input is received
 * @param state state to pass to fun on command call with lifetime bigger than command
 * @return true on success
 * @return false on error (full list)
 */
bool commands_register(commands_t *commands, input_type_t type,
                       char filter, command_fun fun, void *state);

/**
 * @brief Delete/Unregister command from commands so its function is not called anymore 
 * 
 * @param commands commands to delete from
 * @param command command to delete
 * @return true command found and deleted 
 * @return false command not found
 */
bool commands_unregister(commands_t *commands, command_t *command);

/**
 * @brief Check new state of input and if conditions for any of the commands are met, call its function
 * 
 * @param commands
 * @return short number of commands called or -1 in case of an error
 */
short commands_check_input(commands_t *commands);

#endif // __INPUT_H__

M lib-pheripherals/include/logger.h => lib-pheripherals/include/logger.h +66 -1
@@ 28,16 28,81 @@ struct logger_t {
  logger_t *childLogger; // Duplicate logs to this logger
};

/**
 * @brief Create logger_t
 * 
 * @param minimalLevel minimal level to log, levels below this one will not be logged
 * @param debugFile file to output debug level to
 * @param infoFile file to output input level to
 * @param warningFile file to output warning level to
 * @param errorFile file to output error level to
 * @param childLogger child logger that will be called every log to use for duplicating to another file
 * @return logger_t 
 */
logger_t logger_create(LogLevel minimalLevel, FILE *debugFile, FILE *infoFile, FILE *warningFile,
                     FILE *errorFile, logger_t *childLogger);

/**
 * @brief Log given message
 * 
 * @param logger
 * @param level level of log
 * @param file name of file __FILE__
 * @param function name of function __FUNCTION__
 * @param line number of line __LINE__
 * @param message message with format like printf 
 * @param ... arguments to printf
 */
void logger_log(logger_t *logger, LogLevel level, const char *file, const char *function, int line, const char *const message, ...);

/**
 * @brief Log given debug message
 * 
 * @param logger
 * @param file name of file __FILE__
 * @param function name of function __FUNCTION__
 * @param line number of line __LINE__
 * @param message message with format like printf 
 * @param ... arguments to printf
 */
void logger_debug(logger_t *logger, const char *file, const char *function,
                  int line, const char *const message, ...);

/**
 * @brief Log given info message
 * 
 * @param logger
 * @param file name of file __FILE__
 * @param function name of function __FUNCTION__
 * @param line number of line __LINE__
 * @param message message with format like printf 
 * @param ... arguments to printf
 */
void logger_info(logger_t *logger, const char *file, const char *function,
                 int line, const char *const message, ...);

/**
 * @brief Log given warn message
 * 
 * @param logger
 * @param file name of file __FILE__
 * @param function name of function __FUNCTION__
 * @param line number of line __LINE__
 * @param message message with format like printf 
 * @param ... arguments to printf
 */
void logger_warn(logger_t *logger, const char *file, const char *function,
                 int line, const char *const message, ...);

/**
 * @brief Log given error message
 * 
 * @param logger
 * @param file name of file __FILE__
 * @param function name of function __FUNCTION__
 * @param line number of line __LINE__
 * @param message message with format like printf 
 * @param ... arguments to printf
 */
void logger_error(logger_t *logger, const char *file, const char *function,
                  int line, const char *const message, ...);


M lib-pheripherals/include/mzapo_led_strip.h => lib-pheripherals/include/mzapo_led_strip.h +26 -0
@@ 19,10 19,36 @@ extern "C" {
    uint32_t strip;
  } mzapo_ledstrip_t;

  /**
   * @brief Create ledstrip with state
   * 
   * @param mem_base virtual memory address where ledstrip data are saved
   * @return mzapo_ledstrip_t 
   */
  mzapo_ledstrip_t ledstrip_create(volatile uint32_t *mem_base);

  /**
   * @brief Turn off all leds on ledstrip
   * 
   * @param ledstrip 
   */
  void ledstrip_clear(mzapo_ledstrip_t *ledstrip);

  /**
   * @brief Turn on led on index and some around it
   * 
   * @param ledstrip 
   * @param index what led to turn on
   * @param around how many leds around to left and right to turn on (around * 2 + 1 leds will be turned on)
   */
  void ledstrip_turn_on(mzapo_ledstrip_t *ledstrip, uint8_t index, uint8_t around);

  /**
   * @brief Turn on leds from 0 to steps to indicate progress bar
   * 
   * @param ledstrip 
   * @param steps how many steps out of LED_STRIP_COUNT
   */
  void ledstrip_progress_bar_step(mzapo_ledstrip_t *ledstrip, int8_t steps);

#ifdef __cplusplus

M lib-pheripherals/include/mzapo_phys.h => lib-pheripherals/include/mzapo_phys.h +8 -0
@@ 21,6 21,14 @@
extern "C" {
#endif

/**
 * @brief Map physical address to virtual space to use pheripherals
 * 
 * @param region_base start of the region to map
 * @param region_size Size of the whole region
 * @param opt_cached if false, synchronize data
 * @return void* 
 */
void *map_phys_address(off_t region_base, size_t region_size, int opt_cached);

#ifdef __cplusplus

M lib-pheripherals/include/mzapo_rgb_led.h => lib-pheripherals/include/mzapo_rgb_led.h +50 -0
@@ 21,15 21,65 @@ extern "C" {
    volatile rgb_led_pixel_t *mem_base;
  } mzapo_rgb_led_t;

  /**
   * @brief Create rgb leds with state
   * 
   * @param mem_base virtual memory address where rgb leds data begin
   * @return mzapo_rgb_led_t 
   */
  mzapo_rgb_led_t rgb_led_create(unsigned char *mem_base);

  /**
   * @brief Set given rgb led to rgb, 000 for turn off
   * 
   * @param rgb_led 
   * @param id what led to change
   * @param r red (min 0, max 255)
   * @param g green (min 0, max 255)
   * @param b blue (min 0, max 255)
   */
  void rgb_led_set(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id, uint8_t r,
                   uint8_t g, uint8_t b);

  /**
   * @brief Set given rgb led to full red
   * 
   * @param rgb_led 
   * @param id what led to change
   */
  void rgb_led_set_red(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id);

  /**
   * @brief Set given rgb led to full green
   * 
   * @param rgb_led 
   * @param id what led to change
   */
  void rgb_led_set_green(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id);

  /**
   * @brief Set given rgb led to full blue
   * 
   * @param rgb_led 
   * @param id what led to change
   */
  void rgb_led_set_blue(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id);

  /**
   * @brief Get given rgb led color
   * 
   * @param rgb_led 
   * @param id what led to get data from 
   * @return rgb_led_pixel_t 
   */
  rgb_led_pixel_t rgb_led_get(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id);

  /**
   * @brief Set given rgb led to 0 - turn off
   * 
   * @param rgb_led 
   * @param id what led to change
   */
  void rgb_led_clear(mzapo_rgb_led_t *rgb_led, mzapo_rgb_leds_t id);

#ifdef __cplusplus

M lib-pheripherals/include/nonblocking_io.h => lib-pheripherals/include/nonblocking_io.h +24 -1
@@ 6,9 6,32 @@
#include <unistd.h>
#include <termios.h>

/**
 * @brief Set file to nonblocking using cfmakeraw
 * 
 * @param file to set
 * @param old termios struct to save old data to
 * @return int 
 */
int file_set_nonblocking(int file, struct termios *old);

/**
 * @brief Set file to old termios data
 * 
 * @param file to set
 * @param old termios struct to load old data from
 * @return int 
 */
int file_set_blocking(int file, struct termios *old);

/**
 * @brief Read from nonblocking file, if no data, return 0 instead of -1
 * 
 * @param file to read from
 * @param max_size size of buffer
 * @param data buffer to write data to
 * @return int 
 */
int file_read_nonblocking(int file, size_t max_size, uint8_t *data);
bool file_write_nonblocking(int file, size_t size, uint8_t *data, int max_delay);

#endif //_NONBLOCKING_IO_H

M lib-pheripherals/include/xwin_sdl.h => lib-pheripherals/include/xwin_sdl.h +34 -0
@@ 5,10 5,44 @@
#include <SDL.h>
#include <stdint.h>

/**
 * @brief Init SDL window
 * 
 * @param w width
 * @param h height
 * @return int 
 */
int xwin_init(uint16_t w, uint16_t h);

/**
 * @brief Close SDL window
 * 
 */
void xwin_close();

/**
 * @brief Redraw SDL window with img data in format rgb888 stacked together
 * 
 * @param w width of img
 * @param h height of img
 * @param img data with rgb888 stacked together
 */
void xwin_redraw(uint16_t w, uint16_t h, uint8_t *img);

/**
 * @brief Poll event to show OS window is responsive
 * 
 * @param event 
 * @return true event was polled
 * @return false no event found
 */
bool xwin_poll_event(SDL_Event *event);

/**
 * @brief Save image of the window to file
 * 
 * @param output_name where to save the image
 */
void xwin_save_image(char *output_name);

#endif

M lib-pheripherals/src/nonblocking_io.c => lib-pheripherals/src/nonblocking_io.c +0 -29
@@ 54,32 54,3 @@ int file_read_nonblocking(int file, size_t max_size, uint8_t *data)

  return read_bytes;
}

/*bool file_write_nonblocking(int file, size_t size, uint8_t *data, int max_delay) {
  int written = 0;
  bool correct = true;

  TimeMeasure measure = tmeasure_start();

  while (written < size && !tmeasure_exceededmilli(&measure, max_delay)) {
    int status = write(file, data + written, size - written);

    if (status == -1) {
      int error = errno;

      if (error != EAGAIN) {
        errno = error;
        correct = false;
        break;
      }
    } else {
      written += status;
    }
  }

  if (correct && written < size) {
    errno = ETIMEDOUT;
  }

  return correct;
  }*/

M text-viewer/include/text_viewer.h => text-viewer/include/text_viewer.h +25 -0
@@ 27,13 27,38 @@ typedef struct {
  font_t font;
} text_viewer_t;

/**
 * @brief Create text viewer struct
 * 
 * @param path path to file to open
 * @param pheripherals initialized pheripherals of mzapo
 * @param logger
 * @param font to display text with
 * @return text_viewer_t 
 */
text_viewer_t text_viewer_create(char *path, mzapo_pheripherals_t pheripherals,
                                 logger_t *logger, font_t font);

/**
 * @brief Cleans up text viewer data
 * 
 * @param text_viewer Text viewer to clean up
 */
void text_viewer_destroy(text_viewer_t *text_viewer);

/**
 * @brief Load text file and parse it into memory
 * 
 * @param text_viewer 
 * @return file_error_t 
 */
file_error_t text_viewer_load_file(text_viewer_t *text_viewer);

/**
 * @brief Start application - GUI render loop with input handling
 * 
 * @param text_viewer 
 */
void text_viewer_start_loop(text_viewer_t *text_viewer);

#endif // __TEXT_VIEWER_H__