freepascal.ru • Просмотр темы - Графический движок переделка с С++ на Pascal
 

Графический движок переделка с С++ на Pascal

Модератор: Модераторы

Графический движок переделка с С++ на Pascal

Сообщение MARAT_BEST » 14.04.2010 11:23:21

Добрый день !!!
имеем пример работы графического движка на с++ для 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;
}
MARAT_BEST
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2010 02:47:01

Re: Графический движок переделка с С++ на Pascal

Сообщение FedeX » 14.04.2010 11:40:07

Во-первых те исходники что представлены - очень примитивный "движок", даже и движком его не назвать, кажеться это что-то из туториала..
Во-вторых gdx очень устаревшая штука, в документации описана как deprecated + глюки на разных современных аппаратах. Я сам видел как казалось бы элементарные функции из этого набора возвращали неверные значения разрешения экрана этк... В итоге на некоторых девайсах не работают все игры написанные с использованием этой библиотеки..
Сейчас MS рекомендует использовать DirectDraw Mobile :roll:

У меня было что-то вроде движка, в котором я правда в очередном нападке гнева на свой код покоцал всю функциональность, но он работал под трёмя платформами: Windows, Linux и WinMobile. Использовал OpenGL ( OpenGL ES под WinMobile). Он заброшен в плачевном состоянии где-то на Sourceforge (назывался PhloXLib). Но с OpenGL ES дела ещё хуже - он отлично держиться только на самых дорогих аппаратах, на всех остальных - жуткие софтварные тормоза.

Ещё можно использовать GDI - достаточно быстро под мобилками и везде идёт без глюков, но с оптимизацией прийдёться поиграться..

Ах да забыл - ещё есть SDL - готовый почти движок, работает вроде сносно + кроссплатформенность, бери до используй, но производительности может не хватить..

Демки приаттачил..

Добавлено спустя 24 минуты 41 секунду:
OpenGL ES sample
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Графический движок переделка с С++ на Pascal

Сообщение MARAT_BEST » 15.04.2010 04:22:03

FedeX писал(а):Во-первых те исходники что представлены - очень примитивный "движок", даже и движком его не назвать, кажеться это что-то из туториала..
Во-вторых gdx очень устаревшая штука, в документации описана как deprecated + глюки на разных современных аппаратах. Я сам видел как казалось бы элементарные функции из этого набора возвращали неверные значения разрешения экрана этк... В итоге на некоторых девайсах не работают все игры написанные с использованием этой библиотеки..
Сейчас MS рекомендует использовать DirectDraw Mobile :roll:

У меня было что-то вроде движка, в котором я правда в очередном нападке гнева на свой код покоцал всю функциональность, но он работал под трёмя платформами: Windows, Linux и WinMobile. Использовал OpenGL ( OpenGL ES под WinMobile). Он заброшен в плачевном состоянии где-то на Sourceforge (назывался PhloXLib). Но с OpenGL ES дела ещё хуже - он отлично держиться только на самых дорогих аппаратах, на всех остальных - жуткие софтварные тормоза.

Ещё можно использовать GDI - достаточно быстро под мобилками и везде идёт без глюков, но с оптимизацией прийдёться поиграться..

Ах да забыл - ещё есть SDL - готовый почти движок, работает вроде сносно + кроссплатформенность, бери до используй, но производительности может не хватить..

Демки приаттачил..

Добавлено спустя 24 минуты 41 секунду:
OpenGL ES sample

Спасибо большое !!!! профессиональный ответ !!!! буду посматреть :)
MARAT_BEST
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2010 02:47:01

Re: Графический движок переделка с С++ на Pascal

Сообщение MARAT_BEST » 22.04.2010 11:57:15

А есть ли SDL_ttf, SDL_mixer,SDL_image хедеры для pascal и dll WinCe?
MARAT_BEST
незнакомец
 
Сообщения: 6
Зарегистрирован: 05.03.2010 02:47:01

Re: Графический движок переделка с С++ на Pascal

Сообщение FedeX » 23.04.2010 01:45:28

Не помню - заголовки вроде были , надо порыться в офф дистре паскаля для ВинЦе. Насчëт длл - сложнее, даже ту что в демке пришлось компилять самому... новсеравно не советую с ними мучиться - насчëт звукового движка движка можно взять BASS (есть соответствующая версия), а картинки грузить и юитмап шрифты лучше вручную имхо.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир


Вернуться в WinCE

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru