Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1324952
  • 博文数量: 281
  • 博客积分: 8800
  • 博客等级: 中将
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 22:31
文章分类

全部博文(281)

文章存档

2013年(1)

2012年(18)

2011年(16)

2010年(44)

2009年(86)

2008年(41)

2007年(10)

2006年(65)

我的朋友

分类: LINUX

2007-12-17 14:23:27

SDL: 使 Linux 变得有趣

developerWorks
文档选项
将此页作为电子邮件发送

将此页作为电子邮件发送

未显示需要 JavaScript 的文档选项



级别: 初级

Sam Lantinga, 首席程序员, Loki Entertainment Software

1999 年 9 月 01 日

Sam Lantinga 是 Simple DirectMedia Layer (SDL) 库的作者和 Loki Entertainment 的首席开发人员,他将向您介绍一种将游戏移植到 Linux上的优秀工具。SDL 是一个跨平台代码移植的理想工具,它支持许多平台,如Linux、Solaris、IRIX、FreeBSD 和 MacOS,这对于那些认为可以在 Linux上开发商业软件的 Linux 开发者来说是一大进步。他向社区的前辈之一讨教SDL 如何使 Linux 用户享受任何平台上最好的游戏,SDL如何帮助开发者跟上下一代计算机游戏迷的要求。
Sam Lantinga 是 Simple DirectMedia Layer (SDL) 库的作者和 Loki Entertainment 的首席开发人员,他将向您介绍一种将游戏移植到 Linux 上的优秀工具。SDL 是一个跨平台代码移植的理想工具,它支持许多平台,如 Linux、Solaris、IRIX、FreeBSD 和 MacOS,这对于那些认为可以在 Linux 上开发商业软件的 Linux 开发者来说是一大进步。他向社区的前辈之一讨教 SDL 如何使 Linux 用户享受任何平台上最好的游戏,SDL 如何帮助开发者跟上下一代计算机游戏迷的要求。

自从 Linus 首先开发出 Linux 时开始,到现在 Linux 成为所有黑客的梦想并且遍及全世界,Linux 开发最重要的元素之一就是 OS 上游戏的质量和可用性。游戏是我们用来娱乐和休闲的。它们可以提高创造力并拓展思路。游戏还可以用来测量操作系统的性能。由于游戏越来越复杂,它们迫使每个子系统逼近极限。每当我装配一个系统时,首先要做的就是装入一个游戏并试玩,以“测试”每一项的性能。

Linux 上的游戏已经存在了很长时间。从早期的 NetTrek,到受高度赞扬的 DOOM!雷神 (Quake),人们已经可以在 Linux 上玩游戏了。但问题是没有足够的游戏。没有哪家大公司为 Linux 创作能产生轰动效应的游戏。但是,由于该操作系统变得日益流行,这种情况正开始改善。

Linux 上最早期的游戏使用 X11 协议。但是对于游戏来说,X11 实在太慢了,因为它是针对在网络上透明运行的基于菜单的应用而设计的协议。使用它的游戏通常没有绚丽的画面,而且运行得相当慢。 DOOM!是一个值得注意的例外,虽然它使用 X11,但是它通过使用 MIT 共享内存扩展可以使动画更流畅,并提供了逼真的三维效果。还有一些游戏使用 SVGA 图形库,SVGAlib。我最喜欢的一个老游戏是重力战争 (Gravity Wars),它对其模拟的老 Amiga 游戏 Gravity Force 做了重大改动。但使用 SVGAlib 的程序只能适用于少数受支持的显卡。

早期 X11 游戏, 争霸 (Craft)的图片。 神话 2 (Myth 2)的图片,Loki 出品
单击以放大图片 单击以放大图片

今天,游戏开发者有了更多的选择。仍然可以使用 X 工具箱或全屏 API,如 SVGAlib 或 fbcon,来编写游戏,但他们现在还有许多游戏库可以使用。Simple DirectMedia Layer 库是 Linux 上最好的低层游戏开发 API 之一。

中移植了一些演示程序,我将它们的 X11 代码替换成 SDL 代码(请参见下面的列表)。您可以看到,SDL 代码非常易于编写和理解。

X11 代码

int init_x (int X, int Y,
   int W, int H, int bpp,
   const char *Name) {
 XPixmapFormatValues *formatList;
 int            formatCount;
 int            i;
 int            formatOk;
 int            scanlineLength;
 XGCValues        gcVal;
 unsigned long     gcMask;
 dis   = XOpenDisplay ( NULL );
 if ( dis == NULL) {
   fprintf ( stderr , "Error :\n" );
   fprintf ( stderr , " Cannot connect to Display.\n");
   exit (1);
 }
 screen = DefaultScreen ( dis );
 depth = DefaultDepth ( dis , screen );
 width = DisplayWidth ( dis , screen );
 height = DisplayHeight ( dis , screen );
 
 winRoot            = DefaultRootWindow ( dis );
 winAttr.border_pixel   = BlackPixel ( dis , screen );
 winAttr.background_pixel = BlackPixel ( dis , screen );
 winMask            = CWBackPixel | CWBorderPixel;
 
 formatList = XListPixmapFormats( dis, &formatCount);
 if (formatList == NULL){
   fprintf ( stderr , " Cannot get pixmap list\n");
   exit (1);
 }
 formatOk=-1;
 for (i=0; ibytes_per_line*xim->height,
       IPC_CREAT|0777);
 xim->data = SHMInfo.shmaddr = (char *)shmat(SHMInfo.shmid, 0, 0);
 SHMInfo.readOnly = False;
 XShmAttach(dis, &SHMInfo);
 XSync(dis, False);
 buffer=(unsigned char *)xim->data;
#else
 buffer = (unsigned char *)calloc(W*H, pixmapFormat.bits_per_pixel/8); 
 xim = XCreateImage ( dis , CopyFromParent , depth , ZPixmap , 0 ,
      (char *) buffer , W , H , 
      pixmapFormat.scanline_pad, scanlineLength);
 if (xim == NULL){
   fprintf(stderr, " Couldnt create Ximage..\n");
   exit(-1);
 }
#endif
 gcVal.foreground = 0;
 gcVal.background = 0;
 gcMask       = GCForeground | GCBackground;
 gc = XCreateGC ( dis , win , gcMask , &gcVal );
 if (depth==24)
   depth = pixmapFormat.bits_per_pixel;
 return (depth);
}
                                

SDL 代码

int init_x (int X, int Y,
   int W, int H, int bpp,
   const char *Name) {
 int i;
 if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
   {
    fprintf ( stderr , "Erreur :\n" );
    fprintf ( stderr , " Impossible de se connecter au Display\n");
    exit (1);
   }
 screen = SDL_SetVideoMode(W, H, bpp, SDL_SWSURFACE|SDL_HWPALETTE);
 if ( screen == NULL )
   {
    fprintf ( stderr , "Erreur :\n" );
    fprintf ( stderr , " Impossible de se connecter au Display\n");
    exit (1);
   }
 SDL_WM_SetCaption ( Name, Name );
 for ( i=SDL_NOEVENT; iformat->BitsPerPixel;
 width = screen->w;
 height = screen->h;
 buffer = (unsigned char *)screen->pixels;
 return (depth);
}
                    

  • 灵活。返回到上面的 Optimum 演示代码示例,只要移植到 SDL,并确定一些数据假设,那么根本不必改动代码,演示就可以在 Win32、BeOS 和 Linux 控制台上运行了。灵活性的另一方面体现在尽管代码完全是跨平台的,但不会把您和底层实现隔开。SDL 提供了函数 SDL_GetWMInfo(),该函数可以让您访问底层驱动程序的专用窗口信息。Loki Entertainment Software 广泛使用这一技术为它们的游戏智能窗口管理器交互。

    Optimum 演示版的屏幕快照
    Optimum 演示版的屏幕快照 Optimum 演示版的屏幕快照 Optimum 演示版的屏幕快照

  • 这种坚如磐石般的稳定、简单和强大功能的组合已经给 Linux 带来了一些极其引人入胜的游戏,包括 等等。编程爱好者和商业公司使用这个库的事实表示它正在日益提高其功能和稳定性。这符合实际游戏的实际需要。

    文明:力量的呼唤 (Civilization: Call To Power)的图片 天旋地转 2 (Descent 2)的图片
    单击以放大图片 单击以放大图片
    SDL 的起源
    SDL 在两年前问世,当时我正致力于从 Macintosh 仿真器
    Executor到 Win32 的移植工作。我注意到同一个功能在几个平台上基本上都是以相同的方式实现的。所有目标都要求可以访问屏幕、映射鼠标和键盘输入,以及播放声音。我想:为什么不写一个跨平台的库来提供这些许多人会用到的基本服务?应用程序开发者只需要写一个 API,这样就大大简化了他们的工作,还可以使他们的代码可以迅速在多个平台上运行,以吸引尽可能多的观众。我开始着手进行,一年多以后,第一个稳定的 SDL 发行版诞生了。

    创建 SDL 的第一步就是要标识所需的功能。根据分析 Executor 和以往的移植经验,我已经有了一个好的想法。下一步就是构建在 Win32 和 Linux 上运行的有效原型。我知道对于 API,最大的考验就是在实际的应用程序下工作,因此我所做的第一件事就是使用它来完成从 Executor 到 Win32 的移植。在这段时间里,我不断添加 API 的主体,并将它移植到 BeOS。然后,采用最新得到的 DOOM!源码,在短短三天时间内,就使它可以在所有三个受支持的平台上顺畅地运行。

    一年以后,我现在使用它来将世界上最好的一些游戏移植到世界上最受欢迎的操作系统 Linux 上。虽然我就职于商业公司,但这个库本身是免费的,并且它是开放源码概念力量的体现。

    来订阅该邮件列表。该邮件列表镜像为 上的一个新闻组。加入这个邮件列表以获取关于使用 SDL 的提示,错误修正的最新公告和新的功能,及使用 SDL 的项目的预览版本。 有一个非常棒的用于 Win32、DOS、Linux、OS/2 和 QNX 的图形库。但它是一个商业库,而 VESA 控制台驱动程序对于 Linux 是免费的。因此,可以支持 SDL 中的 VESA 控制台驱动程序。
  • Mesa 集成为一个 GLX 层。OpenGL 绝对是将来在 Linux 上开发三维游戏的方法。但是,GLX API 处理事件的方法不如 SDL 那样灵活。有人要求将类似于 GLX 的扩展集成到 SDL,以将它用作基于 GL 的游戏的输入接口。
  • 重新设计体系结构以允许多重显示和多重输入。当前的体系结构将 SDL 函数以存根模块编译,并在运行时动态装入低级驱动程序。这种跨平台执行方式将导致一个难于使用的构建过程,并产生一个复杂的头文件。对我来说,最要紧的一件事就是重新设计构建过程,这样所有驱动程序都可以编译到一个库中,然后在运行时动态选择。这样做的好处就是可以同时有多个活动的显示和输入方法。想像一下游戏同时在控制台和远程 X11 显示器上运行!
  • 更多游戏!SDL 的改进将使越来越多的人使用这个库,而越来越多的游戏将会出现在 Linux 上。
  • 能够涉足 Linux 游戏,我感到非常激动,我希望能够继续工作为 Linux 世界带来欢乐,因为 Linux 待我太好了。正如他们所说的,企鹅也喜欢寻开心。

    我很快会写一篇后续文章,它将带给您有关如何使用 SDL 写游戏的教程。



    下载一些 Linux 上最好的游戏:

    Game developer's newsgroup

    ,在 LinuxWorld杂志中

    ,在 LinuxWorld杂志中

    ,在 LinuxWorld杂志中



    Sam Lantinga 是 Simple DirectMedia Layer 库的作者,现在是 的首席程序员,这家公司致力于生产最畅销的 Linux 游戏。他与 Linux 和游戏打交道是从 1995 年开始的,从事各种 DOOM! 工具移植,以及将 Macintosh 游戏 Maelstrom移植到 Linux。现在,他正在移植 铁路大亨 2 (Railroad Tycoon II),这是个大量使用 SDL 技术的游戏,很快将由 Loki Entertainment Software 出品。

    阅读(1568) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~