Extract rendering function out and render a few lines
This commit is contained in:
parent
177f73f78a
commit
8117e9250a
246
bt.c
246
bt.c
@ -16,6 +16,7 @@
|
||||
|
||||
const int SCREEN_WIDTH = 900;
|
||||
const int SCREEN_HEIGHT = 700;
|
||||
const int SCROLLBACK_DEFAULT_SIZE = 4096;
|
||||
const SDL_Color WHITE = {255, 255, 255, 255};
|
||||
const SDL_Color BLACK = {0, 0, 0, 255};
|
||||
const SDL_Color RED = {255, 0, 0, 255};
|
||||
@ -26,20 +27,26 @@ const SDL_Color MAGENTA = {255, 0, 255, 255};
|
||||
const SDL_Color SKYBLUE = {0, 255, 255, 255};
|
||||
const SDL_Color RAYWHITE = {200, 200, 200, 255};
|
||||
|
||||
typedef struct scrollback {
|
||||
typedef struct {
|
||||
float height;
|
||||
float ypos;
|
||||
int capacity;
|
||||
int length;
|
||||
char *buf;
|
||||
} scrollback;
|
||||
} Scrollback;
|
||||
|
||||
typedef struct file_descriptors {
|
||||
typedef struct {
|
||||
int master;
|
||||
int child;
|
||||
} file_descriptors;
|
||||
} FileDescriptors;
|
||||
|
||||
void spawn(file_descriptors *fds) {
|
||||
typedef struct {
|
||||
Scrollback* sb;
|
||||
TTF_Font* font;
|
||||
SDL_Renderer* renderer;
|
||||
} Context;
|
||||
|
||||
void spawn(FileDescriptors *fds) {
|
||||
openpty(&fds->master, &fds->child, NULL, NULL, NULL);
|
||||
pid_t p = fork();
|
||||
if (p == 0) {
|
||||
@ -57,7 +64,7 @@ void spawn(file_descriptors *fds) {
|
||||
}
|
||||
}
|
||||
|
||||
int read_pty(file_descriptors *fds, scrollback *sb) {
|
||||
int read_pty(FileDescriptors *fds, Scrollback *sb) {
|
||||
ssize_t nread;
|
||||
char readbuf[256];
|
||||
switch (nread = read(fds->master, readbuf, sizeof(readbuf))) {
|
||||
@ -84,9 +91,115 @@ int read_pty(file_descriptors *fds, scrollback *sb) {
|
||||
}
|
||||
}
|
||||
|
||||
void render_scrollback(Context* ctx) {
|
||||
SDL_RenderClear(ctx->renderer);
|
||||
|
||||
SDL_Color current_color = WHITE;
|
||||
int col_max = 80;
|
||||
char row_buf[col_max];
|
||||
int nrow = 0;
|
||||
int ncol = 0;
|
||||
int row_height = 18;
|
||||
float row_posx = 0;
|
||||
Scrollback sb = *ctx->sb;
|
||||
for (int c = 0; c <= sb.length; c++) {
|
||||
// for (int c = 0; c <= -1; c++) {
|
||||
if (sb.buf[c] == '\r') {
|
||||
continue;
|
||||
} else if (sb.buf[c] == '\n' || sb.buf[c] == '\0' || ncol >= col_max) {
|
||||
row_buf[ncol] = '\0';
|
||||
// TODO: Render new line or something?
|
||||
// Vector2 pos = { row_posx, nrow * row_height + sb.ypos };
|
||||
// DrawTextEx(*fontDefault, row_buf, pos, fontsize, 0, current_color);
|
||||
SDL_Surface* surface =
|
||||
TTF_RenderText_Blended(ctx->font, row_buf, WHITE);
|
||||
|
||||
// now you can convert it into a texture
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(ctx->renderer, surface);
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = nrow * 15;
|
||||
rect.w = surface->w;
|
||||
rect.h = surface->h;
|
||||
|
||||
|
||||
SDL_RenderCopy(ctx->renderer, texture, NULL, &rect);
|
||||
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
nrow++;
|
||||
ncol = 0;
|
||||
row_posx = 0;
|
||||
// Control sequence
|
||||
} else if (sb.buf[c] == '\x1b') {
|
||||
int c2 = c + 1;
|
||||
// Control Sequence Introducer
|
||||
int csi_args[16];
|
||||
char csi_code;
|
||||
int nargs = 0;
|
||||
if (sb.buf[c2] == '[') {
|
||||
char *esc_buf = sb.buf + c2 + 1;
|
||||
while (true) {
|
||||
char *substr;
|
||||
long num = strtol(esc_buf, &substr, 10);
|
||||
if (esc_buf != substr) {
|
||||
csi_args[nargs++] = num;
|
||||
esc_buf = substr;
|
||||
if (substr[0] == ';') {
|
||||
esc_buf++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
csi_code = substr[0];
|
||||
SDL_Color new_color = WHITE;
|
||||
switch (csi_code) {
|
||||
case 'm':
|
||||
for (int i = 0; i < nargs; i++) {
|
||||
if (csi_args[i] == 31) {
|
||||
new_color = RED;
|
||||
} else if (csi_args[i] == 32) {
|
||||
new_color = GREEN;
|
||||
} else if (csi_args[i] == 33) {
|
||||
new_color = YELLOW;
|
||||
} else if (csi_args[i] == 34) {
|
||||
new_color = BLUE;
|
||||
} else if (csi_args[i] == 35) {
|
||||
new_color = MAGENTA;
|
||||
} else if (csi_args[i] == 36) {
|
||||
new_color = SKYBLUE;
|
||||
} else if (csi_args[i] == 0) {
|
||||
new_color = RAYWHITE;
|
||||
}
|
||||
}
|
||||
row_buf[ncol] = '\0';
|
||||
// TODO: This looks like the actual place where we
|
||||
// draw the text at a line
|
||||
// Vector2 pos = { row_posx, nrow * row_height + sb.ypos };
|
||||
// DrawTextEx(*fontDefault, row_buf, pos, fontsize, 0, current_color);
|
||||
current_color = new_color;
|
||||
ncol = 0;
|
||||
c += (substr) - (sb.buf + c);
|
||||
// TODO: Get the text height
|
||||
// int width = MeasureTextEx(*fontDefault, row_buf, fontsize, 1).x;
|
||||
// row_posx += width + 0.85;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row_buf[ncol++] = sb.buf[c];
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderPresent(ctx->renderer);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
scrollback sb = { 0 };
|
||||
file_descriptors fds = { 0 };
|
||||
Scrollback sb = { 0 };
|
||||
FileDescriptors fds = { 0 };
|
||||
|
||||
spawn(&fds);
|
||||
|
||||
@ -94,20 +207,21 @@ int main(void) {
|
||||
printf("error initializing SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Window* window = SDL_CreateWindow( "bt",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
int start_x = 20;
|
||||
int start_y = 20;
|
||||
SDL_Window* window = SDL_CreateWindow("bt",
|
||||
start_x,
|
||||
start_y,
|
||||
SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT,
|
||||
SDL_WINDOW_SHOWN );
|
||||
SDL_WINDOW_SHOWN);
|
||||
if (window == NULL) {
|
||||
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_SetRenderDrawColor(renderer, 130, 163, 255, 1);
|
||||
// SDL_SetRenderDrawColor(renderer, 130, 163, 255, 1);
|
||||
TTF_Init();
|
||||
TTF_Font* font = TTF_OpenFont( "./fira.ttf", 16);
|
||||
|
||||
@ -120,7 +234,7 @@ int main(void) {
|
||||
// TODO: It would be nice to figure out how to do this in SDL
|
||||
// SetTargetFPS(60);
|
||||
|
||||
sb.capacity = 2048;
|
||||
sb.capacity = SCROLLBACK_DEFAULT_SIZE;
|
||||
sb.buf = malloc(sb.capacity);
|
||||
sb.buf[0] = '\0';
|
||||
sb.length = 0;
|
||||
@ -136,6 +250,11 @@ int main(void) {
|
||||
|
||||
sb.ypos = 0;
|
||||
|
||||
Context ctx = {
|
||||
.sb = &sb,
|
||||
.font = font,
|
||||
.renderer = renderer
|
||||
};
|
||||
bool new_read = false;
|
||||
bool new_char = false;
|
||||
SDL_Event e;
|
||||
@ -203,108 +322,13 @@ int main(void) {
|
||||
}
|
||||
|
||||
|
||||
// Drawing
|
||||
int nread = read_pty(&fds, &sb);
|
||||
if (nread > 0) {
|
||||
sb.length += nread;
|
||||
new_read = true;
|
||||
}
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_Surface* surfaceMessage =
|
||||
TTF_RenderText_Blended(font, "put your text here", WHITE);
|
||||
|
||||
// now you can convert it into a texture
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = surfaceMessage->w;
|
||||
rect.h = surfaceMessage->h;
|
||||
|
||||
SDL_RenderCopy(renderer, texture, NULL, &rect);
|
||||
|
||||
SDL_Color current_color = WHITE;
|
||||
int col_max = 200;
|
||||
char row_buf[col_max];
|
||||
int nrow = 0;
|
||||
int ncol = 0;
|
||||
int row_height = 18;
|
||||
float row_posx = 0;
|
||||
// for (int c = 0; c <= sb.length; c++) {
|
||||
for (int c = 0; c <= -1; c++) {
|
||||
if (sb.buf[c] == '\r') {
|
||||
continue;
|
||||
} else if (sb.buf[c] == '\n' || sb.buf[c] == '\0' || ncol >= col_max) {
|
||||
row_buf[ncol] = '\0';
|
||||
// TODO: Render new line or something?
|
||||
// Vector2 pos = { row_posx, nrow * row_height + sb.ypos };
|
||||
// DrawTextEx(*fontDefault, row_buf, pos, fontsize, 0, current_color);
|
||||
nrow++;
|
||||
ncol = 0;
|
||||
row_posx = 0;
|
||||
} else if (sb.buf[c] == '\x1b') {
|
||||
int c2 = c + 1;
|
||||
// Control Sequence Introducer
|
||||
int csi_args[16];
|
||||
char csi_code;
|
||||
int nargs = 0;
|
||||
if (sb.buf[c2] == '[') {
|
||||
char *esc_buf = sb.buf + c2 + 1;
|
||||
while (true) {
|
||||
char *substr;
|
||||
long num = strtol(esc_buf, &substr, 10);
|
||||
if (esc_buf != substr) {
|
||||
csi_args[nargs++] = num;
|
||||
esc_buf = substr;
|
||||
if (substr[0] == ';') {
|
||||
esc_buf++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
csi_code = substr[0];
|
||||
SDL_Color new_color = WHITE;
|
||||
switch (csi_code) {
|
||||
case 'm':
|
||||
for (int i = 0; i < nargs; i++) {
|
||||
if (csi_args[i] == 31) {
|
||||
new_color = RED;
|
||||
} else if (csi_args[i] == 32) {
|
||||
new_color = GREEN;
|
||||
} else if (csi_args[i] == 33) {
|
||||
new_color = YELLOW;
|
||||
} else if (csi_args[i] == 34) {
|
||||
new_color = BLUE;
|
||||
} else if (csi_args[i] == 35) {
|
||||
new_color = MAGENTA;
|
||||
} else if (csi_args[i] == 36) {
|
||||
new_color = SKYBLUE;
|
||||
} else if (csi_args[i] == 0) {
|
||||
new_color = RAYWHITE;
|
||||
}
|
||||
}
|
||||
row_buf[ncol] = '\0';
|
||||
// TODO: This looks like the actual place where we
|
||||
// draw the text at a line
|
||||
// Vector2 pos = { row_posx, nrow * row_height + sb.ypos };
|
||||
// DrawTextEx(*fontDefault, row_buf, pos, fontsize, 0, current_color);
|
||||
current_color = new_color;
|
||||
ncol = 0;
|
||||
c += (substr) - (sb.buf + c);
|
||||
// TODO: Get the text height
|
||||
// int width = MeasureTextEx(*fontDefault, row_buf, fontsize, 1).x;
|
||||
// row_posx += width + 0.85;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row_buf[ncol++] = sb.buf[c];
|
||||
}
|
||||
}
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surfaceMessage);
|
||||
render_scrollback(&ctx);
|
||||
}
|
||||
|
||||
free(sb.buf);
|
||||
|
@ -1,8 +1,7 @@
|
||||
#-*- mode: org -*-
|
||||
#+TODO: BLOCKED TODO INPROGRESS | DONE BACKLOG
|
||||
#+TODO: TODO | DONE
|
||||
#+STARTUP: overview
|
||||
|
||||
|
||||
* DONE Render with Raylib
|
||||
* DONE Load custom Mono font
|
||||
* DONE Render input from user
|
||||
@ -12,17 +11,12 @@
|
||||
* DONE Auto-scrolling
|
||||
* DONE Render scrollback by rows
|
||||
* DONE Handle color escape sequences
|
||||
* TODO Backspace and Return aren't repeating [[https://github.com/raysan5/raylib/issues/2041][Issue Here]]
|
||||
* TODO Switch to SDL2
|
||||
* DONE Switch to SDL2
|
||||
* TODO Clean up the rendering of the scrollback buffer
|
||||
* TODO Get Backspace and Return to repeat properly [[https://github.com/raysan5/raylib/issues/2041][Why we switched to SDL]]
|
||||
* TODO Render the scrollback line by line
|
||||
* TODO Only draw scrollback that is visible
|
||||
* TODO Improve the scrolling to match first and last lines
|
||||
* TODO Handle unicode characters
|
||||
* TODO Handle canonical and raw commands
|
||||
* TODO Mouse copy/paste
|
||||
* TODO Manually control when raylib updates/draws
|
||||
* TODO Create basic vertical splits
|
||||
|
||||
* COMMENT Local variables
|
||||
;; Local Variables:
|
||||
;; eval: (olivetti-mode t)
|
||||
;; End:
|
||||
* TODO Create basic vertical splits?
|
Loading…
x
Reference in New Issue
Block a user