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:
parent
09c01eb2c5
commit
3a5fda0d9c
50
userspace/cp.c
Normal file
50
userspace/cp.c
Normal 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
|
||||
*/
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user