Extract rendering function out and render a few lines

This commit is contained in:
Joseph Ferano 2023-11-11 17:25:57 +07:00
parent 177f73f78a
commit 8117e9250a
2 changed files with 143 additions and 125 deletions

242
bt.c
View File

@ -16,6 +16,7 @@
const int SCREEN_WIDTH = 900; const int SCREEN_WIDTH = 900;
const int SCREEN_HEIGHT = 700; const int SCREEN_HEIGHT = 700;
const int SCROLLBACK_DEFAULT_SIZE = 4096;
const SDL_Color WHITE = {255, 255, 255, 255}; const SDL_Color WHITE = {255, 255, 255, 255};
const SDL_Color BLACK = {0, 0, 0, 255}; const SDL_Color BLACK = {0, 0, 0, 255};
const SDL_Color RED = {255, 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 SKYBLUE = {0, 255, 255, 255};
const SDL_Color RAYWHITE = {200, 200, 200, 255}; const SDL_Color RAYWHITE = {200, 200, 200, 255};
typedef struct scrollback { typedef struct {
float height; float height;
float ypos; float ypos;
int capacity; int capacity;
int length; int length;
char *buf; char *buf;
} scrollback; } Scrollback;
typedef struct file_descriptors { typedef struct {
int master; int master;
int child; 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); openpty(&fds->master, &fds->child, NULL, NULL, NULL);
pid_t p = fork(); pid_t p = fork();
if (p == 0) { 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; ssize_t nread;
char readbuf[256]; char readbuf[256];
switch (nread = read(fds->master, readbuf, sizeof(readbuf))) { 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) { int main(void) {
scrollback sb = { 0 }; Scrollback sb = { 0 };
file_descriptors fds = { 0 }; FileDescriptors fds = { 0 };
spawn(&fds); spawn(&fds);
@ -94,10 +207,11 @@ int main(void) {
printf("error initializing SDL: %s\n", SDL_GetError()); printf("error initializing SDL: %s\n", SDL_GetError());
return 1; return 1;
} }
int start_x = 20;
int start_y = 20;
SDL_Window* window = SDL_CreateWindow("bt", SDL_Window* window = SDL_CreateWindow("bt",
SDL_WINDOWPOS_UNDEFINED, start_x,
SDL_WINDOWPOS_UNDEFINED, start_y,
SCREEN_WIDTH, SCREEN_WIDTH,
SCREEN_HEIGHT, SCREEN_HEIGHT,
SDL_WINDOW_SHOWN); SDL_WINDOW_SHOWN);
@ -107,7 +221,7 @@ int main(void) {
} }
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); 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_Init();
TTF_Font* font = TTF_OpenFont( "./fira.ttf", 16); 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 // TODO: It would be nice to figure out how to do this in SDL
// SetTargetFPS(60); // SetTargetFPS(60);
sb.capacity = 2048; sb.capacity = SCROLLBACK_DEFAULT_SIZE;
sb.buf = malloc(sb.capacity); sb.buf = malloc(sb.capacity);
sb.buf[0] = '\0'; sb.buf[0] = '\0';
sb.length = 0; sb.length = 0;
@ -136,6 +250,11 @@ int main(void) {
sb.ypos = 0; sb.ypos = 0;
Context ctx = {
.sb = &sb,
.font = font,
.renderer = renderer
};
bool new_read = false; bool new_read = false;
bool new_char = false; bool new_char = false;
SDL_Event e; SDL_Event e;
@ -203,108 +322,13 @@ int main(void) {
} }
// Drawing
int nread = read_pty(&fds, &sb); int nread = read_pty(&fds, &sb);
if (nread > 0) { if (nread > 0) {
sb.length += nread; sb.length += nread;
new_read = true; 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 render_scrollback(&ctx);
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);
} }
free(sb.buf); free(sb.buf);

View File

@ -1,8 +1,7 @@
#-*- mode: org -*- #-*- mode: org -*-
#+TODO: BLOCKED TODO INPROGRESS | DONE BACKLOG #+TODO: TODO | DONE
#+STARTUP: overview #+STARTUP: overview
* DONE Render with Raylib * DONE Render with Raylib
* DONE Load custom Mono font * DONE Load custom Mono font
* DONE Render input from user * DONE Render input from user
@ -12,17 +11,12 @@
* DONE Auto-scrolling * DONE Auto-scrolling
* DONE Render scrollback by rows * DONE Render scrollback by rows
* DONE Handle color escape sequences * DONE Handle color escape sequences
* TODO Backspace and Return aren't repeating [[https://github.com/raysan5/raylib/issues/2041][Issue Here]] * DONE Switch to SDL2
* TODO 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 Only draw scrollback that is visible
* TODO Improve the scrolling to match first and last lines
* TODO Handle unicode characters * TODO Handle unicode characters
* TODO Handle canonical and raw commands * TODO Handle canonical and raw commands
* TODO Mouse copy/paste * TODO Mouse copy/paste
* TODO Manually control when raylib updates/draws * TODO Create basic vertical splits?
* TODO Create basic vertical splits
* COMMENT Local variables
;; Local Variables:
;; eval: (olivetti-mode t)
;; End: