Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8U8g2srcclibu8log.c

261 lines · 6.5 KB · C

1/*
2
3 u8log.c
4
5
6 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
7
8 Copyright (c) 2018, olikraus@gmail.com
9 All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13
14 * Redistributions of source code must retain the above copyright notice, this list
15 of conditions and the following disclaimer.
16
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions and the following disclaimer in the documentation and/or other
19 materials provided with the distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
22 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35*/
36
37#include <stdint.h>
38#include <string.h>
39#include "u8x8.h"
40
41
42/*
43static uint8_t u8log_is_on_screen(u8log_t *u8log, uint8_t x, uint8_t y)
44{
45 if ( x >= u8log->width )
46 return 0;
47 if ( y >= u8log->height )
48 return 0;
49 return 1;
50}
51*/
52
53static void u8log_clear_screen(u8log_t *u8log)
54{
55 uint8_t *dest = u8log->screen_buffer;
56 uint16_t cnt = u8log->height;
57 cnt *= u8log->width;
58 do
59 {
60 *dest++ = ' ';
61 cnt--;
62 } while( cnt > 0 );
63
64}
65
66
67/* scroll the content of the complete buffer, set redraw_line to 255 */
68static void u8log_scroll_up(u8log_t *u8log)
69{
70 uint8_t *dest = u8log->screen_buffer;
71 uint8_t *src = dest+u8log->width;
72 uint16_t cnt = u8log->height;
73 cnt--;
74 cnt *= u8log->width;
75 do
76 {
77 *dest++ = *src++;
78 cnt--;
79 } while( cnt > 0 );
80 cnt = u8log->width;
81 do
82 {
83 *dest++ = ' ';
84 cnt--;
85 } while(cnt > 0);
86
87 if ( u8log->is_redraw_line_for_each_char )
88 u8log->is_redraw_all = 1;
89 else
90 u8log->is_redraw_all_required_for_next_nl = 1;
91}
92
93/*
94 Place the cursor on the screen. This will also scroll, if required
95*/
96static void u8log_cursor_on_screen(u8log_t *u8log)
97{
98 //printf("u8log_cursor_on_screen, cursor_y=%d\n", u8log->cursor_y);
99 if ( u8log->cursor_x >= u8log->width )
100 {
101 u8log->cursor_x = 0;
102 u8log->cursor_y++;
103 }
104 while ( u8log->cursor_y >= u8log->height )
105 {
106 u8log_scroll_up(u8log);
107 u8log->cursor_y--;
108 }
109}
110
111/*
112 Write a printable, single char on the screen, do any kind of scrolling
113*/
114static void u8log_write_to_screen(u8log_t *u8log, uint8_t c)
115{
116 u8log_cursor_on_screen(u8log);
117 u8log->screen_buffer[u8log->cursor_y * u8log->width + u8log->cursor_x] = c;
118 u8log->cursor_x++;
119
120 if ( u8log->is_redraw_line_for_each_char )
121 {
122 u8log->is_redraw_line = 1;
123 u8log->redraw_line = u8log->cursor_y;
124 }
125}
126
127/*
128 Handle control codes or write the char to the screen.
129 Supported control codes are:
130
131 \n 10 Goto first position of the next line. Line is marked for redraw.
132 \r 13 Goto first position in the same line. Line is marked for redraw.
133 \t 9 Jump to the next tab position
134 \f 12 Clear the screen and mark redraw for whole screen
135 any other char Write char to screen. Line redraw mark depends on
136 is_redraw_line_for_each_char flag.
137*/
138void u8log_write_char(u8log_t *u8log, uint8_t c)
139{
140 switch(c)
141 {
142 case '\n': // 10
143 u8log->is_redraw_line = 1;
144 u8log->redraw_line = u8log->cursor_y;
145 if ( u8log->is_redraw_all_required_for_next_nl )
146 u8log->is_redraw_all = 1;
147 u8log->is_redraw_all_required_for_next_nl = 0;
148 u8log->cursor_y++;
149 u8log->cursor_x = 0;
150 u8log_cursor_on_screen(u8log); // 31 Aug 2024 https://github.com/olikraus/u8g2/issues/2319
151 break;
152 case '\r': // 13
153 u8log->is_redraw_line = 1;
154 u8log->redraw_line = u8log->cursor_y;
155 u8log->cursor_x = 0;
156 break;
157 case '\t': // 9
158 u8log->cursor_x = (u8log->cursor_x + 8) & 0xf8;
159 break;
160 case '\f': // 12
161 u8log_clear_screen(u8log);
162 u8log->is_redraw_all = 1;
163 u8log->cursor_x = 0;
164 u8log->cursor_y = 0;
165 break;
166 default:
167 u8log_write_to_screen(u8log, c);
168 break;
169 }
170}
171
172void u8log_Init(u8log_t *u8log, uint8_t width, uint8_t height, uint8_t *buf)
173{
174 memset(u8log, 0, sizeof(u8log_t));
175 u8log->width = width;
176 u8log->height = height;
177 u8log->screen_buffer = buf;
178 u8log_clear_screen(u8log);
179}
180
181void u8log_SetCallback(u8log_t *u8log, u8log_cb cb, void *aux_data)
182{
183 u8log->cb = cb;
184 u8log->aux_data = aux_data;
185}
186
187void u8log_SetRedrawMode(u8log_t *u8log, uint8_t is_redraw_line_for_each_char)
188{
189 u8log->is_redraw_line_for_each_char = is_redraw_line_for_each_char;
190}
191
192/* offset can be negative or positive, it is 0 by default */
193void u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset)
194{
195 u8log->line_height_offset = line_height_offset;
196}
197
198
199
200void u8log_WriteChar(u8log_t *u8log, uint8_t c)
201{
202 u8log_write_char(u8log, c);
203 if ( u8log->is_redraw_line || u8log->is_redraw_all )
204 {
205 if ( u8log->cb != 0 )
206 {
207 u8log->cb(u8log);
208 }
209 u8log->is_redraw_line = 0;
210 u8log->is_redraw_all = 0;
211 }
212}
213
214void u8log_WriteString(u8log_t *u8log, const char *s)
215{
216 while( *s != '\0' )
217 {
218 u8log_WriteChar(u8log, *s);
219 s++;
220 }
221}
222
223static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b) U8X8_NOINLINE;
224static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b)
225{
226 b &= 0x0f;
227 if ( b < 10 )
228 u8log_WriteChar(u8log, b+'0');
229 else
230 u8log_WriteChar(u8log, b+'a'-10);
231}
232
233void u8log_WriteHex8(u8log_t *u8log, uint8_t b)
234{
235 u8log_WriteHexHalfByte(u8log, b >> 4);
236 u8log_WriteHexHalfByte(u8log, b);
237}
238
239void u8log_WriteHex16(u8log_t *u8log, uint16_t v)
240{
241 u8log_WriteHex8(u8log, v>>8);
242 u8log_WriteHex8(u8log, v);
243}
244
245void u8log_WriteHex32(u8log_t *u8log, uint32_t v)
246{
247 u8log_WriteHex16(u8log, v>>16);
248 u8log_WriteHex16(u8log, v);
249}
250
251/* v = value, d = number of digits (1..3) */
252void u8log_WriteDec8(u8log_t *u8log, uint8_t v, uint8_t d)
253{
254 u8log_WriteString(u8log, u8x8_u8toa(v, d));
255}
256
257/* v = value, d = number of digits (1..5) */
258void u8log_WriteDec16(u8log_t *u8log, uint16_t v, uint8_t d)
259{
260 u8log_WriteString(u8log, u8x8_u16toa(v, d));
261}