(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365)

UEFI下的弹跳小游戏

  • 1 Bounce游戏
    • 1.1 游戏架构
    • 1.2 移植和编写代码
      • 1)编写文件读取到内存的函数
      • 2)编写图像显示函数
      • 3)实现弹跳函数Bounce
      • 4)实现主功能
  • 2 测试弹跳小游戏

昨天闲暇的时候,把Tim Lewis的迷宫游戏编译了一下,自娱自乐在UEFI下玩了一把。

奇怪的是,CSDN竟然给我发了“入选《游戏领域内容榜》第27名”,如下图:

图1 CSDN奇怪的评选

嗯,虽然从理论上来说,这篇博客也算写了个游戏,可我主要写的是UEFI程序啊。除了这篇博客的名字外,在关键字里我也没有设置“游戏”字样。

实在搞不懂CSDN的评判算法。

不管了,昨天看Tim Lewis的代码中,还有一些游戏,今天想再编译试试。

1 Bounce游戏

在早期的Windows XP中,有一个让人印象深刻的屏保。桌面上一个小球,在屏幕上来回撞,运行的过程中画出各种轨迹。

Bounce就是用来实现类似功能的UEFI程序。

不过,直接编译后,发现无法运行。看了下代码,图像是通过类似HII的方式来组织的。

不大习惯这种方式,我还是决定自己把程序修改一下。

1.1 游戏架构

从功能上来说,要实现的比较简单:
1) 图像显示(包括指定位置的图像显示);
2) 遇到障碍物的动作处理(主要是屏幕四周)。

这是个粗糙的架构,在此基础上,可以扩展多个图像碰撞后的处理,实现类似以前的屏保的效果。

实际上,UEFI开发探索系列博客中所开发的图像处理函数,完全可以直接使用。

为了方便,我也是在之前的代码基础上进行移植的。基础工程是以前的MyGuiFrame,修改了其中与图像处理相关Picture.c,以及添加了一个文件处理函数,位于FileRW.c中。

1.2 移植和编写代码

主要的编写步骤如下。

1)编写文件读取到内存的函数

修改原来通过GUID获取文件的方法,直接读取bmp图像到内存。文件处理的函数,放在了FileRW.c中,如下所示:

//robin 增加一个处理图像文件的加载函数
EFI_STATUS
LoadFile(IN CONST CHAR8    *FilePath,OUT VOID          **File,OUT UINT32        *FileSize
)
{FILE *f = fopen(FilePath, "rb");if (f == NULL) {return EFI_NOT_FOUND;}fseek(f, 0, SEEK_END);*FileSize = ftell(f);fseek(f, 0, SEEK_SET);  //same as rewind(f);*File = malloc(*FileSize);if (*File == NULL) {return EFI_OUT_OF_RESOURCES;}if (fread(*File, *FileSize, 1, f) < 1) {return EFI_DEVICE_ERROR;}fclose(f);return EFI_SUCCESS;
}

2)编写图像显示函数

图像显示的函数包括DisplayImage()和DisplayImageAt(),内容如下:

EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mBlt;
UINTN mHeight;
UINTN mWidth;
int DisplayImageAt (UINTN X, UINTN Y)
{gGraphicsOutput->Blt (gGraphicsOutput,mBlt,EfiBltBufferToVideo,0,0,X,Y,mWidth,mHeight,mWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));return 0;
}EFI_STATUS
DisplayImage (IN CONST CHAR8    *BmpFilePath)
{EFI_STATUS Status;UINT8 *ImageData;UINTN ImageSize;UINTN BltSize;UINTN CoordinateX;UINTN CoordinateY;//robin 修改原有代码,将图像文件加载Status = LoadFile(BmpFilePath, (VOID **)&ImageData, &ImageSize);if (EFI_ERROR(Status)) {             //print error messagesreturn FALSE;}BltSize = 0;Status = ConvertBmpToGopBlt (ImageData,ImageSize,(VOID **) &mBlt,&BltSize,&mHeight,&mWidth);if (EFI_ERROR (Status)) {free (ImageData);}CoordinateX = (gGraphicsOutput->Mode->Info->HorizontalResolution / 2) - (mWidth / 2);CoordinateY = (gGraphicsOutput->Mode->Info->VerticalResolution / 2) - (mHeight / 2);DisplayImageAt ((UINTN) CoordinateX, (UINTN) CoordinateY);return EFI_SUCCESS;}

DisplayImageAt()在指定位置处,将内存mBlt中存储的图像,直接显示到屏幕上;而DisplayImage()则完成了将BMP图像加载到内存mBlt,以及调用DisplayImageAt()显示图像的功能。

3)实现弹跳函数Bounce

弹跳函数通过UEFI定时器,按一定的频率移动图像,如果图像撞到屏幕四周,则反弹回来继续移动。

逻辑结构还是比较简单的,内容如下:

EFI_GRAPHICS_OUTPUT_BLT_PIXEL mBoundBg = {201,  174, 255, 0};
EFI_EVENT mEvent;
EFI_STATUS bounce (VOID)
{EFI_EVENT events[2];UINTN index;EFI_INPUT_KEY Key;INTN DeltaX;INTN DeltaY;INTN CurrentX;INTN CurrentY;INTN NewX;INTN NewY;gBS->CreateEvent (EVT_TIMER,0,NULL,NULL,&mEvent);gBS->SetTimer (mEvent,TimerPeriodic,// 10*1000*1000  //fix time? 1s10*1000*80   //80ms);Key.ScanCode = SCAN_NULL;DeltaX = 3;DeltaY = 3;events[0] = gST->ConIn->WaitForKey;events[1] = mEvent;CurrentX = (gGraphicsOutput->Mode->Info->HorizontalResolution / 2) - (mWidth / 2);CurrentY = (gGraphicsOutput->Mode->Info->VerticalResolution / 2) - (mHeight / 2);do {gBS->WaitForEvent (2, events, &index);if (index == 0)  {gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);continue;} else {NewX = CurrentX + DeltaX;NewY = CurrentY + DeltaY;if (NewX + mWidth > gGraphicsOutput->Mode->Info->HorizontalResolution) {//bounce XNewX = gGraphicsOutput->Mode->Info->HorizontalResolution - mWidth;DeltaX = -DeltaX;} else if (NewX < 0) {//bounce XNewX = 0;DeltaX = -DeltaX;}if (NewY + mHeight > gGraphicsOutput->Mode->Info->VerticalResolution) {//bounce YNewY = gGraphicsOutput->Mode->Info->VerticalResolution - mHeight;DeltaY = -DeltaY;} else if (NewY < 0) {//bounce YNewY = 0;DeltaY = -DeltaY;}gGraphicsOutput->Blt(gGraphicsOutput,&mBoundBg,EfiBltVideoFill,0,0,CurrentX,CurrentY,mWidth,mHeight,0);DisplayImageAt (NewX, NewY);CurrentX = NewX;CurrentY = NewY;}} while (Key.ScanCode != SCAN_END);gST->ConOut->Reset (gST->ConOut, FALSE);return EFI_SUCCESS;
}

4)实现主功能

在主程序中,添加对bmp图像的加载显示,并实现弹跳效果:

if (EFI_ERROR (DisplayImage("bounce.bmp"))) {return 1;}bounce();

为了方便演示,我把屏幕分辨率改为了800x600。

经过以上步骤,就完成了弹跳小游戏的编程了。

2 测试弹跳小游戏

使用如下命令编译:

C:\vUDK2018\edk2>build -p RobinPkg\RobinPkg.dsc -m RobinPkg\Applications\BounceGame\BounceGame.inf -a IA32

把编译好的程序BounceGame.efi以及项目文件夹下的bounce.bmp拷贝到模拟器所在文件夹,运行BounceGame.efi即可看到效果。

在Tianocore模拟器中,运行效果如图2所示。

图2 弹跳小游戏

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目代码位于:/ FF RobinPkg/RobinPkg/Applications/BounceGame下


UEFI开发探索95 – 弹跳小游戏相关推荐

  1. UEFI开发探索94 – 迷宫小游戏

    (请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) UEFI下的迷宫小游戏 1 Maze程序结构分析 1)定义全局变量 2)设置迷宫 3) 游戏控制 ...

  2. UEFI开发探索99 – UEFI Shell下截屏工具

    (请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) UEFI Shell下截屏工具 1 PrintScreenLogger的代码结构 1)Print ...

  3. UEFI开发探索QA – 问题辑录(持续更新)

    最近正在尝试在Unbutu16上搭建开发和调试环境,其中过程一言难尽,到现在也没完成到符合我要求的程度. 正是因为遇到障碍,我今天早上回到Win10+UDK2018的环境下,想重新编译下AppPkg, ...

  4. html小游戏代码_研发实践:Mozilla分享如何开发一款WebVR小游戏

    文章相关引用及参考:mozvr 本文来自Mozilla的Josh Marinacci (映维网 2019年02月06日)在倡导新技术时,我总是尝试采用现实世界开发者的方式,而对于WebVR,开发一款游 ...

  5. UEFI开发探索97 – EDK2模拟器搭建网络环境

    (请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) EDK2模拟器搭建网络环境 1 搭建EDK2开发环境 1)工具安装 2)下载代码库 3)更新子模 ...

  6. 云开发谁是卧底线下小游戏发牌助手微信小程序源码-亲测可用

    云开发谁是卧底线下小游戏源码,发牌助手微信小程序源码. "谁是卧底OL"是一个非常有趣,风靡全国的比拼语言表述能力.知识面与想象力的游戏. 谁是卧底OL是一款由开发商北游科技倾力打 ...

  7. 视频教程-Layabox3D游戏开发入门-微信3D小游戏案例 -微信开发

    Layabox3D游戏开发入门-微信3D小游戏案例 有多年Unity程序开发经验,有策划和美术设计的经验.愿意在csdn这个平台和大家一起分享! 金龙 ¥29.00 立即订阅 扫码下载「CSDN程序员 ...

  8. 如何通过 LeanCloud 快速开发实时对战小游戏?

    实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...

  9. 视频|如何通过 LeanCloud 快速开发实时对战小游戏

    实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...

最新文章

  1. wsl子系统添加开机启动任务
  2. sap Status状态栏设计
  3. 【推荐系统算法学习笔记1】基本架构、专有名词、构建流程
  4. 前端如何快速上手 Web 3D 游戏的开发
  5. 云服务器ECS共享标准型S6全新发布, 行业内最具性价比
  6. C语言中Uint8_t数据类型
  7. 什么是网络单纯型算法
  8. onvif学习笔记8:最近写的一个ONVIF客户端的心得小结
  9. Python实战从入门到精通第七讲——字符串与文本1之字符串开头或结尾匹配
  10. 零经验程序员如何抢占面试机会?
  11. 48. Rotate Image java solutions
  12. Laravel的中间件
  13. erstudio安装
  14. 张宇基础30讲 第8讲
  15. 无根树的计数——prufer序列
  16. 2020年的5种常见骇客行为,你的电脑安全吗?
  17. TF卡用FAT32还是NTFS?
  18. 怎么查看计算机簇大小,分区格式与簇的大小讲解
  19. 说话人识别VAD算法概述
  20. 计算机网络跟Internet的区别和联系,互联网和因特网的区别与联系

热门文章

  1. 亚马逊服务器文件上传,将文件从亚马逊托管站点上传到其他FTP服务器
  2. 互斥锁实现线程互斥(嵌入式学习)
  3. ImageNet数据集的构建逻辑
  4. N1・N2听力单词 —— 恋爱、结婚、生子
  5. 程序员入门第一个程序
  6. 【Android基础】应用界面编程
  7. golang单例模式
  8. win10修改ntp服务器地址,win10怎么设置ntp服务器地址
  9. 嵌入式C语言之---模块化编程
  10. “4.29”赛事再燃“360春秋杯”国际挑战赛报名启动