203 lines
4.8 KiB
C
203 lines
4.8 KiB
C
#include "type.h"
|
|
#include "cmatrix.h"
|
|
#include "terminal.h"
|
|
|
|
static size_t random_seed = 114;
|
|
static size_t
|
|
rand() {
|
|
return ( ((random_seed = random_seed * 214013L
|
|
+ 2531011L) >> 16) & 0x7fff );
|
|
}
|
|
|
|
struct cmatrix_node {
|
|
u8 row;
|
|
u8 character;
|
|
struct cmatrix_node *pre;
|
|
struct cmatrix_node *nxt;
|
|
};
|
|
|
|
struct cmatrix_info {
|
|
u8 column;
|
|
u8 max_length;
|
|
u8 now_length;
|
|
struct cmatrix_node *head;
|
|
struct cmatrix_node *tail;
|
|
};
|
|
|
|
typedef struct cmatrix_node cm_node;
|
|
typedef struct cmatrix_info cm_info;
|
|
|
|
#define NODE_POOL_SIZE ((TERMINAL_ROW) * (TERMINAL_COLUMN))
|
|
static cm_node node_pool[NODE_POOL_SIZE];
|
|
|
|
static cm_node*
|
|
alloc_node()
|
|
{
|
|
for (int i = 0; i < NODE_POOL_SIZE; i++)
|
|
if (node_pool[i].character == 0)
|
|
return &node_pool[i];
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
free_node(cm_node *node_ptr)
|
|
{
|
|
node_ptr -> row = 0;
|
|
node_ptr -> character = 0;
|
|
if (node_ptr -> pre != NULL) {
|
|
node_ptr -> pre -> nxt = NULL;
|
|
node_ptr -> pre = NULL;
|
|
}
|
|
if (node_ptr -> nxt != NULL) {
|
|
node_ptr -> nxt -> pre = NULL;
|
|
node_ptr -> nxt = NULL;
|
|
}
|
|
}
|
|
|
|
#define INFO_POOL_SIZE (TERMINAL_COLUMN)
|
|
static cm_info info_pool[INFO_POOL_SIZE];
|
|
|
|
static const u8 char_pool[] = {
|
|
'a','b','c','d','e','f','g','h','i','j','k','l','m',
|
|
'n','o','p','q','r','s','t','u','v','w','x','y','z',
|
|
'A','B','C','D','E','F','G','H','I','J','K','L','M',
|
|
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
|
'!','@','#','$','^','&','*','(',')','{','}','[',']',
|
|
'|','?','/',':',';','`','~','>','<',',','.','%','-',
|
|
'_','+','=','0','1','2','3','4','5','6','7','8','9',
|
|
};
|
|
|
|
static void
|
|
init_info(cm_info *info_ptr)
|
|
{
|
|
info_ptr -> max_length = rand() % (TERMINAL_ROW - 1) + 1;
|
|
info_ptr -> head = info_ptr -> tail = NULL;
|
|
}
|
|
|
|
static void
|
|
expand_info(cm_info *info_ptr)
|
|
{
|
|
u8 character = char_pool[rand() % ARRAY_SIZE(char_pool)];
|
|
|
|
if (info_ptr -> head == NULL) {
|
|
cm_node node = {
|
|
.row = 0,
|
|
.character = character,
|
|
.pre = NULL,
|
|
.nxt = NULL,
|
|
};
|
|
cm_node *node_ptr = alloc_node();
|
|
*node_ptr = node;
|
|
// 修改info
|
|
info_ptr -> head = node_ptr;
|
|
info_ptr -> tail = node_ptr;
|
|
info_ptr -> now_length++;
|
|
// 打印字符
|
|
#ifdef TESTS
|
|
struct color_char black_green = {
|
|
.background = BLACK,
|
|
.foreground = GREEN,
|
|
.print_char = info_ptr -> head -> character,
|
|
.print_pos = TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column)
|
|
};
|
|
kprintf(0, "%s", black_green);
|
|
#else
|
|
kprintf(TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column),
|
|
"%b%c", GREEN, info_ptr -> head -> character);
|
|
#endif
|
|
|
|
} else if (info_ptr -> head -> row < TERMINAL_ROW - 1) {
|
|
cm_node node = {
|
|
.row = info_ptr -> head -> row + 1,
|
|
.character = character,
|
|
.pre = NULL,
|
|
.nxt = info_ptr -> head,
|
|
};
|
|
cm_node *node_ptr = alloc_node();
|
|
*node_ptr = node;
|
|
// 打印字符
|
|
#ifdef TESTS
|
|
struct color_char black_green = {
|
|
.background = BLACK,
|
|
.foreground = GREEN,
|
|
.print_char = info_ptr -> head -> character,
|
|
.print_pos = TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column)
|
|
};
|
|
kprintf(0, "%s", black_green);
|
|
#else
|
|
kprintf(TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column),
|
|
"%f%c", GREEN, info_ptr -> head -> character);
|
|
#endif
|
|
// 修改info
|
|
info_ptr -> head -> pre = node_ptr;
|
|
info_ptr -> head = node_ptr;
|
|
info_ptr -> now_length++;
|
|
// 打印字符
|
|
#ifdef TESTS
|
|
struct color_char green_white = {
|
|
.background = GREEN,
|
|
.foreground = WHITE,
|
|
.print_char = info_ptr -> head -> character,
|
|
.print_pos = TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column)
|
|
};
|
|
kprintf(0, "%s", green_white);
|
|
#else
|
|
kprintf(TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column),
|
|
"%b%c", GREEN, info_ptr -> head -> character);
|
|
#endif
|
|
} else {
|
|
// 打印字符
|
|
#ifdef TESTS
|
|
struct color_char black_green = {
|
|
.background = BLACK,
|
|
.foreground = GREEN,
|
|
.print_char = info_ptr -> head -> character,
|
|
.print_pos = TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column)
|
|
};
|
|
kprintf(0, "%s", black_green);
|
|
#else
|
|
kprintf(TERMINAL_POS(info_ptr -> head -> row,
|
|
info_ptr -> column),
|
|
"%f%c", GREEN, info_ptr -> head -> character);
|
|
#endif
|
|
}
|
|
|
|
if (info_ptr -> now_length > info_ptr -> max_length
|
|
|| info_ptr -> head -> row == TERMINAL_ROW - 1) {
|
|
cm_node *node_ptr = info_ptr -> tail;
|
|
// 打印字符
|
|
kprintf(TERMINAL_POS(info_ptr -> tail -> row, info_ptr -> column),
|
|
"%c", ' ');
|
|
// 修改info
|
|
info_ptr -> tail = info_ptr -> tail -> pre;
|
|
info_ptr -> now_length--;
|
|
// 释放内存
|
|
free_node(node_ptr);
|
|
}
|
|
}
|
|
|
|
void
|
|
cmatrix_start()
|
|
{
|
|
clear_screen();
|
|
for (int i = 0; i < TERMINAL_COLUMN; i++)
|
|
info_pool[i].column = i;
|
|
while(1) {
|
|
for (int i = 0; i < TERMINAL_COLUMN; i++) {
|
|
cm_info *info_ptr = &info_pool[i];
|
|
if (info_ptr -> now_length == 0)
|
|
init_info(info_ptr);
|
|
expand_info(info_ptr);
|
|
}
|
|
for (int i = 0; i < 1e7; i++) {
|
|
// do nothing
|
|
}
|
|
}
|
|
} |