PocketFrog나 PocketHAL등을 사용하려면
Game API(GAPI)가 지원되어야 합니다. 그런데 이 GAPI라는 녀석은 PocketPC에서만 지원되는 놈이라 일반적인 CE .net에서는 동작하지 않습니다. 그러던 중 찾아보니
HPC계열에서 구동하는 GAPI가 있더군요. 혹시나 싶어 GAPI호환 DLL을 제작하면 되지 않을까 싶어 한번 만들어 봤습니다.
gx.h 원본 소스 보기
[CODE]
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the GXDLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// GXDLL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#if defined(_M_IX86)
#define GXDLL_API
#else
#ifdef GXDLL_EXPORTS
#define GXDLL_API __declspec(dllexport)
#else
#define GXDLL_API __declspec(dllimport)
#endif
#endif
struct GXDisplayProperties {
DWORD cxWidth;
DWORD cyHeight; // notice lack of 'th' in the word height.
long cbxPitch; // number of bytes to move right one x pixel - can be negative.
long cbyPitch; // number of bytes to move down one y pixel - can be negative.
long cBPP; // # of bits in each pixel
DWORD ffFormat; // format flags.
};
struct GXKeyList {
short vkUp; // key for up
POINT ptUp; // x,y position of key/button. Not on screen but in screen coordinates.
short vkDown;
POINT ptDown;
short vkLeft;
POINT ptLeft;
short vkRight;
POINT ptRight;
short vkA;
POINT ptA;
short vkB;
POINT ptB;
short vkC;
POINT ptC;
short vkStart;
POINT ptStart;
};
GXDLL_API int GXOpenDisplay(HWND hWnd, DWORD dwFlags);
GXDLL_API int GXCloseDisplay();
GXDLL_API void * GXBeginDraw();
GXDLL_API int GXEndDraw();
GXDLL_API int GXSetViewport( DWORD dwTop, DWORD dwHeight, DWORD dwReserved1, DWORD dwReserved2 );
GXDLL_API BOOL GXIsDisplayDRAMBuffer();
GXDLL_API GXDisplayProperties GXGetDisplayProperties();
GXDLL_API int GXOpenInput();
GXDLL_API int GXCloseInput();
GXDLL_API GXKeyList GXGetDefaultKeys(int iOptions);
GXDLL_API int GXSuspend();
GXDLL_API int GXResume();
// Although these flags can be unrelated they still
// have unique values.
#define GX_FULLSCREEN 0x01 // for OpenDisplay()
#define GX_NORMALKEYS 0x02
#define GX_LANDSCAPEKEYS 0x03
#ifndef kfLandscape
#define kfLandscape 0x8 // Screen is rotated 270 degrees
#define kfPalette 0x10 // Pixel values are indexes into a palette
#define kfDirect 0x20 // Pixel values contain actual level information
#define kfDirect555 0x40 // 5 bits each for red, green and blue values in a pixel.
#define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel
#define kfDirect888 0x100 // 8 bits each for red, green and blue values in a pixel.
#define kfDirect444 0x200 // 4 red, 4 green, 4 blue
#define kfDirectInverted 0x400
#endif
[/CODE]
위의 소스를 보면 GX.DLL이 하는 일이 몇가지 없다는 것을 알 수 있습니다. 결국 이 녀석이 하는 일은 비디오 메모리의 구성 상태와 비디오 메모리 주소를 응용 어플리케이션에 잘 넘겨줘서 응용 어플리케이션단에서 디바이스 종속적이지 않게 코딩할 수 있게 도와주는 역할을 합니다.
핵심적으로 구현해야 하는 API는 아래의 네개의 API입니다.
[CODE]
GXDLL_API int GXOpenDisplay(HWND hWnd, DWORD dwFlags);
GXDLL_API int GXCloseDisplay();
GXDLL_API void * GXBeginDraw();
GXDLL_API GXDisplayProperties GXGetDisplayProperties();
[/CODE]
- GXOpenDisplay()는 해당 비디오 메모리 주소에 맞게 Virtual Allocation을 수행합니다.
- GXBeginDraw()는 Virtual Allocation된 메모리 주소를 반환합니다.
- GXCloseDisplay()는 Virtual Free를 수행하며
- GXGetDisplayProperties()는 해당 디스플레이에 맞는 해상도와 픽셀의 구성 상태를 반환합니다.
위에서 나열한 동작만 지켜서 구현해주면 잘 동작합니다. 실제 단말기에 올려서 TCPMP 플레이어로 미디어 플레이 테스트 해보니 GAPI드라이버를 로딩해서 플레이 할 때 일반적인 녀석은 GDI와 비교해봐서 20%정도의 향상이 있었으며, 특이한 녀석 (가로형 LCD를 세로형 단말기에 적용한 녀석)의 경우는 200%의 향상이 있었습니다.
위의 드라이버를 다운로드해서 압축을 해제한 뒤 gx.dll파일을 TCPMP 플레이어와 같은 디렉토리에 놓으시면 됩니다. 주의하셔야할 점은
아이나비 PRO나 아이나비 UP+는 호환되지 않습니다.
PRO Plus의 경우는 성능 향상이 상당하나 UP의 경우는 성능 향상이 미미합니다. 그리고 미디어 소스에 따라 성능 차이가 있는데, 파일 IO가 많이 일어나는 대용량 미디어 파일보다 용량은 적으나 프레임이 많은 미디어 소스에서 이득이 많습니다. 이점 참고바랍니다.
Posted by 졸곰