/* 屏幕向上滚动 函数不检查状态变化的合法性,是否处于可滚动状态由调用者判断 因此,此函数不要直接调用 */ static void erase_upward_console_screen(unsigned int new_line_idx/*, bool rolling_one_line*/) { unsigned int new_line = new_line_idx; unsigned int erased_line = dsp_ctx.window.topline; unsigned int erased_pos_x = 0; unsigned int erased_pos_y = 0; unsigned int new_pos_x = 0; unsigned int new_pos_y = 0; unsigned int count, erased_count; int i; reset_up_idx(); dsp_ctx.window.topline = new_line; while(1) { dsp_ctx.color = BLACK_PIX; erased_count = draw_a_line(&erased_pos_x, &erased_pos_y, erased_line, dsp_ctx.buffer.lastchar); /* 向屏幕打印替代的行 */ if (new_line != dsp_ctx.buffer.lastchar) { dsp_ctx.color = WHITE_PIX; count = draw_a_line(&new_pos_x, &new_pos_y, new_line, dsp_ctx.buffer.lastchar); dsp_ctx.window.lastchar = get_buf_idx(new_line + count); new_line = get_buf_idx(new_line + count); if ( new_line == dsp_ctx.buffer.lastchar) { dsp_ctx.window.downward = 0; } else { modify_up_idx(new_pos_x, new_pos_y); } } /* 屏幕刷新完毕 */ if (erased_pos_y >= dsp_ctx.max_y - 20) break; erased_line = get_buf_idx(erased_line + erased_count); } /* 维护相关数据 */ dsp_ctx.window.pos_x = new_pos_x; dsp_ctx.window.pos_y = new_pos_y; dsp_ctx.color = WHITE_PIX; return; }
void hal_console_init(void) { video_console_ops.write = write_string; dsp_ctx.window.topline = 2 * sizeof(unsigned int); dsp_ctx.window.pos_x = 0; dsp_ctx.window.pos_y = 0; dsp_ctx.window.lastchar = 2 * sizeof(unsigned int); dsp_ctx.window.downward = 0; dsp_ctx.window.step[0] = -1; dsp_ctx.window.step[1] = -1; /* fix me 目前仅静态分配 */ memset(&dsp_ctx.buffer.buf, 0, CONSOLE_BUFFER_SIZE); dsp_ctx.color = WHITE_PIX; dsp_ctx.buffer.topline = 2 * sizeof(unsigned int); dsp_ctx.buffer.lastchar = 2 * sizeof(unsigned int); /* */ dsp_ctx.buffer.tail_line = 2 * sizeof(unsigned int); reset_up_idx(); /* Init the global lock */ spin_lock_init(&dsp_ctx.lock); /* 取分辨率 */ get_screen_resolution(&dsp_ctx.max_x, &dsp_ctx.max_y, NULL); console_cursor_setup(); console_cursor_set_height(DOTFNT_CHAR_LINE_HEIGHT); return; }
/** @brief 接口,分辨率变更处理函数, 环境不足,因此目前未测试 @width[in] @height[in] @return void */ void modify_screen_resolution(unsigned long width, unsigned long height) { int count = 0; /* 重绘屏幕 且屏幕首行保持不变 */ dsp_ctx.max_x = width; dsp_ctx.max_y = height; dsp_ctx.window.pos_x = 0; dsp_ctx.window.pos_y = 0; reset_up_idx(); dsp_ctx.window.lastchar = get_buf_idx(dsp_ctx.window.topline); while (1) { /* 屏幕满,向上滚动 */ if (dsp_ctx.window.pos_y >= dsp_ctx.max_y - 20) { break; } if (dsp_ctx.window.lastchar == dsp_ctx.buffer.lastchar) { dsp_ctx.window.downward = 0; break; } else { /*打印一行(指屏幕)数据,或者不足一行时打印到缓存最后一个字符 count为本次处理的字节数 */ count = draw_a_line(&dsp_ctx.window.pos_x, &dsp_ctx.window.pos_y, dsp_ctx.window.lastchar, dsp_ctx.buffer.lastchar); /* 更新窗口的状态 */ dsp_ctx.window.lastchar = get_buf_idx(dsp_ctx.window.lastchar + count); modify_up_idx(dsp_ctx.window.pos_x, dsp_ctx.window.pos_y); } } return; }
/* 屏幕向下滚动 注意,此函数不是接口,实现这个功能还需要在外面包一层 目前接口还未实现,因为目前还不具备所需的条件 */ static void erase_dnward_console_screen(int step) { int pos_x, pos_y; int i; unsigned long newline, erased_line; unsigned long erased_count, count; int erased_pos_x = 0; int erased_pos_y = 0; int new_pos_x = 0; int new_pos_y = 0; /* 当前已经是第一行,直接退出 */ if (dsp_ctx.window.topline == dsp_ctx.buffer.topline) { return; } reset_up_idx(); erased_line = dsp_ctx.window.topline; /* 定位屏幕应输出的第一行 */ newline = erased_line; for (i = 0; i < step; i++) { newline = prev_line_in_buffer(newline); if (newline == dsp_ctx.buffer.topline) break; } dsp_ctx.window.topline = newline; /* 刷新屏幕,每次循环刷新一行 从屏幕左上角开始刷新 */ while (1) { if (erased_line != dsp_ctx.buffer.lastchar) { dsp_ctx.color = BLACK_PIX; /* 用黑色重写本行,即擦除本行 */ erased_count = draw_a_line(&erased_pos_x, &erased_pos_y, erased_line, dsp_ctx.buffer.lastchar); erased_line = get_buf_idx(erased_line + erased_count); } /* 向屏幕打印需输出的行 */ dsp_ctx.color = WHITE_PIX; count = draw_a_line(&new_pos_x, &new_pos_y, newline, dsp_ctx.buffer.lastchar); dsp_ctx.window.lastchar = get_buf_idx(newline + count); newline = get_buf_idx(newline + count); /* 新数据已经输出到缓存末尾 */ if (newline == dsp_ctx.buffer.lastchar) break; modify_up_idx(new_pos_x, new_pos_y); /* 已打印满一屏 */ if (new_pos_y >= (dsp_ctx.max_y - 20)) break; } dsp_ctx.window.downward = 1; dsp_ctx.window.pos_x = new_pos_x; dsp_ctx.window.pos_y = new_pos_y; dsp_ctx.color = WHITE_PIX; return; }