]> Chaos Git - corbenik/corbenik.git/commitdiff
Fix up cprintf
authorchaoskagami <chaos.kagami@gmail.com>
Tue, 26 Apr 2016 04:01:00 +0000 (00:01 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Tue, 26 Apr 2016 04:01:00 +0000 (00:01 -0400)
source/main.c
source/std/draw.c
source/std/draw.h
source/std/memory.c
source/std/memory.h

index 6667468538818642c0c7382b5e1d7cfac3088607..42053ce9b6546ee3c113cb2626e97a153f4a4dc3 100644 (file)
@@ -5,17 +5,24 @@ void load_options() {
 }
 
 void init_system() {}
+
 int menu_handler() {
-    render_textbufs();
     return 1;
 }
 
 void main() {
     if (fmount()) {
         // Failed to mount SD. Bomb out.
+        cprintf(BOTTOM_SCREEN, "%pFailed to mount SD card.\n", COLOR(RED, BLACK));
+    } else {
+        cprintf(BOTTOM_SCREEN, "Mounted SD card.\n");
+    }
+
+    for (int i = 0; i < 200; i++) {
+        cprintf(TOP_SCREEN, "%d\n", i);
     }
 
-    cprintf(TOP_SCREEN, "Hello, %d, %s!\n", 5042, "person");
+    cprintf(TOP_SCREEN, "Done printing.");
 
     load_options(); // Load configuration.
 
index e4f6aebd3da9631aa96c382d2591bd32248f523d..0a0148181ea44aac91fb77821186b9ff585ad669 100644 (file)
@@ -6,8 +6,8 @@
 #include "memory.h"
 #include "font.h"
 
-static uint8_t cursor_x = 0, cursor_y = 0;
-static uint8_t dirty_text = 0; // We need to redraw.
+static unsigned int top_cursor_x = 0, top_cursor_y = 0;
+static unsigned int bottom_cursor_x = 0, bottom_cursor_y = 0;
 
 static char text_buffer_top    [TEXT_TOP_SIZE];
 static char text_buffer_bottom [TEXT_BOTTOM_SIZE];
@@ -43,7 +43,7 @@ void clear_screen(uint8_t* screen) {
                size = SCREEN_TOP_SIZE;
                buffer = text_buffer_top;
                buffer_size = TEXT_TOP_SIZE;
-       } else if(screen == framebuffers->top_left) {
+       } else if(screen == framebuffers->bottom) {
                size = SCREEN_BOTTOM_SIZE;
                buffer = text_buffer_bottom;
                buffer_size = TEXT_BOTTOM_SIZE;
@@ -56,20 +56,25 @@ void clear_screen(uint8_t* screen) {
 }
 
 void clear_screens() {
-    clear_screen(screen_top_left);
-    clear_screen(screen_bottom);
-       cursor_x = 0;
-       cursor_y = 0;
+    clear_screen(framebuffers->top_left);
+    clear_screen(framebuffers->bottom);
+       top_cursor_x = 0;
+       top_cursor_y = 0;
+       bottom_cursor_x = 0;
+       bottom_cursor_y = 0;
 }
 
-void draw_character(char* screen, const char character, const unsigned int buf_x, const unsigned int buf_y, const uint32_t color) {
+void draw_character(uint8_t* screen, const char character, const unsigned int buf_x, const unsigned int buf_y, const uint32_t color_fg, const uint32_t color_bg) {
+    if (!isprint(character))
+        return; // Don't output non-printables.
+
        int width  = 0;
        int height = 0;
        if(screen == framebuffers->top_left ||
        screen == framebuffers->top_right) {
                width  = SCREEN_TOP_WIDTH;
                height = SCREEN_TOP_HEIGHT;
-       } else if(screen == framebuffers->top_left) {
+       } else if(screen == framebuffers->bottom) {
                width  = SCREEN_BOTTOM_WIDTH;
                height = SCREEN_BOTTOM_HEIGHT;
        } else {
@@ -85,41 +90,63 @@ void draw_character(char* screen, const char character, const unsigned int buf_x
         for (int x = 7; x >= 0; x--) {
             int screen_pos = (pos_x * height * 3 + (height - y - pos_y - 1) * 3) + (7 - x) * 3 * height;
 
+            screen[screen_pos]     = color_bg >> 16;
+            screen[screen_pos + 1] = color_bg >> 8;
+            screen[screen_pos + 2] = color_bg;
+
             if ((char_pos >> x) & 1) {
-                screen[screen_pos] = color >> 16;
-                screen[screen_pos + 1] = color >> 8;
-                screen[screen_pos + 2] = color;
+                screen[screen_pos] = color_fg >> 16;
+                screen[screen_pos + 1] = color_fg >> 8;
+                screen[screen_pos + 2] = color_fg;
             }
         }
     }
 }
 
-void putc(int buf, const char c) {
-       int width  = 0;
-       int height = 0;
-       int size   = 0;
+void putc(int buf, unsigned char color, const char c) {
+       unsigned int width  = 0;
+       unsigned int height = 0;
+       unsigned int size = 0;
+    unsigned int cursor_x;
+    unsigned int cursor_y;
     char* colorbuf;
     char* strbuf;
-       if(buf == TOP_SCREEN) {
+
+       if (buf == TOP_SCREEN) {
                width    = TEXT_TOP_WIDTH;
                height   = TEXT_TOP_HEIGHT;
                size     = TEXT_TOP_SIZE;
         colorbuf = color_buffer_top;
         strbuf   = text_buffer_top;
-       } else if(buf == BOTTOM_SCREEN) {
+        cursor_x = top_cursor_x;
+        cursor_y = top_cursor_y;
+       } else if (buf == BOTTOM_SCREEN) {
                width    = TEXT_BOTTOM_WIDTH;
                height   = TEXT_BOTTOM_HEIGHT;
                size     = TEXT_BOTTOM_SIZE;
         colorbuf = color_buffer_bottom;
         strbuf   = text_buffer_bottom;
+        cursor_x = bottom_cursor_x;
+        cursor_y = bottom_cursor_y;
        } else {
                return; // Invalid buffer.
        }
 
        unsigned int offset = width * cursor_y + cursor_x;
 
-       if (offset > size)
-               return; // TODO - Scrollback.
+       if (offset >= size) {
+        // Scroll a line back. This involves memcpy.
+        // Yes, memcpy overwrites part of the buffer it is reading.
+        memcpy(strbuf, strbuf+width, size-width);
+        memcpy(colorbuf, colorbuf+width, size-width);
+        cursor_y -= 1;
+               offset = width * cursor_y + cursor_x;
+    }
+
+       if (offset >= size) {
+        // So if we're being real, this won't ever happen.
+        return;
+    }
 
     switch(c) {
         case '\n':
@@ -131,7 +158,7 @@ void putc(int buf, const char c) {
             break;
         default:
             strbuf[offset] = c;
-            colorbuf[offset] = 0xf0; // White on black.
+            colorbuf[offset] = color; // White on black.
             cursor_x++;
             if (cursor_x >= width) {
                 cursor_y++;
@@ -139,76 +166,57 @@ void putc(int buf, const char c) {
             }
             break;
     }
-}
-
-void puts(int buf, const char *string) {
-    char *ref = string;
 
-    while(*ref != '\0') {
-        putc(buf, *ref);
-        *ref++;
+    if (buf == TOP_SCREEN) {
+        top_cursor_x = cursor_x;
+        top_cursor_y = cursor_y;
+    } else if (buf == BOTTOM_SCREEN) {
+        bottom_cursor_x = cursor_x;
+        bottom_cursor_y = cursor_y;
     }
-
-    dirty_text = 1; // Framebuffer needs update.
 }
 
-void render_textbufs() {
-    if(!dirty_text)
-        return;
-
-    dirty_text = 0; // We're updating it.
+void puts(int buf, unsigned char color, const char *string) {
+    char *ref = (char*)string;
 
-       for(int x=0; x < TEXT_TOP_WIDTH; x++) {
-               for(int y=0; y < TEXT_TOP_HEIGHT; y++) {
-            char c = text_buffer_top[y*TEXT_TOP_WIDTH+x];
-            uint32_t color_fg = colors[((color_buffer_top[y*TEXT_TOP_WIDTH+x] >> 4) & 0x0f)];
-            uint32_t color_bg = colors[(color_buffer_top[y*TEXT_TOP_WIDTH+x] & 0x0f)];
-                       draw_character(framebuffers->top_left, c, x, y, color_fg);
-               }
-       }
-
-       for(int x=0; x < TEXT_BOTTOM_WIDTH; x++) {
-               for(int y=0; y < TEXT_BOTTOM_HEIGHT; y++) {
-            char c = text_buffer_top[y*TEXT_TOP_WIDTH+x];
-            uint32_t color_fg = colors[((color_buffer_top[y*TEXT_TOP_WIDTH+x] >> 4) & 0x0f)];
-            uint32_t color_bg = colors[(color_buffer_top[y*TEXT_TOP_WIDTH+x] & 0x0f)];
-                       draw_character(framebuffers->top_left, c, x, y, color_fg);
-               }
-       }
+    while(*ref != '\0') {
+        putc(buf, color, *ref);
+        ref++;
+    }
 }
 
-void put_int(int channel, int n) {
+void put_int(int channel, unsigned char color, int n) {
     char conv[16], out[16];
     memset(conv, 0, 16);
     memset(out, 0, 16);
 
-    int i = 0, sign = n;
-    int inter;
+    int i = 0, sign = 0;
+    if (n < 0) {
+        n = -n;
+        sign = 1;
+    }
     do {
         conv[i] = n % 10;
-        if (conv[i] < 0)
-            conv[i] = -conv[i];
         conv[i] += '0';
         ++i;
     } while((n /= 10) != 0);
 
-    if (sign < 0)
+    if (sign)
         conv[i++] = '-';
 
     int len = strlen(conv);
     for(int i=0; i < len; i++)
         out[i] = conv[(len-1) - i];
 
-    puts(channel, out);
+    puts(channel, color, out);
 }
 
-void put_uint(int channel, unsigned int n) {
+void put_uint(int channel, unsigned char color, unsigned int n) {
     char conv[16], out[16];
     memset(conv, 0, 16);
     memset(out, 0, 16);
 
     int i = 0;
-    unsigned int inter;
     do {
         conv[i++] = (n % 10) + '0';
     } while((n /= 10) != 0);
@@ -217,20 +225,37 @@ void put_uint(int channel, unsigned int n) {
     for(int i=0; i < len; i++)
         out[i] = conv[(len-1) - i];
 
-    puts(channel, out);
+    puts(channel, color, out);
+}
+
+void cflush(int channel) {
+    if (channel == TOP_SCREEN) {
+               for(int x=0; x < TEXT_TOP_WIDTH; x++) {
+                       for(int y=0; y < TEXT_TOP_HEIGHT; y++) {
+               char c = text_buffer_top[y*TEXT_TOP_WIDTH+x];
+               uint32_t color_fg = colors[((color_buffer_top[y*TEXT_TOP_WIDTH+x] >> 4) & 0x0f)];
+               uint32_t color_bg = colors[(color_buffer_top[y*TEXT_TOP_WIDTH+x] & 0x0f)];
+                               draw_character(framebuffers->top_left, c, x, y, color_fg, color_bg);
+                       }
+               }
+    } else if (channel == BOTTOM_SCREEN) {
+               for(int x=0; x < TEXT_BOTTOM_WIDTH; x++) {
+                       for(int y=0; y < TEXT_BOTTOM_HEIGHT; y++) {
+               char c = text_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x];
+               uint32_t color_fg = colors[((color_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x] >> 4) & 0x0f)];
+               uint32_t color_bg = colors[(color_buffer_top[y*TEXT_TOP_WIDTH+x] & 0x0f)];
+                               draw_character(framebuffers->bottom, c, x, y, color_fg, color_bg);
+                       }
+               }
+       }
 }
 
-int cprintf(int channel, const char* format, ...) {
-    int rc;
+void cprintf(int channel, const char* format, ...) {
     va_list ap;
     va_start( ap, format );
 
-    int i;
-    unsigned int u;
-    char* s;
-    char c;
-
-    char *ref = format;
+    char *ref = (char*)format;
+    unsigned char color = 0xf0;
 
     while(*ref != '\0') {
         if(*ref == '%') {
@@ -238,34 +263,34 @@ int cprintf(int channel, const char* format, ...) {
             ref++;
             switch(*ref) {
                 case 'd':
-                    i = va_arg( ap, int );
-                    put_int(channel, i);
+                    put_int(channel, color, va_arg( ap, int ));
                     break;
                 case 'u':
-                    u = va_arg( ap, unsigned int );
-                    put_uint(channel, u);
+                    put_uint(channel, color, va_arg( ap, unsigned int ));
                     break;
                 case 's':
-                    s = va_arg( ap, char* );
-                    puts(channel, s);
+                    puts(channel, color, va_arg( ap, char* ));
                     break;
                 case 'c':
-                    c = va_arg( ap, char );
-                    putc(channel, c);
+                    putc(channel, color, va_arg( ap, int ));
+                    break;
+                case 'p':
+                    color = va_arg( ap, unsigned int );
                     break;
                 case '%':
-                    putc(channel, '%');
+                    putc(channel, color, '%');
                     break;
                 default:
                     break;
             }
-            ref++;
         } else {
-            putc(channel, *ref);
-            *ref++;
+            putc(channel, color, *ref);
         }
+        ref++;
     }
 
     va_end( ap );
-    return rc;
+
+    cflush(channel);
 }
+
index 3ce23bffa6b071486c9f5954f4da32e2370f98f9..26b5831fe8c1567a25c671e64767732bed21df82 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __STD_DRAW_H
 #define __STD_DRAW_H
 
+/* This is in a nutshell a partial implementation of stdio.
+   It isn't perfect, but it does work. */
+
 #include <stdint.h>
 
 #define SCREEN_TOP_WIDTH 400
@@ -43,20 +46,41 @@ static struct framebuffers {
 
 void clear_screen(uint8_t* screen);
 void clear_screens();
-void draw_character(char* screen, const char character, const unsigned int pos_x, const unsigned int pos_y, const uint32_t color);
+void draw_character(uint8_t* screen, const char character, const unsigned int pos_x, const unsigned int pos_y, const uint32_t color_fg, const uint32_t color_bg);
 
 #define TOP_SCREEN    0
-#define BOTTOM_SCREEN 0
+#define BOTTOM_SCREEN 1
 
-void putc(int buf, const char c);
-void puts(int buf, const char *string);
-void render_textbufs();
+void putc(int buf, unsigned char color, const char c);
+void puts(int buf, unsigned char color, const char *string);
+void cflush(int channel);
 
-void put_int(int channel, int n);
-void put_uint(int channel, unsigned int n);
+void put_int(int channel, unsigned char color, int n);
+void put_uint(int channel, unsigned char color, unsigned int n);
 
 // Like printf. Supports the following format specifiers:
 //   %s %c %d %u
-int cprintf(int channel, const char* format, ...);
+// The following non-standard formats are also supported (but are subject to replacement)
+//   %p - unsigned char, changes color of text (will be replaced with ANSI codes eventually)
+void cprintf(int channel, const char* format, ...);
+
+#define BLACK     0
+#define BLUE      1
+#define GREEN     2
+#define CYAN      3
+#define RED       4
+#define MAGENTA   5
+#define BROWN     6
+#define GRAY      7
+#define D_GRAY    8
+#define B_BLUE    9
+#define B_GREEN   10
+#define B_CYAN    11
+#define B_RED     12
+#define B_MAGENTA 13
+#define YELLOW    14
+#define WHITE     15
+
+#define COLOR(fg, bg) (((fg & 0x0f) << 4) | (bg & 0x0f))
 
 #endif
index 249fc33997d92b99cc97c74db80f605535e18a68..e71a4a95cf0c31e58ca23eaa64e694ba039e81cf 100644 (file)
@@ -10,6 +10,12 @@ int strlen(const char *string)
     return string_end - string;
 }
 
+int isprint(char c) {
+       if (c >= 32 && c <= 127)
+        return 1;
+    return 0;
+}
+
 void memcpy(void *dest, const void *src, size_t size)
 {
     char *destc = (char *)dest;
index 3345d3793ed709676e1af96c6a3c34618615e8ef..4afbc76e88c24f4cc27c8f488c57bc2516b6cad2 100644 (file)
@@ -13,5 +13,6 @@ void strncpy(void *dest, const void *src, const size_t size);
 int strncmp(const void *buf1, const void *buf2, const size_t size);
 int atoi(const char *str);
 uint8_t* memfind (uint8_t *string, uint32_t stringlen, uint8_t *pat, uint32_t patlen);
+int isprint(char c);
 
 #endif