UEFI开发探索95 – 弹跳小游戏
(请保留-> 作者: 罗冰 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 – 弹跳小游戏相关推荐
- UEFI开发探索94 – 迷宫小游戏
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) UEFI下的迷宫小游戏 1 Maze程序结构分析 1)定义全局变量 2)设置迷宫 3) 游戏控制 ...
- UEFI开发探索99 – UEFI Shell下截屏工具
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) UEFI Shell下截屏工具 1 PrintScreenLogger的代码结构 1)Print ...
- UEFI开发探索QA – 问题辑录(持续更新)
最近正在尝试在Unbutu16上搭建开发和调试环境,其中过程一言难尽,到现在也没完成到符合我要求的程度. 正是因为遇到障碍,我今天早上回到Win10+UDK2018的环境下,想重新编译下AppPkg, ...
- html小游戏代码_研发实践:Mozilla分享如何开发一款WebVR小游戏
文章相关引用及参考:mozvr 本文来自Mozilla的Josh Marinacci (映维网 2019年02月06日)在倡导新技术时,我总是尝试采用现实世界开发者的方式,而对于WebVR,开发一款游 ...
- UEFI开发探索97 – EDK2模拟器搭建网络环境
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) EDK2模拟器搭建网络环境 1 搭建EDK2开发环境 1)工具安装 2)下载代码库 3)更新子模 ...
- 云开发谁是卧底线下小游戏发牌助手微信小程序源码-亲测可用
云开发谁是卧底线下小游戏源码,发牌助手微信小程序源码. "谁是卧底OL"是一个非常有趣,风靡全国的比拼语言表述能力.知识面与想象力的游戏. 谁是卧底OL是一款由开发商北游科技倾力打 ...
- 视频教程-Layabox3D游戏开发入门-微信3D小游戏案例 -微信开发
Layabox3D游戏开发入门-微信3D小游戏案例 有多年Unity程序开发经验,有策划和美术设计的经验.愿意在csdn这个平台和大家一起分享! 金龙 ¥29.00 立即订阅 扫码下载「CSDN程序员 ...
- 如何通过 LeanCloud 快速开发实时对战小游戏?
实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...
- 视频|如何通过 LeanCloud 快速开发实时对战小游戏
实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...
最新文章
- wsl子系统添加开机启动任务
- sap Status状态栏设计
- 【推荐系统算法学习笔记1】基本架构、专有名词、构建流程
- 前端如何快速上手 Web 3D 游戏的开发
- 云服务器ECS共享标准型S6全新发布, 行业内最具性价比
- C语言中Uint8_t数据类型
- 什么是网络单纯型算法
- onvif学习笔记8:最近写的一个ONVIF客户端的心得小结
- Python实战从入门到精通第七讲——字符串与文本1之字符串开头或结尾匹配
- 零经验程序员如何抢占面试机会?
- 48. Rotate Image java solutions
- Laravel的中间件
- erstudio安装
- 张宇基础30讲 第8讲
- 无根树的计数——prufer序列
- 2020年的5种常见骇客行为,你的电脑安全吗?
- TF卡用FAT32还是NTFS?
- 怎么查看计算机簇大小,分区格式与簇的大小讲解
- 说话人识别VAD算法概述
- 计算机网络跟Internet的区别和联系,互联网和因特网的区别与联系