GAPI编程实践

GAPI编程实践

(发布时间200062)

 

尽管在Pocket PC平台上,游戏开发人员不能使用DirectDraw 来开发游戏,但最近有一个好消息,就是 Microsoft 专门为Pocket PC新开发了一个名叫“GAPI”的游戏API Game Application Interface)。它不仅可以直接访问显示内存,而且可以访问Pocket PC硬件按键。

您需要具备GAPI SDK、运行动态链接库(Runtime DLLs),以及 位于EVTools 第二张光盘“PocketPCSDK/Program Files/Support/GameAPI”目录下的一个示例程序。

 

步骤1创建一个示例程序“Hello World” GAPI 没有集成在Pocket PC SDK之中。所以要进行一些预备步骤:

手动地把“GX.H”包含文件复制到Pocket PC SDK“Include”目录下。 把依赖CPU类型“GX.LIB”文件复制到Pocket PC SDK的相应“Lib”目录下。 最后,把依赖CPU类型的“GX.DLL” 文件复制到Pocket PC“Windows”目录。

现在,您可以开始建立您的第一个简单的“Hello World” 程序了。 启动eMbedded Visual C++,创建一个新的Pocket PC应用程序,然后把它命名为“FirstGX” 在向导创建了新工程后,让我们添加GAPI初始化调用。 把下面的代码行添加到InitInstance 函数的末尾:

// Try opening the Display for Full screen access

if (GXOpenDisplay(hWnd, GX_FULLSCREEN) == 0) {

      return FALSE;   // we won't be able to draw.

}

 

// Initialize the Hardware Buttons

GXOpenInput();

 

// Get the Display properties

g_gxdp = GXGetDisplayProperties();

// Get information about the Hardware Keys and fills

// the g_gxkl structure

g_gxkl = GXGetDefaultKeys(GX_NORMALKEYS);

 

return TRUE;

 

这段代码使用了必须在FirstGX.cpp 源文件的全局空间里定义的两个变量。为避免编译错误,我们还必须我们的代码里包含进GX.H 文件:

直接在eMbedded Visual C++ 向导创建的包含文件中添加以下行:

#include "gx.h"

GXDisplayProperties g_gxdp;      // GX struct

GXKeyList g_gxkl;              // GX struct

我们应该在关闭应用程序之前将Game API 清理干净。 WinMain 函数的末尾插入下面两行代码:

GXCloseDisplay();

GXCloseInput();

 

步骤2直接在显示内存中进行写操作

在我们开始编写代码之前,我们必须回忆一下。根据Pocket PC硬件的不同,您可能有16位的彩色显示器CasioHP、或Compaq)或者8位的显示器(黑白或彩色,例如Compaq Aero 1550)。为了断定您的Pocket PC显示器是什么样的,您可以检查一下g_gxdp 结构的cBPP成员。它会告诉您您的显示器究竟是多少位的。

在直接访问16位显示的显示内存之前,您必须要知道显示控制器是如何来解释16位色彩掩码的。有两种可能的标志设置:KfDirect555 kfDirect565555 把一个 XRRRRRGG.GGGBBBBB色彩掩码转换成Red-Green-Blue形式的短变量,而565 会把它转换成RRRRRXGG.GGGBBBBB的形式。

8位的彩色显示设备上,您可以使用一个字节来表示256种颜色。 现在,我们可以直接写屏了。我们想在这些键中的一个键被按下的时候,用一种颜色填充整个屏幕。 FirstGX.cpp 源文件的顶部添加以下函数:

bool ClearScreen(int colRed,int colGreen, int colBlue)

{

      // 16 bit per pixel code.  Note 2 different pixel formats.

      switch (g_gxdp.cBPP)

      {

      case 16: {

                  unsigned short PixelCol = 0;

                  if (g_gxdp.ffFormat | kfDirect565) {

                        PixelCol = (unsigned short)

                                    ((colRed & 0xff)<< 11 |

                                     (colGreen & 0xff) << 5 |

                                     (colBlue & 0xff));

                  } else if (g_gxdp.ffFormat | kfDirect555) {

                        PixelCol = (unsigned short)

                                    ((colRed & 0xff)<< 10 |

                                     (colGreen & 0xff) << 5 |

                                     (colBlue & 0xff));

                  }

            

     unsigned short * pusLine = (unsigned short *)GXBeginDraw();

     if (pusLine == NULL) return false; // NOT OK TO DRAW

     

         for (unsigned int y = 0; y < g_gxdp.cyHeight; y++) {

               unsigned short * pusDest = pusLine;

               for (unsigned int x = 0;

                    x < g_gxdp.cxWidth; x++) {

                     *pusDest = PixelCol;

                     pusDest += g_gxdp.cbxPitch >> 1;

               }

               pusLine += g_gxdp.cbyPitch >> 1;

         }

         GXEndDraw();

         break;

         }

        case 8:    {

              // Get a Random Color

              // IMPORTANT:

              // 8Bit are using a palette and the formular

              // below does not compute a read RGB color

              unsigned char bPixel = (colRed &0xf)<<5 |

                                      (colGreen&0x3)<<3 |

                                      (colBlue&0xF);

                                     

        unsigned char * pbLine = (unsigned char *)GXBeginDraw();

        if (pbLine == NULL)     return false;// NOT OK TO DRAW

       

           for (unsigned int y = 0; y < g_gxdp.cyHeight; y++) {

                 unsigned char * pbDest = pbLine;

                 for (unsigned int x = 0;

                      x < g_gxdp.cxWidth; x++) {

                       *pbDest = bPixel;

                       pbDest += g_gxdp.cbxPitch;

                 }

                 pbLine += g_gxdp.cbyPitch;

           }

           GXEndDraw();

           break;

           }

     }

     return false;

}

 

步骤3访问硬件按键

这是个很简单的任务。您应该很熟悉Windows“WM_messages” ,并且知道如何使用它们。了解了这些知识,您就知道了如何来使用Pocket PC硬件按键。只要分析一下Windows过程中的WM_KEYUP WM_KEYDOWN 消息即可。

这里是我的FirstGX 程序的WM_KEYDOWN 分支:

               case WM_KEYDOWN:

                     vkKey = (short)wParam;

                     if (vkKey == g_gxkl.vkUp) {

                           ClearScreen(0,0,0); // Black

                           break;

                     }

                    

                     if (vkKey == g_gxkl.vkDown) {

                           ClearScreen(255,0,0); // Red

                           break;

                     }

                    

                     if (vkKey == g_gxkl.vkLeft) {

                           ClearScreen(0,255,0); // Green

                           break;

                     }

                    

                     if (vkKey == g_gxkl.vkRight) {

                           ClearScreen(0,0,255); // Blue

                           break;

                     }

                    

                     if (vkKey == g_gxkl.vkStart) {

                           SendMessage(hWnd, WM_CLOSE, 0, 0);

                           break;

                     }

所有可能的按键名称列表可以在gx.h 包含文件的GXKeyList 结构中找到。

步骤3准备运行!

在我们开始编译并把我们的FirstGX 程序下载Pocket PC上之前,我们必须在工程的库文件列表中添加gx.lib 文件。然后,我们可以编译这个程序,并把它下载到我们的Pocket PC上。运行它,按一下键,看看会发生什么?

 

结论

正如您看见的,Game API很简单,但是已经足够强大了,它能满足我们编写快速动作游戏的全部需要。本示例展示了如何使用GAPI的一些细节和技巧。如果愿意,您可以下载本示例的所有源代码。

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值