имеем пример работы графического движка на с++ для wince
как его можно переделать на pascal
думаю такой пригодился бы каждому кто хочет писать на wince
есть кто может перевести ?
может у кого нибудь есть уже готовый пример на подобие ?
- Код: Выделить всё
- // Test0.cpp : Defines the entry point for the application.
 //
 #include "stdafx.h"
 #include "resource.h"
 #include <aygshell.h>
 #include <gx.h>
 //////////////////////////////////////////////////////////////////////////////////////
 #define SCRTYPE_UNKNOWN 0
 #define SCRTYPE_QVGA 1
 #define SCRTYPE_VGA 2
 #define SCRMODE_NONE 0
 #define SCRMODE_GAPI_QVGA 1
 #define SCRMODE_RAW_VGA 1
 //////////////////////////////////////////////////////////////////////////////////////
 // Global Variables:
 HINSTANCE g_hInst; // The current instance
 HWND g_hMainWindow; // Main window handle
 // Физические размеры и ориентация экрана
 int g_phscreen_type;
 int g_phscreen_dx;
 int g_phscreen_dy;
 int g_phscreen_orient;
 // Размеры фреймбуфера
 int screen_dx;
 int screen_dy;
 int screen_size;
 int screen_mode;
 // Прямоугольник вывода
 RECT crect_fullscreen;
 // Копия фреймбуфера
 LPWORD shadow_buffer;
 // координаты мыши (стилуса)
 int stylus_down = 0;
 int stylus_last_x = 0;
 int stylus_last_y = 0;
 // переменные нашей главной картинки
 int main_x = 50; // координаты картинки
 int main_y = 50; //
 int main_sdx = 10; // её размеры
 int main_sdy = 11; //
 // собственно сама картинка - каждый WORD это один пиксель - как видно это
 // одномерный массив всего-лишь ...
 const WORD main_sprite [11*10] = {
 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000,
 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000,
 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000,
 0x0000, 0xFFFF, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0xFFFF, 0x0000,
 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF
 };
 // название класса и окна ...
 const TCHAR * g_sWindowClass = L"WC_TEST0_CLASS1\0";
 const TCHAR * g_sTitle = L"Test0\0";
 ////////////////////////////////////////////////////////////////////////////////////
 // Инициализируем графику
 //
 BOOL InitGfx ( void )
 {
 GXDisplayProperties dispprop;
 // размеры фреймбуфера зададим фиксированные 240 х 320
 screen_dx = 240;
 screen_dy = 320;
 screen_size = screen_dx * screen_dy;
 screen_mode = SCRMODE_NONE;
 // границы для вывода на полный экран
 crect_fullscreen.left = 0;
 crect_fullscreen.right = 240;
 crect_fullscreen.top = 0;
 crect_fullscreen.bottom = 320;
 // инициализируем дисплей
 if (GXOpenDisplay(g_hMainWindow, GX_FULLSCREEN) == 0) {
 MessageBox(g_hMainWindow, L"GAPI: Unable to init display.", L"ERROR", MB_OK);
 return FALSE;
 }
 dispprop = GXGetDisplayProperties();
 
 // проверяем графические параметры
 if ((dispprop.cBPP != 16) || (dispprop.cxWidth != (unsigned int)screen_dx) || (dispprop.cyHeight != (unsigned int)screen_dy))
 {
 GXCloseDisplay();
 MessageBox(g_hMainWindow, L"GAPI: Unable to init 240x320 16bpp mode.", L"ERROR", MB_OK);
 return FALSE;
 }
 // ок, все нормально, режим работы - qvga gapi фреймбуфер
 screen_mode = SCRMODE_GAPI_QVGA;
 shadow_buffer = (LPWORD) malloc(screen_size*sizeof(WORD));
 return TRUE;
 }
 // Освобождаем ресурсы gapi и прочее
 //
 void DeinitGfx ( void )
 {
 if (screen_mode == SCRMODE_GAPI_QVGA) GXCloseDisplay();
 free(shadow_buffer);
 }
 // Выводим копию фреймбуфера на актуальный экран
 //
 void DrawShadowBuffer ( LPWORD buf )
 {
 if (screen_mode == SCRMODE_GAPI_QVGA) {
 LPWORD framebuffer = (LPWORD) GXBeginDraw();
 memcpy(framebuffer, buf, screen_size*sizeof(WORD));
 GXEndDraw();
 return;
 }
 }
 // Рисуем картинку из массива (spr_data) в буфер (fbuf, копию фреймбуфера шириной 240 пикс.)
 //
 void draw_sprite( LPWORD fbuf, int x, int y, RECT clip_rect, LPWORD spr_data, int sdx, int sdy )
 {
 int __x, __y;
 int sx, sy;
 int ddx, ddy;
 LPWORD spraddr, bufaddr;
 int i, j;
 WORD d;
 // проверяем не вылезли ли координаты за ограничивающую область так что рисовать совсем ничего уже и не надо
 __x = x; if ((__x >= clip_rect.right) || ((__x + sdx) <= clip_rect.left)) return;
 __y = y; if ((__y >= clip_rect.bottom) || ((__y + sdy) <= clip_rect.top)) return;
 // проверяем не вылезли ли координаты за ограничивающую область так что рисовать придется не весь спрайт, а его кусок
 sx = 0; if (__x<clip_rect.left) { sx = (clip_rect.left-__x); __x = clip_rect.left; }
 sy = 0; if (__y<clip_rect.top) { sy = (clip_rect.top-__y); __y = clip_rect.top; }
 ddx = sdx - sx; if ((clip_rect.right - __x) < ddx) ddx = (clip_rect.right - __x);
 ddy = sdy - sy; if ((clip_rect.bottom - __y) < ddy) ddy = (clip_rect.bottom - __y);
 // указатели на начало отображения в буфере экрана и начало в спрайтовом буфере
 spraddr = &((spr_data)[sy*sdx+sx]);
 bufaddr = &(fbuf[__y*screen_dx+__x]);
 for (j=0; j<ddy; j++) {
 for (i=0; i<ddx; i++) {
 d = spraddr[i];
 if (d != 0) bufaddr[i] = d;
 }
 spraddr += sdx;
 bufaddr += 240;
 }
 }
 // Обрабатываем события мыши (стилуса то есть)
 //
 void OnMouseDown ( int mx, int my )
 {
 stylus_down = 1;
 stylus_last_x = mx;
 stylus_last_y = my;
 }
 void OnMouseUp ( int mx, int my )
 {
 stylus_down = 0;
 stylus_last_x = mx;
 stylus_last_y = my;
 }
 void OnMouseMove ( int mx, int my )
 {
 stylus_down = 1;
 stylus_last_x = mx;
 stylus_last_y = my;
 }
 // Функция вызывающаяся по таймеру где собственно мы всё и рисуем на экран
 //
 void TimerTick ( void )
 {
 // управление картинкой
 if (stylus_down == 1) {
 main_x = stylus_last_x - 4;
 main_y = stylus_last_y - 5;
 }
 
 // заполняем буфер цветом
 memset(shadow_buffer, 0x33, screen_size*sizeof(WORD));
 // рисуем нашу картинку
 draw_sprite(shadow_buffer, main_x, main_y, crect_fullscreen, (LPWORD)main_sprite, main_sdx, main_sdy);
 // рисуем (копируем) буфер на экран (во фреймбуфер)
 DrawShadowBuffer(shadow_buffer);
 }
 // переводим координаты мыши в координаты QVGA с началом в левом верхнем углу
 //
 void AdjustMouseMessage ( LPARAM * lp )
 {
 int x, y;
 x = LOWORD(*lp);
 y = HIWORD(*lp);
 // Здесь необходимо проверить как поворот экрана влияет на координаты стилуса для
 // разных КПК и разных режимов работы - пока я не стал включать сюда код, требуется
 // ещё провести тестирование ... пока оставим пустой
 // тут эта строка нужна будет если программа будет работать в настоящем vga-режиме
 // то есть ресурсы программы содержат CEUX, HI_RES_AWARE, иначе даже на vga-устройствах координаты
 // мыши один фиг будут в qvga
 if (g_phscreen_type == SCRTYPE_VGA) { x = x >> 1; y = y >> 1; }
 *lp = (y << 16) | (x & 0xFFFF);
 }
 // Processes messages for the main window.
 //
 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
 switch (message)
 {
 case WM_CREATE:
 break;
 case WM_DESTROY:
 PostQuitMessage(0);
 break;
 case WM_LBUTTONDOWN:
 // выходим из программы если нажали где-то в левом верхнем углу экрана
 if ((lParam == 0) || (lParam == 1)) { PostQuitMessage(0); return 0; }
 AdjustMouseMessage(&lParam);
 OnMouseDown(LOWORD(lParam), HIWORD(lParam));
 break;
 case WM_LBUTTONUP:
 AdjustMouseMessage(&lParam);
 OnMouseUp(LOWORD(lParam), HIWORD(lParam));
 break;
 case WM_MOUSEMOVE:
 AdjustMouseMessage(&lParam);
 OnMouseMove(LOWORD(lParam), HIWORD(lParam));
 break;
 case WM_KEYDOWN:
 break;
 case WM_ACTIVATE:
 break;
 case WM_SETTINGCHANGE:
 break;
 case WM_TIMER:
 TimerTick();
 return 0;
 default:
 return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
 }
 // Registers the window class.
 //
 ATOM MyRegisterClass(HINSTANCE hInstance, LPCTSTR szWindowClass)
 {
 WNDCLASS wc;
 wc.style = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc = (WNDPROC) WndProc;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hInstance = hInstance;
 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
 wc.hCursor = 0;
 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 wc.lpszMenuName = 0;
 wc.lpszClassName = szWindowClass;
 return RegisterClass(&wc);
 }
 // Saves instance handle and creates main window
 //
 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
 {
 int wx;
 
 // If it is already running, then focus on the window
 g_hMainWindow = FindWindow(g_sWindowClass, g_sTitle);
 if (g_hMainWindow)
 {
 // set focus to foremost child window
 // The "| 0x01" is used to bring any owned windows to the foreground and
 // activate them.
 SetForegroundWindow((HWND)((ULONG) g_hMainWindow | 0x00000001));
 MessageBox(g_hMainWindow, L"Already running.", L"WARNING", MB_OK);
 return 0;
 }
 // Register class
 if (!MyRegisterClass(hInstance, g_sWindowClass)) {
 MessageBox(g_hMainWindow, L"Unable to register class.", L"ERROR", MB_OK);
 return FALSE;
 }
 
 // Получаем реальные физические размеры экрана КПК
 g_phscreen_dx = GetSystemMetrics(SM_CXSCREEN);
 g_phscreen_dy = GetSystemMetrics(SM_CYSCREEN);
 g_phscreen_type = SCRTYPE_UNKNOWN;
 if ((g_phscreen_dx == 480) || (g_phscreen_dy == 480)) { g_phscreen_type = SCRTYPE_VGA; wx = 640; }
 if ((g_phscreen_dx == 240) || (g_phscreen_dy == 240)) { g_phscreen_type = SCRTYPE_QVGA; wx = 320; }
 if (g_phscreen_type == SCRTYPE_UNKNOWN) {
 // Error handling for unknown screen resolution ...
 }
 // Получаем текущую ориентацию экрана (портретная, ландшафтная ...)
 DEVMODE sDevMode = {0};
 sDevMode.dmSize = sizeof(DEVMODE);
 sDevMode.dmFields = DM_DISPLAYORIENTATION;
 ChangeDisplaySettingsEx(NULL, &sDevMode, NULL, CDS_TEST, NULL);
 g_phscreen_orient = sDevMode.dmDisplayOrientation;
 // Создаем квадратное окно - чтобы при поворотах экрана в процессе работы нашей программы - оно все равно закрывало весь экран
 g_hMainWindow = CreateWindow(g_sWindowClass, g_sTitle, WS_VISIBLE, 0, 0, wx, wx, NULL, NULL, hInstance, NULL);
 if (!g_hMainWindow) {
 MessageBox(g_hMainWindow, L"Unable to create main window.", L"ERROR", MB_OK);
 return FALSE;
 }
 // окно должно быть поверх всех остальных окон в системе - чтобы нажатия мыши система не вздумала передать другим окнам!
 SetWindowPos(g_hMainWindow, HWND_TOPMOST, 0, 0, wx, wx, 0);
 ShowWindow(g_hMainWindow, nCmdShow);
 UpdateWindow(g_hMainWindow);
 // прячем разные не нужным нам кнопки, значок клавиатуры, кнопку "start" и т.д.
 SHFullScreen(g_hMainWindow, SHFS_HIDETASKBAR);
 SHFullScreen(g_hMainWindow, SHFS_HIDESIPBUTTON);
 SHFullScreen(g_hMainWindow, SHFS_HIDESTARTICON);
 return TRUE;
 }
 //
 // Entry point
 //
 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
 {
 MSG msg;
 // Store instance handle in our global variable
 g_hInst = hInstance;
 // Perform application initialization:
 if (!InitInstance (hInstance, nCmdShow)) return FALSE;
 // Init graphics engine
 if (!InitGfx()) return FALSE;
 // Устанавливаем таймер на 50мс или 1/20сек.
 SetTimer(g_hMainWindow, 1, 50, NULL);
 // Main message loop:
 while (GetMessage(&msg, NULL, 0, 0))
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 // Убираем, удаляем, чистим ...
 DeinitGfx();
 return 0;
 }



 
 
