Super fast terminal scrolling.

* Uses memmove to shift terminal cells and graphics memory.
* Can cat cat super-fast!

Verified in windowed, fullscreen, and VGA modes.

[ci skip]
This commit is contained in:
Kevin Lange 2012-09-10 23:42:45 -07:00
parent 09c01eb2c5
commit 3a5fda0d9c
2 changed files with 74 additions and 6 deletions

50
userspace/cp.c Normal file
View File

@ -0,0 +1,50 @@
/*
* cp
*/
#include <stdio.h>
#define CHUNK_SIZE 4096
int main(int argc, char ** argv) {
FILE * fd;
FILE * fout;
if (argc < 3) {
fprintf(stderr, "usage: %s [source] [destination]\n", argv[0]);
return 1;
}
fd = fopen(argv[1], "r");
if (!fd) {
fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], argv[1]);
return 1;
}
fout = fopen(argv[2], "w");
size_t length;
fseek(fd, 0, SEEK_END);
length = ftell(fd);
fseek(fd, 0, SEEK_SET);
char buf[CHUNK_SIZE];
while (length > CHUNK_SIZE) {
fread( buf, 1, CHUNK_SIZE, fd);
fwrite(buf, 1, CHUNK_SIZE, fout);
length -= CHUNK_SIZE;
}
if (length > 0) {
fread( buf, 1, length, fd);
fwrite(buf, 1, length, fout);
}
fclose(fd);
fclose(fout);
return 0;
}
/*
* vim:tabstop=4
* vim:noexpandtab
* vim:shiftwidth=4
*/

View File

@ -800,15 +800,33 @@ void term_redraw_all() {
}
void term_term_scroll() {
for (uint16_t y = 0; y < term_height - 1; ++y) {
for (uint16_t x = 0; x < term_width; ++x) {
cell_set(x,y,cell_ch(x,y+1),cell_fg(x,y+1),cell_bg(x,y+1), cell_flags(x,y+1));
}
}
for (uint16_t x = 0; x < term_width; ++x) {
cell_set(x, term_height-1,' ',current_fg, current_bg,0);
}
/* Shirt terminal cells one row up */
memmove(term_buffer, (void *)((uintptr_t)term_buffer + sizeof(t_cell) * term_width), sizeof(t_cell) * term_width * (term_height - 1));
/* Reset the "new" row to clean cells */
memset((void *)((uintptr_t)term_buffer + sizeof(t_cell) * term_width * (term_height - 1)), 0x0, sizeof(t_cell) * term_width);
if (_vga_mode) {
/* In VGA mode, we can very quickly just redraw everything */
term_redraw_all();
} else {
/* In graphical modes, we will shift the graphics buffer up as necessary */
uintptr_t dst, src;
size_t siz = char_height * (term_height - 1) * GFX_W(ctx) * GFX_B(ctx);
if (_windowed) {
/* Windowed mode must take borders into account */
dst = (uintptr_t)ctx->backbuffer + (GFX_W(ctx) * decor_top_height) * GFX_B(ctx);
src = (uintptr_t)ctx->backbuffer + (GFX_W(ctx) * (decor_top_height + char_height)) * GFX_B(ctx);
} else {
/* While fullscreen mode does not */
dst = (uintptr_t)ctx->backbuffer;
src = (uintptr_t)ctx->backbuffer + (GFX_W(ctx) * char_height) * GFX_B(ctx);
}
/* Perform the shift */
memmove((void *)dst, (void *)src, siz);
/* And redraw the new rows */
for (uint16_t x = 0; x < term_width; ++x) {
cell_redraw(x, term_height - 1);
}
}
}
uint32_t codepoint;