📄 kernel.c
字号:
#include "system.h"
#include "vesa.h"
#include "mouse.h"
#include "interrupt.h"
#include "io.h"
#include "message.h"
/******************************************************
* 声明部份 *
******************************************************/
enum kernel_kernel_state_enum{ KERNEL_WAIT_USER_LOGIN , KERNEL_USER_LOGED_IN , KERNEL_GAME } ;
void kernel_draw_login_form() ;
/******************************************************
* 数据定义部分 *
******************************************************/
static int kernel_mouse_x_position = 444 ;
static int kernel_mouse_y_position = 300 ;
static enum mouse_type_enum kernel_mouse_type = MOUSE_NORMAL_MOUSE ;
static enum kernel_kernel_state_enum kernel_kernel_state = KERNEL_WAIT_USER_LOGIN ;
struct message_message_queue_struct kernel_message_queue ;
static unsigned short *old_picture ;
static int old_picture_width ;
static int old_picture_height ;
static int application_picture_x ;
static int application_picture_y ;
static int game_picture_x ;
static int game_picture_y ;
/* 棋盘数据
** "空格" 表示没有
** - | 表示墙
** * 表示人
** o 表示球
** O 表示没有球的箱子
** Q 表示有球的箱子
*/
char chess[ 9 ][ 9 ] = {{ ' ' , ' ' , ' ' , '-' , '-' , '-' , ' ' , ' ' , ' '} ,
{ ' ' , ' ' , ' ' , '|' , 'o' , '|' , ' ' , ' ' , ' '} ,
{ ' ' , ' ' , ' ' , '|' , ' ' , '|' , ' ' , ' ' , ' '} ,
{ '-' , '-' , '-' , '|' , 'O' , '|' , '-' , '-' , '-'} ,
{ '|' , 'o' , ' ' , 'O' , '*' , 'O' , ' ' , 'o' , '|'} ,
{ '-' , '-' , '-' , '|' , 'O' , '|' , '-' , '-' , '-'} ,
{ ' ' , ' ' , ' ' , '|' , ' ' , '|' , ' ' , ' ' , ' '} ,
{ ' ' , ' ' , ' ' , '|' , 'o' , '|' , ' ' , ' ' , ' '} ,
{ ' ' , ' ' , ' ' , '-' , '-' , '-' , ' ' , ' ' , ' '} } ;
char bakchess[ 9 ][ 9 ] ;
/******************************************************
* 函数实现部份 *
******************************************************/
int tmp = 0;
// 得到棋盘图片地址函数
void *get_game_picture_addr( char chess )
{
switch( chess ){
case '-' :
case '|' :
return ( void * )0x45000 ;
case '*' :
return ( void * )0x47000 ;
case 'o' :
return ( void * )0x46000 ;
case 'O' :
return ( void * )0x43000 ;
case 'Q' :
return ( void * )0x44000 ;
}
}
/* 打印棋盘函数 */
void print_chess()
{
// 画新图
int x = game_picture_x + 32 ;
int y = game_picture_y + 16 + 32 ;
for( int j = 0 ; j < 9 ; ++j ){
for( int i = 0 ; i < 9 ; ++i ){
if( chess[ j ][ i ] == ' ' ){
// 打印一个白色矩型
unsigned short color = vesa_compond_rgb( 255 , 255 , 255 ) ;
vesa_draw_rect( x + i * 32 , y + j * 32 , x + i * 32 + 32 , y + j * 32 + 32 , color , 1 ) ;
}
else{
void *p = get_game_picture_addr( chess[ j ][ i ] ) ;
unsigned short mask_color = vesa_compond_rgb( 0 , 255 , 0 ) ; // 设置掩色
vesa_show_bmp_picture( x + i * 32 , y + j * 32 , p , mask_color , 1 ) ; // 启用掩色
}
}
}
}
// 画登陆界面
void kernel_draw_login_form() //0x90020
{
// 用白色清屏
unsigned short color = vesa_compond_rgb( 255 , 255 , 255 ) ;
vesa_clean_screen( color ) ;
// 显示第一幅图,所占矩形 ( 150 , 271 )-( 431 , 375 )
vesa_show_bmp_picture( 150 , 271 , ( void * )0x50000 , 0 , 0 ) ;
// 显示第二幅图
color = vesa_compond_rgb( 0 , 255 , 0 ) ;
vesa_show_bmp_picture( 457 , 225 , ( void * )0x60000 , color , 1 ) ;
// 显示 mouse
mouse_show_mouse( 444 , 300 , kernel_mouse_type ) ; //0x900a3
}
// 断定一个点是否在一个矩形之中
int kernel_does_point_in_rect( int x , int y , int x1 , int y1 , int x2 , int y2 )
{
if( x >= x1 && x <= x2 ){
if( y >= y1 && y <= y2 ){
return 1 ;
}
}
return 0 ;
}
// 完成用户登陆
void kernel_login()
{
// 进行系统登陆操作
// 用白色清屏
unsigned short color = vesa_compond_rgb( 255 , 255 , 255 ) ;
vesa_clean_screen( color ) ;
// 显示第二幅图做桌面
color = vesa_compond_rgb( 0 , 255 , 0 ) ;
vesa_show_bmp_picture( 606 , 400 , ( void * )0x60000 , color , 1 ) ;
application_picture_x = 10 ;
application_picture_y = 10 ;
// 保存应用程序地区原图片,供移动使用
vesa_copy_picture_from_screen( application_picture_x , application_picture_y , old_picture , 128 + 32 , 128 + 32 ) ; // 为原图长度加 mouse 长度
// 显示应用程序图标
color = vesa_compond_rgb( 0 , 255 , 0 ) ;
vesa_show_bmp_picture( application_picture_x , application_picture_x , ( void * )0x70000 , color , 1 ) ;
// 显示英文
// "PYOS MADE IN CHINA" ; // 18 个英文
color = vesa_compond_rgb( 0 , 0 , 255 ) ;
for( int i = 0 ; i < 18 ; ++i ){
vesa_print_english( 630 + i * 8 , 552 , i , color ) ;
}
// 画底边
color = vesa_compond_rgb( 187 , 250 , 131 ) ;
for( int i = 0 ; i < 30 ; i += 2 ){
vesa_draw_x_line( 570 + i , 0 , 799 , color ) ;
}
// 显示汉字
// "关机哈尔滨工业大学谢煜波" ; 12 个
// 先显示"关机"
color = vesa_compond_rgb( 255 , 0 , 255 ) ;
for( int i = 0 ; i < 2 ; ++i ){
vesa_print_chinese( 4 + i * 18 , 577 , i , color ) ;
}
// 再显示"哈尔滨工业大学"
color = vesa_compond_rgb( 0 , 0 , 255 ) ;
for( int i = 2 ; i < 9 ; ++i ){
vesa_print_chinese( 598 + ( i - 2 )* 18 , 577 , i , color ) ;
}
// 再显示"谢煜波"
for( int i = 9 ; i < 12 ; ++i ){
vesa_print_chinese( 742 + ( i - 9 ) * 18 , 577 , i , color ) ;
}
// 显示 mouse
mouse_show_mouse( 400 , 300 , MOUSE_NORMAL_MOUSE ) ;
// 恢复 mouse 指针
kernel_mouse_x_position = 400 ;
kernel_mouse_y_position = 300 ;
// 更改 mouse 状态
kernel_mouse_type = MOUSE_NORMAL_MOUSE ;
// 更改系统状态
kernel_kernel_state = KERNEL_USER_LOGED_IN ;
}
// 完成用户退出
void kernel_logout()
{
// 用白色清屏
unsigned short color = vesa_compond_rgb( 255 , 255 , 255 ) ;
vesa_clean_screen( color ) ;
// 显示退出图片( 246 * 103 )
vesa_show_bmp_picture( 277 , 248 , ( void * )0x20000 , 0 , 0 ) ;
// 关中断
interrupt_close_interrupt() ;
// 清空消息队列
message_init_message_queue( &kernel_message_queue ) ;
// 加入退出消息
struct message_message_struct message ;
message.message_type = MESSAGE_SHUTDOWN_COMPUTER ;
message_put_message( &kernel_message_queue , message ) ;
}
// 画游戏
void kernel_draw_game( int x , int y )
{
// 先恢复 mouse 中保存的图
mouse_restore_picture( kernel_mouse_x_position , kernel_mouse_y_position ) ;
// 画白色背景
unsigned short color = vesa_compond_rgb( 255 , 255 , 255 ) ;
vesa_draw_rect( x , y , x + 356 , y + 372 , color , 1 ) ;
// 画矩形框
color = vesa_compond_rgb( 0 , 0 , 255 ) ;
vesa_draw_rect( x , y , x + 356 , y + 372 , color , 0 ) ;
vesa_draw_rect( x + 1 , y + 1 , x + 356 - 1 , y + 372 - 1 , color , 0 ) ;
// 画顶
vesa_show_bmp_picture( x + 2 , y + 2 , ( void * )0x30400 , 0 , 0 ) ;
// 画棋盘图
print_chess() ;
// 显示 mouse , 因为可能在画棋盘时盖住了 mouse
mouse_show_mouse( kernel_mouse_x_position , kernel_mouse_y_position , kernel_mouse_type ) ;
}
// 启动游戏
void kernel_start_game()
{
game_picture_x = 222 ;
game_picture_y = 50 ;
// 保存 game 区原图片,供移动使用
vesa_copy_picture_from_screen( game_picture_x , game_picture_y , old_picture , 356 + 32 , 372 + 32 ) ;
kernel_kernel_state = KERNEL_GAME ;
// 画游戏
kernel_draw_game( game_picture_x , game_picture_y ) ;
}
// 关闭游戏
void close_game()
{
//重画桌面
kernel_login() ;
}
void game_handle( char ch )
{
static int x = 4 ;
static int y = 4 ;
if( ch == 'i' ){ // i 键,向上走
if( chess[ x - 1 ][ y ] == '|' || chess[ x - 1 ][ y ] == '-' || chess[ x - 1 ][ y ] == 'Q' ){
// 如果上方是墙,或有球的箱子,则不能通过,直接返回
return ;
}
else{
// 可以移动
// 把老地方置空
chess[ x ][ y ] = ' ' ;
// 检测人欲移到的位置现在是不是一个箱子
if( chess[ x - 1 ][ y ] == 'O' ){
// 是一个箱子,则把箱子移动一下
// 检测箱子移动到的地方是不是球
if( chess[ x - 2 ][ y ] == 'o' ){
// 是球,则把此地作为有球的箱子
chess[ x - 2 ][ y ] = 'Q' ;
}
else{
// 不是球,则把此地作为箱子
chess[ x - 2 ][ y ] = 'O' ;
}
}
// 人向上走一格
--x ; // 因为,x 是行,
chess[ x ][ y ] = '*' ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -