⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 singlesnake.c

📁 a efi snake game
💻 C
字号:
#include "efi.h"
#include "efilib.h"
#include"she.h"
#include "Bmp\Bmp.h"
#include "Hii\Hii.h"
#include"ConsoleControl\ConsoleControl.h"
#define Out  ST->ConOut
#define In   ST->ConIn
#define SCAN_CODE_UP    0x01
#define SCAN_CODE_DOWN  0x02
#define SCAN_CODE_RIGHT 0x03
#define SCAN_CODE_LEFT  0x04
#define SCAN_CODE_ESC   0x17
#define N 200

//EFI_GUID  gEfiHiiProtocolGuid = EFI_HII_PROTOCOL_GUID;
EFI_GUID  gEfiUgaDrawProtocolGuid = EFI_UGA_DRAW_PROTOCOL_GUID;
EFI_GUID gEfiConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
EFI_UGA_DRAW_PROTOCOL                 *UgaDraw;
EFI_CONSOLE_CONTROL_PROTOCOL          *ConsoleControl;
EFI_HII_PROTOCOL                      *mHii; 
static EFI_UGA_PIXEL        EfiColors[16] = {

  0x00, 0x00, 0x00, 0x00,  // BLACK
  0x98, 0x00, 0x00, 0x00,  // BLUE
  0x00, 0x98, 0x00, 0x00,  // GREEN
  0x98, 0x98, 0x00, 0x00,  // CYAN
  0x00, 0x00, 0x98, 0x00,  // RED
  0x98, 0x00, 0x98, 0x00,  // MAGENTA
  0x00, 0x98, 0x98, 0x00,  // BROWN
  0x98, 0x98, 0x98, 0x00,  // LIGHTGRAY
  0x30, 0x30, 0x30, 0x00,  // DARKGRAY - BRIGHT BLACK
  0xff, 0x00, 0x00, 0x00,  // LIGHTBLUE - ?
  0x00, 0xff, 0x00, 0x00,  // LIGHTGREEN - ?
  0xff, 0xff, 0x00, 0x00,  // LIGHTCYAN
  0x00, 0x00, 0xff, 0x00,  // LIGHTRED
  0xff, 0x00, 0xff, 0x00,  // LIGHTMAGENTA
  0x00, 0xff, 0xff, 0x00,  // LIGHTBROWN
  0xff, 0xff, 0xff, 0x00,  // WHITE
};


UINTN Node;
EFI_INPUT_KEY Key;
UINTN Score=0;
UINT8 Barrier=1;
UINTN Gamespeed=100000;
struct Food
{
INTN x;
 INTN  y;
 UINTN  yes;
}food;

struct Snake
{
 INTN x[N];
 INTN y[N];
 UINTN node;
 UINTN direction;
 UINTN life;
}snake;

  
VOID 
DrawData(
IN UINT8               *ImageBuffer,
IN      UINTN                 Col,
IN   UINTN                    Row
);

EFI_STATUS
DrawWord(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable,
IN CHAR16 *Value,
IN UINT16 X,
IN UINT16 Y,
IN UINT16   Background,
IN UINT16 WordCount
);

UINT8
Rand(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
Init(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
   );
EFI_STATUS
DrawK(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
VOID
PrintScore(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable)
{   
	CHAR16 Str1[50];
	UINT8  Count1;
	ValueToString(Str1,0,Score);
	Count1=(UINT8)StrLen(Str1);
	DrawWord(ImageHandle,SystemTable,Str1,160,65,3,Count1);
	return;
}
VOID
GameOver(VOID);

EFI_STATUS
GamePlay(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);

Main(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{  
	UINT8     Count,Countsize;

	UINTN      i,j,k;
	CHAR16   *Str=L"Start Load";
	CHAR16   *Str2=L"JJDD";
	Count=11;
	if(Barrier==1)
	{
	Init(ImageHandle,SystemTable);
	ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
	UgaDraw->Blt(UgaDraw,  &EfiColors[0], EfiUgaVideoFill,0,0,0,0,800,600,0);
    DrawData(sheData,350,250); 
	DrawWord(ImageHandle,SystemTable,Str,340,520,0,Count);
	k=0;
	for(j=0;j<14;j++)
	{
	for(i=0;i<6;i++)
		{
    UgaDraw->Blt(UgaDraw,&EfiColors[15], EfiUgaVideoFill,0,0,k,565,8,16,0);
	k=k+9;
		}
	BS->Stall(500000);
	}
	}
	DrawK(ImageHandle,SystemTable);	
	if(Barrier==1)
	Str2=L"The First Barrier" ;
	else if(Barrier==2)
		Str2=L"The Second Barrier" ;
	else if(Barrier==3)
		Str2=L"The Third Barrier" ;
    Countsize=(UINT8)StrLen(Str2);

	DrawWord(ImageHandle,SystemTable,Str2,300,45,3,Countsize);
	GamePlay(ImageHandle,SystemTable);
	ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText);
	return EFI_SUCCESS;
}

EFI_STATUS
Init(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{  
       EFI_HANDLE  Handle;
       UINTN       Size;
       EFI_STATUS  Status;
     
      UINTN                       UgaDrawProtocolCount;
      EFI_HANDLE                  *UgaDrawHandles;
      ConsoleControl = NULL;
	  InitializeLib(ImageHandle,SystemTable);
	  Size = sizeof (EFI_HANDLE);
      Status = BS->LocateHandle (
                  ByProtocol,
                  &gEfiHiiProtocolGuid,
                  NULL,
                  &Size,
                  &Handle
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = BS->HandleProtocol (
                  Handle,
                  &gEfiHiiProtocolGuid,
                  &mHii
);	
 Status = BS->LocateProtocol (
               &gEfiConsoleControlProtocolGuid,
               NULL,
                 (VOID **)&ConsoleControl
                 );
if(EFI_ERROR(Status))
	{
	Print(L"error");
	}
	Status=LibLocateHandle (
            ByProtocol,
            &gEfiUgaDrawProtocolGuid, 
            NULL, 
            &UgaDrawProtocolCount,
            &UgaDrawHandles
            );
	if(EFI_ERROR(Status))
	{
	Print(L"error");
	}
   BS->HandleProtocol (
                UgaDrawHandles[0],
                &gEfiUgaDrawProtocolGuid,
                &UgaDraw
                );
   return EFI_SUCCESS;
}

EFI_STATUS
DrawK(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{    
	  CHAR16 *Value=L"SCORE:";
	  UINT16                    Count,i=100,j;
      UINT16                    GlyphWidth=19;
      UINT32                    GlyphStatus=0;
      UINT8                     *Glyph;      
      EFI_UGA_PIXEL              *Buffer;
	  EFI_STATUS                  Status;
	InitializeLib(ImageHandle,SystemTable);
	  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);
      UgaDraw->Blt(UgaDraw,  &EfiColors[0], EfiUgaVideoFill,0,0,0,0,800,600,0);
	  UgaDraw->Blt(UgaDraw,  &EfiColors[3], EfiUgaVideoFill,0,0,0,0,800,100,0);
	  UgaDraw->Blt(UgaDraw,  &EfiColors[3], EfiUgaVideoFill,0,0,0,500,800,100,0);
	  UgaDraw->Blt(UgaDraw,  &EfiColors[3], EfiUgaVideoFill,0,0,0,0,100,600,0);
      UgaDraw->Blt(UgaDraw,  &EfiColors[3], EfiUgaVideoFill,0,0,700,0,100,600,0);
 for(j=0;j<7;j++)
	{
	 Count=0;
     Status= mHii->GetGlyph(mHii,&Value[j],&Count,&Glyph, &GlyphWidth,&GlyphStatus);
     Buffer = AllocateZeroPool (8*19* sizeof (EFI_UGA_PIXEL));
	  Status=mHii->GlyphToBlt( mHii, Glyph, EfiColors[15],EfiColors[5],1,8,19, Buffer);
              
    Status=UgaDraw->Blt(
		    UgaDraw, Buffer,
            EfiUgaBltBufferToVideo,
            0, 0,
            i,65,
            8,19, 0
            );  
	i=i+8;
	}
   return EFI_SUCCESS;           
}

UINT8
Rand(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{   
    UINT8          ValueTime;
	EFI_TIME       Time;
	EFI_STATUS     Status;

  // EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
	Status=RT->GetTime(&Time,NULL);
	if(EFI_ERROR(Status))
	{
		Print(L"error");
		return EFI_SUCCESS;
	}
 ValueTime=Time.Second;
 return ValueTime;
}


EFI_STATUS
GamePlay(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
	
	EFI_STATUS Status;
	UINT8    flag;
	food.yes=1;//需要出现食物
	snake.life=0;//活着
	snake.direction=1;//方向向右
	snake.x[0]=110;//蛇头
	snake.y[0]=110;//
	snake.x[1]=120;//
	snake.y[1]=110;//
	snake.node=2;//蛇的节点数
	PrintScore(ImageHandle,SystemTable);
	flag=0;
	
	while(1)
	{  
        Status= In->ReadKeyStroke(In,&Key);
		while(Status==EFI_NOT_READY)//在没有按键的情况下蛇自己移动
		{ 
			Status= In->ReadKeyStroke(In,&Key);
			if(food.yes==1)//需要出现新食物
			{
				food.x=Rand(ImageHandle,SystemTable)*10+100;
				food.y=Rand(ImageHandle,SystemTable)*6+110;
				while(food.x%10!=0)
					food.x++;
				while(food.y%10!=0)
					food.y++;
				food.yes=0;
			}
			if(food.yes==0);//画面上有食物就要显示
			{
			
			UgaDraw->Blt(UgaDraw,&EfiColors[4], EfiUgaVideoFill,0,0,food.x,food.y,10,10,0);
			}

			for(Node=snake.node-1;Node>0;Node--)
			{
				snake.x[Node]=snake.x[Node-1];
				snake.y[Node]=snake.y[Node-1];
			}
			switch(snake.direction)
			{
				case 1:snake.x[0]+=10;break;//右
				case 2:snake.x[0]-=10;break;//左
				case 3:snake.y[0]-=10;break;//上
				case 4:snake.y[0]+=10;break;//下
			}
			
			for(Node=3;Node<snake.node;Node++)//从蛇的第四节开始判断是否撞到了自己,蛇头为二节,第三节不可能拐过来
			{
				if(snake.x[Node]==snake.x[0]&&snake.y[Node]==snake.y[0])
				{
					GameOver();
					snake.life=1;
					break;
				}
			}

			if(snake.x[0]<100||snake.x[0]>690||snake.y[0]<100||snake.y[0]>490)
			{
				GameOver();
				snake.life=1;
			}
			if(snake.life==1)
				break;
			if(snake.x[0]==food.x&&snake.y[0]==food.y)//吃到食物
			{
			  
				UgaDraw->Blt(UgaDraw,&EfiColors[0], EfiUgaVideoFill,0,0,food.x,food.y,10,10,0);//把食物去掉
				
				snake.x[snake.node]=-20;//jacke
				snake.y[snake.node]=-20;//jacke
				food.yes=1;
				snake.node++;
				Score+=10;
				if(Score==100)
			       {
					Barrier=2;
					Main(ImageHandle,SystemTable);
					return EFI_SUCCESS;
				   }

				else if(Score==200)
					   {
					Barrier=3;
					Main(ImageHandle,SystemTable);
					return EFI_SUCCESS;
					   }
					 else if(Score==400)
				{
						  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText); 
						  Print(L"You Win");
						  return EFI_SUCCESS;
				}
			PrintScore(ImageHandle,SystemTable);	
			}
			 for(Node=0;Node<snake.node;Node++)//花出蛇
	         UgaDraw->Blt(UgaDraw,&EfiColors[2], EfiUgaVideoFill,0,0,snake.x[Node],snake.y[Node],10,10,0);
		     BS->Stall(Gamespeed);
			//用黑色去除蛇的最后一节
			UgaDraw->Blt(UgaDraw,&EfiColors[0], EfiUgaVideoFill,0,0,snake.x[Node-1],snake.y[Node-1],10,10,0);
		}//结束(In->ReadKeyStroke(In,&Key)
		  
			if(snake.life==1)
				break;
		 // flag=1;
		//	WaitForSingleEvent(In->WaitForKey,0);
		//	Status=In->ReadKeyStroke(In, &Key);//接受按键
			if(Key.ScanCode==SCAN_CODE_ESC)
				goto Done;
	   	else if(Key.ScanCode==SCAN_CODE_UP&&snake.direction!=4)
			snake.direction=3;
		else if(Key.ScanCode==SCAN_CODE_RIGHT&&snake.direction!=2)
			snake.direction=1;
		else if(Key.ScanCode==SCAN_CODE_LEFT&&snake.direction!=1)
		{
			snake.direction=2;

            
		}
		else if(Key.ScanCode==SCAN_CODE_DOWN&&snake.direction!=3)
		{
			// Str1=L"JAKD";
			snake.direction=4;
		}
       
              }//结束while(1);
	 Done:  
		 GameOver();
		 return EFI_SUCCESS;
		
		}

		    VOID 
			GameOver(VOID)
			
		   {
		   ConsoleControl->SetMode(ConsoleControl,EfiConsoleControlScreenText);
		   Out->ClearScreen(Out);
		   PrintAt(1,0,L"Game Over");
		   return;
		};

VOID 
DrawData(
//IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
IN UINT8               *ImageBuffer,
IN      UINTN                 Col,
IN   UINTN                    Row
)
{
  
  BMP_IMAGE_HEADER        *BmpHeader;
  UINTN                   Height, Width;
  EFI_UGA_PIXEL           *BltBuffer, *Blt;
  UINT8                   *Image;
  UINT32                 SizeOfX, SizeOfY,ImageIndex;         
  UINT32                  ColorDepth;
  UINT32                  RefreshRate;       
  UINT32                  BltBufferSize;
  BmpHeader = (BMP_IMAGE_HEADER *)ImageBuffer;
  Image = ImageBuffer + BmpHeader->ImageOffset;
  BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight;
  BltBuffer = AllocateZeroPool (BltBufferSize * sizeof (EFI_UGA_PIXEL));
  if (BltBuffer == NULL) 
	  {
    Print (L"UgaDraw: Out of memory for Blt Buffer\n");
    goto Done;
  }

UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
        Blt->Blue = *Image++;
        Blt->Green = *Image++;
        Blt->Red = *Image;
	}

    ImageIndex = (UINTN)(Image - BmpHeader->ImageOffset);
    if ((ImageIndex % 4) != 0) 
		{
      Image = Image + (4 - (ImageIndex % 4));
    }
  
  }
     UgaDraw->Blt (
                  UgaDraw, 
                  BltBuffer,              EfiUgaBltBufferToVideo, 
                  0,                      0, 
				  Col,Row,
                  BmpHeader->PixelWidth,  BmpHeader->PixelHeight,
                  BmpHeader->PixelWidth * sizeof (EFI_UGA_PIXEL)
                  );

Done:
	if (BltBuffer != NULL) {
    BS->FreePool (BltBuffer);
}
}
EFI_STATUS
DrawWord(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable,
IN CHAR16 *Value,
IN UINT16 X,
IN UINT16 Y,
IN UINT16 Background,
IN UINT16 WordCount

)
{
	  UINT16                    Count,j;
      UINT16                    GlyphWidth=19;
      UINT32                    GlyphStatus=0;
      UINT8                     *Glyph;      
      EFI_UGA_PIXEL             *Buffer;
	  EFI_STATUS                 Status;
	//  LibInitializeShellApplication (ImageHandle, SystemTable);
	InitializeLib(ImageHandle,SystemTable);
	  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics); 
 for(j=0;j<WordCount;j++)
	{
	 Count=0;
     Status= mHii->GetGlyph(mHii,&Value[j],&Count,&Glyph, &GlyphWidth,&GlyphStatus);
     Buffer = AllocateZeroPool (8*19* sizeof (EFI_UGA_PIXEL));
	 Status=mHii->GlyphToBlt( mHii, Glyph, EfiColors[15],EfiColors[Background],1,8,19, Buffer);
              
    Status=UgaDraw->Blt(
		    UgaDraw, Buffer,
            EfiUgaBltBufferToVideo,
            0, 0,
            X,Y,
            8,19, 0
            );  
	X=X+8;
	}
   return EFI_SUCCESS;           
}










⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -