[sdlpal]游戏开始界面背景图的显示

本文介绍了SDLPal如何从资源文件中加载并显示开始界面的背景图。背景图数据从mkf文件读取到内存,然后转换成纹理。详细讲解了从图片资源创建数据到屏幕的过程,包括内存管理、Blit操作和效率优化。同时提到了分辨率适配和防止图像拉伸变形的计算,但未深入探讨。
摘要由CSDN通过智能技术生成

继续看了下sdlpal的源码,这节讲下代码是如何从资源文件中读取所需图片并显示到屏幕上的。
下面这张就是开始界面了,当然除了背景图外还有菜单,菜单里的两个选项其实就是绘制的两行文字(一般的菜单除了文字还会有菜单背景图的,这里没有,只是简单的文字), 菜单的原理就另外章节讲了,这里只讲下图片资源的加载和显示。
这里写图片描述


一路跟踪,发现背景是在这里绘制的:mian()->PAL_GameMain()->PAL_OpeningMenu()->PAL_DrawOpeningMenuBackground(),当然还有很多其他代码,这里不用理,弄明白最后那个函数就可以了。这些函数具体在哪个文件就不说了,用VS Code查找很方便。看下该函数的内部实现:

/* From: sdlpal/uigame.c */

// 可以看到函数并没有多少行代码
VOID
PAL_DrawOpeningMenuBackground(
   VOID
)
/*++
  Purpose:

    Draw the background of the main menu.

  Parameters:

    None.

  Return value:

    None.

--*/
{
    // LPBYTE的原型是unsigned char*,该变量用来存放从那些mkf读取到的图片资源数据
    LPBYTE buf;

    // 之所以要malloc这么多个字节,是因为开始界面那张背景图的分辨率是320 * 200的
    // 因此我们要用320 * 200个字节来保存图片数据
    buf = (LPBYTE)malloc(320 * 200);
    if (buf == NULL)
    {
        return;
    }

   //
   // Read the picture from fbp.mkf.
   //
   // 从上面源码的注释可知道,背景图是压缩在fbp.mkf这个资源文件中的
   // 函数第一个参数是用来写入数据的,第二个参数指定了写入数据的大小,第三个参数应该是用来说明该图片在资源文件中的位置信息,最后一个参数当然是fbp.mkf这个资源文件了
   // 该函数的内部实现先不看,等看明白了mfk资源文件的结构后,在开一篇单独的文章记录一下
   // 现在只要知道-调用这个函数后,我们就从资源文件中读取到了背景图的数据信息
   PAL_MKFDecompressChunk(buf, 320 * 200, MAINMENU_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP);

   //
   // ...and blit it to the screen buffer.
   //
   // 读取到图片后,当然需要将它绘制到屏幕上,下面这个函数就是专门负责将图片数据填充到屏幕上的
   // gpScreen在VIDEO_Startup()中创建好了,下面这个函数只是将buf数据填充到gpScreen->pixels中
   // 该函数的内部实现,下面会讲到
   PAL_FBPBlitToSurface(buf, gpScreen);
   // 数据填充好后,还需刷新下屏幕才可以显示到屏幕上的,该函数下面会讲
   VIDEO_UpdateScreen(NULL);

    // 其实调用PAL_FBPBlitToSurface(buf, gpScreen)后,已经将buf这段内存中的数据转换成了SDL_Surface*这种类型的数据(也就是gpScreen),因此可以将buf释放掉了
   free(buf);
}

如果你使用过SDL2在一个窗口显示一张图片,那么你肯定知道它的大致过程是这样的:

// 加载一个bmp文件
SDL_Surface* surface = SDL_LoadBMP("foo.bmp");
// 将surface转换成texture
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
// 拷贝到渲染器上
SDL_RenderCopy(renderer, texture, NULL, NULL);
// 刷新显示
SDL_RenderPresent(renderer);

sdlpal开始界面的背景图显示原理也和这个差不多,不过背景图并不是从一个bmp文件中加载的,而是从mkf文件中读取数据到内存,然后将内存中的数据转换成一个SDL_Surface*

// lpBitmapFBP是从fbp.mkf文件中读取到的bmp图片文件的数据,它其实就是一个unsigned char类型的数组
// 数组的每个元素记录着图片的像素信息。lpDstSurface就是转换后的数据了。
// 从下面的NOTE注释可以看出,该函数有个限制,它要求图片的分辨率是320*200像素的,如果读取到一个不符
// 合该分辨率的图片数据到lpBitmapFBP,再调用该函数是不会创建出plDstSurface的。
INT
PAL_FBPBlitToSurface(
   LPBYTE            lpBitmapFBP,
   SDL_Surface      *lpDstSurface
)
/*++
  Purpose:

    Blit an uncompressed bitmap in FBP.MKF to an SDL surface.
    NOTE: Assume the surface is already locked, and the surface is a 8-bit 320x200 one.

  Parameters:

    [IN]  lpBitmapFBP - pointer to the RLE-compressed bitmap to be decoded.

    [OUT] lpDstSurface - pointer to the destination SDL surface.

  Return value:

    0 = success, -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值