2020301918-os/kern/cmatrix.c
2022-10-02 12:54:35 +08:00

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
}
}
}