Add [minimal] error handling + text buffering stuff

This commit is contained in:
Esteban I. RM 2017-10-29 14:07:35 -03:00
parent c934cf8eb9
commit 593502d699
10 changed files with 169 additions and 21 deletions

View File

@ -159,7 +159,7 @@ public:
args.insert(args.end(), sources.begin(), sources.end());
args.insert(args.end(), optimization.begin(), optimization.end());
args.insert(args.end(), static_bin.begin(), static_bin.end());
SH::exec(args, "");
std::cout << SH::exec(args, "") << std::endl;
} catch (std::runtime_error& err) {
return false;
}
@ -180,6 +180,13 @@ public:
add('0', '9');
add('A', 'Z');
add('a', 'z');
chars.push_back('@');
chars.push_back('>');
chars.push_back('<');
chars.push_back('$');
chars.push_back('"');
chars.push_back('\'');
chars.push_back('~');
}
std::string getName() { return "fonts"; }
std::vector<std::string> dependencies() {
@ -191,9 +198,10 @@ public:
std::ofstream f("font/font.h");
for (auto c : chars) {
std::string s(1, c);
std::string xbm = SH::exec({"convert","-font","./letvezi.ttf","-resize","16x32!", "-pointsize","14","label:"+s, "xbm:-"}, "");
std::string tail = SH::exec({"tail", "--lines=7"}, xbm);
std::string sed = SH::exec({"sed","s/^static char \\(.*\\)_bits\\[\\]/bits['" + s +"']/"}, tail);
std::string xbm = SH::exec({"convert","-font","./dejavu.ttf","-resize","8x16!", "-pointsize","14","label:"+s, "xbm:-"}, "");
std::string tail = SH::exec({"tail", "--lines=3"}, xbm);
if (s == "'") s = "\\\\'"; // hacky hack
std::string sed = SH::exec({"sed","s|^static char \\(.*\\)_bits\\[\\]|bits['" + s +"']|"}, tail);
f << sed << std::endl;
}
@ -307,7 +315,8 @@ int main(int argc, char** argv) {
"src/FontManager.cxx",
"src/Pos.cxx",
"src/RawFB.cxx",
"src/Toolkit.cxx"
"src/Toolkit.cxx",
"src/Exceptions.cxx"
};
man.add(std::shared_ptr<Task>(new TaskFonts()));

BIN
dejavu.ttf Normal file

Binary file not shown.

8
include/Exceptions.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <stdexcept>
class FramebufferException : public std::runtime_error {
public:
FramebufferException() : std::runtime_error("FramebufferException") {};
};

View File

@ -4,6 +4,8 @@
#include <string>
#include <vector>
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
class FontManager {
private:

23
include/TextScreen.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "FontManager.h"
#include <string>
#include <deque>
class TextScreen {
std::deque<std::string> buffers;
uint32_t buffer_limit;
std::string prompt;
std::string input_line; // for commands and shit
Drawer& backend;
FontManager fm;
public:
TextScreen(Drawer& backend, uint32_t buffer_limit);
void addLine(const std::string& str);
void setInputPrompt(std::string prompt);
// -1 (equiv) is "backspace", other chars are passthru (will end up as spaces when shown
// -x (equiv) need to represent left/right etc
void addInput(uint16_t c);
void render();
};

View File

@ -1,16 +1,20 @@
#include <iostream>
#include "Color.h"
#include "Drawer.h"
#include "RawFB.h"
#include "DoubleBuffering.h"
#include "FontManager.h"
#include "Toolkit.h"
#include "TextScreen.h"
int main(int argc, char ** argv){
DoubleBuffering fb(std::shared_ptr<RawFB>(new RawFB("/dev/fb0")));
std::shared_ptr<RawFB> rawfb = std::shared_ptr<RawFB>(new RawFB("/dev/fb0"));
DoubleBuffering fb(rawfb);
FontManager fonts(fb);
Toolkit tk(fb);
TextScreen tm(fb, 80);
/*
bool up = true;
int c = -16;
while (1) {
@ -37,6 +41,27 @@ int main(int argc, char ** argv){
fb.refreshScreen();
}
*/
int i = 0;
int acc = 0;
tm.setInputPrompt("exio4@localhost:~$");
while (1) {
fb.clear();
if (i == 0) {
acc++;
tm.addLine("Hello, from line " + std::to_string(acc));
}
i = (i + 1) % 15;
tm.render();
fb.refreshScreen();
}
return 0;
}

0
src/Exceptions.cxx Normal file
View File

View File

@ -7,19 +7,16 @@ FontManager::FontManager(Drawer& backend) : backend(backend) {
}
bool FontManager::check_bit(int c, int x, int y) {
if (bits[c].size() == 0) return false;
if (x < 0 || x >= 16) return false;
if (y < 0 || y >= 32) return false;
if (x < 8) {
return bits[c][y * 2] & (1 << x);
} else {
return bits[c][y * 2 + 1] & (1 << (x - 8));
}
if (x < 0 || x >= FONT_WIDTH) return false;
if (y < 0 || y >= FONT_HEIGHT) return false;
return bits[c][y] & (1 << x);
}
void FontManager::write(Pos pos, char c, int scale, Color col, double blend) {
if (bits[c].size() == 0) return;
for (int ox = 0; ox < 16; ox++) {
for (int oy = 0; oy < 32; oy++) {
for (int ox = 0; ox < FONT_WIDTH; ox++) {
for (int oy = 0; oy < FONT_HEIGHT; oy++) {
if (check_bit(c, ox, oy)) {
int count = 0;
for (int Ax = -1; Ax <= 1; Ax++) {
@ -30,7 +27,7 @@ void FontManager::write(Pos pos, char c, int scale, Color col, double blend) {
for (int i = 0; i < scale; i++) {
for (int j = 0; j < scale; j++) {
backend.putPixel(Pos(pos.x + ox * scale + i, pos.y + oy * scale + j), col, (count < 5 ? 0.5 : 1) * blend);
backend.putPixel(Pos(pos.x + ox * scale + i, pos.y + oy * scale + j), col, blend);
}
}
}

View File

@ -8,6 +8,7 @@
#include <stropts.h>
#include <sys/mman.h>
#include "RawFB.h"
#include "Exceptions.h"
#include <cstring>
RawFB::RawFB(const std::string& fb_file) {
@ -16,15 +17,27 @@ RawFB::RawFB(const std::string& fb_file) {
/* inits */
int fb_fd = open(fb_file.c_str(), O_RDWR);
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);
ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);
if (fb_fd < 0) {
throw new FramebufferException();
}
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
throw new FramebufferException();
}
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
throw new FramebufferException();
}
vinfo.xoffset = 0;
vinfo.yoffset = 0;
ioctl (fb_fd, FBIOPAN_DISPLAY, &vinfo);
if (ioctl (fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) {
throw new FramebufferException();
}
bufferSize = vinfo.yres_virtual * finfo.line_length;
fbp = (uint8_t*)mmap(0, bufferSize,
PROT_READ | PROT_WRITE,
MAP_SHARED, fb_fd, (off_t)0);
if (fbp == (uint8_t*)-1) {
throw new FramebufferException();
}
lineLen = finfo.line_length;
bpp = vinfo.bits_per_pixel/8;
ww = (uint16_t) vinfo.xres;

71
src/TextScreen.cxx Normal file
View File

@ -0,0 +1,71 @@
#include "TextScreen.h"
#include "Toolkit.h"
TextScreen::TextScreen(Drawer& backend, uint32_t blimit) : backend(backend), fm(backend) {
buffer_limit = blimit;
}
void TextScreen::addLine(const std::string& str) {
buffers.push_back(str);
if (buffers.size() > buffer_limit) {
buffers.pop_front();
}
}
void TextScreen::setInputPrompt(std::string prompt) {
this->prompt = prompt;
}
void TextScreen::addInput(uint16_t c) {
if (c == -1) {
if (input_line.size() > 0) {
input_line.pop_back();
}
} else {
input_line.push_back((char)(uint8_t)c);
}
}
void TextScreen::render() {
Toolkit tk(backend);
const int factor_width = 8;
const int factor_height = 16;
int width = backend.screenWidth() / factor_width;
int height = backend.screenHeight() / factor_height;
int y = 0;
int ix = buffers.size()-height-1;
if (ix < 0) ix = 0;
for (int i=0; i < height-1; i++) {
if (ix+i >= buffers.size()) break;
int x = 0;
for (int j = 0; j < width; j++) {
if (j >= buffers[ix+i].size()) break;
fm.write(Pos(x,y), buffers[ix+i][j]);
x += factor_width;
}
y += factor_height;
}
{
y = backend.screenHeight() - factor_height;
tk.line(Pos(0,y), Pos(backend.screenWidth(),y), Color(0,128,0));
int x = 0;
for (int i=0; i < prompt.size(); i++) {
fm.write(Pos(x,y), prompt[i]);
x += factor_width;
}
bool too_long = false;
int min = 0;
int max = input_line.size();
int diff = width - prompt.size() - 1;
if (max > diff) {
too_long = true;
max = diff;
min = input_line.size() - diff;
}
for (int i=min; i < max; i++) {
fm.write(Pos(x,y), input_line[i]);
x += factor_width;
}
}
}