Pewien czas temu na portegeclub.com pojawiła się zmodyfikowana biblioteka GAPI wykorzystująca kilka funkcji procesora graficznego toshiby G900. Jednak widzę, że sporo osób wciąż nie do końca wie o co w tym wszystkim chodzi i jak tego używać. Więc pozwolę sobie nieco przybliżyć temat i opisać krok po kroku jak przekonać gry do użycia tej zmodyfikowanej wersji GAPI.
A więc co to w ogóle jest całe to GAPI? Otóż nazwa GAPI oznacza
Game
API, jest to biblioteka stworzona w czasach systemów windows CE, w okolicy roku 2000. Pisanie gier pod urządzenia mobilne było wówczas sporym problemem. Wprawdzie wysokopoziomowe funkcje GDI (Graphics Device Interface) pozwalały na tworzenie prostych gier bez znajomości szczegółów sprzętu, na który jest pisane oprogramowanie. O ile GDI nadaje się do gier typu pasjans, czy saper, to jest ogólnie mówiąc dość wolny i powoduje spore problemy przy próbie wyświetlania animacji i w związku z tym nie nadaje się do tworzenia bardziej zaawansowanych graficznie programów. Z kolei najwydajniejsze rozwiązanie - bezpośrednie adresowanie pamięci wideo wymagałoby skompilowania różnych wersji gry praktycznie dla każdego PDA, gdyż sposób dostępu do pamięci wideo może się dość mocno różnić pomiędzy poszczególnymi urządzeniami. Ponieważ same urządzenia korzystające z windowsa CE były dość mocno ograniczone (brak wielokanałowego syntezatora dźwięku, brak sprzętu obsługującego akcelerację 3D, mała ilość pamięci), wersja pełnego DirectX-a dla urządzeń przenośnych po prostu nie miała sensu. Stąd pomysł stworzenia biblioteki, która umożliwi dla programisty bezpośredni dostęp do pamięci wideo oraz klawiszy urządzenia w sposób uniwersalny: odpowiedzialnością producentów stało się aby funkcje GAPI działały zgodnie ze specyfikacją i to na nich została przeniesiona odpowiedzialność stworzenia części gapi stanowiącej pośrednik pomiędzy standardowymi funkcjami wywoływanymi przez programistę, a niestandardowym sprzętem.
Można więc w uproszczeniu myśleć o GAPI jako o mocno ograniczonej wersji DirectX-a.
Mimo, że o czasu WM5 (albo Windowsa Mobile 2003, nie mam tu pewności) możliwy jest bezpośrednio dostęp do pamięci wideo bez pośrednictwa GAPI, biblioteka ta jest wciąż bardzo chętnie stosowana w grach. Powodem takiego stanu rzeczy jest głównie możliwość zachowania kompatybilności ze starszymi systemami.
Jest tylko jeden niewielki problem - GAPI było projektowane w czasach, kiedy palmtopy miały jedną standardową rozdzielczość - QVGA (320x240). Dlatego programy korzystające z GAPI mogą mieć problemy z obsługą współczesnych urządzeń z ekranami o wyższych rozdzielczościach, takimi jak Toshiba G900 ze swoim ekranem WVGA (800x480). Każdy program radzi sobie inaczej z tym problemem: część nie uruchomi się wcale, część będzie wyświetlana w niewielkim prostokącie o rozmiarze 320x240 w rogu ekranu, część przeskaluje się do rozdzielczości VGA. Jednak skalowanie odbywa się zwykle w bardzo uproszczony sposób: przez podwajanie pikseli, a więc postawienie zamiast każdego pojedynczego piksela kwadraciku o rozmiarze 2x2 piksele. Efektem jest obraz zajmujący wprawdzie większą część ekranu, ale z bardzo wyraźnie widocznymi pikselami. Dodatkowym problemem występującym przy uruchamianiu programów GAPI na tosi G900 jest fakt, iż wyświetlenie całego obrazu wymaga narysowania cztery razy większej liczby pikseli niż na urządzeniu QVGA. Dlatego dość częsta jest sytuacja, w której gra chodząca płynnie na 195MHz Wizardzie ledwie działa na 500MHZ Toshibie.
Rozwiązaniem wszystkich tych problemów jest wykorzystanie zmodyfikowanej biblioteki GAPI stworzonej przez użytkownika Elviesss, współodpowiedzialnego za wersję TCPMP wykorzystującą sprzętowe dekodowanie GoForce5500. Samą bibliotekę można pobrać stąd:
http://www.portegeclub.com/forum/viewtopic.php?t=1798Więc w jaki sposób to działa i co nam daje? Biblioteka ta "przekonuje" uruchomiony program, że rozdzielczość ekranu to jedynie 320x240, dzięki czemu sam zapis wartości pikseli do pamięci jest tak samo szybki jak w przypadku urządzeń QVGA. Następnie gotowy obraz o rozdzielczości QVGA jest sprzętowo skalowany na pełny ekran przez GoForce'a z filtrowaniem liniowym, co go lekko wygładza i powoduje, że piksele nie rzucają się aż tak w oczy. Porównanie działania gry w trybie podwajania pikseli (na górze) oraz obrazu po sprzętowym skalowaniu przez zmodyfikowane GAPI (na dole):


Obraz otrzymany za pomocą zmodyfikowanego GAPI ma wprawdzie nieco nieprawidłowe proporcje, ale nie przeszkadza to w graniu, a do tego jest znacznie przyjaźniejszy dla oka.
Więc do jakich gier można to GAPI wykorzystać? Oczywiście tylko do tych, które wyświetlają obraz za pomocą GAPI. Ale jeśli gra po uruchomieniu wyświetla się w małym kwadraciku w rogu ekranu albo w trybie podwajania pikseli, jest duża szansa na to, że używa właśnie GAPI.
Problem w tym, że biblioteka GAPI (gx.dll) jest już na tyle standardowa, że jest dołączana w każdym ROMie dla pda i w normalnej sytuacji gra będzie korzystała właśnie z wersji zawartej w ROMie, której nie można po prostu nadpisać. Są dwie metody na to, aby gra skorzystała z wersji zmodyfikowanej: pierwszą jest wgotowanie zmodyfikowanego GAPI do ROMu zamiast standardowej biblioteki gx.dll. Jednak należy pamiętać że ta modyfikacja jest wciąż wczesną wersją i może powodować problemy z niektórymi programami. Dlatego bezpieczniejszym sposobem jest umieszczenie zmodyfikowanej biblioteki w folderze gry pod inną niż standardowa nazwą (np. gx.dl_) i zmodyfikowanie samej gry tak, aby użyła właśnie tego pliku. W podanym wyżej wątku na portegeclub.com są wprawdzie zamieszczone programy, które spróbują automatycznie zmodyfikować plik gry, jednak osobiście wolę to zrobić ręcznie. Przy okazji można zobaczyć czy dana gra korzysta z GAPI, czy nie.
Zanim się do tego zabierzemy, będziemy potrzebować edytora szesnastkowego. Podam procedurę modyfikacji na przykładzie doskonałego darmowego edytora tekstu
notepad++ z pluginem
hexEdit (o ile dobrze pamiętam, jest on dołączony w standardowym instalatorze notepada++). Oczywiście można użyć dowolnego innego edytora, jak na przykład EDh bezpośrednio na pda.
A więc plik wykonywalny (.exe) wybranej gry kopiujemy na PC-ta i otwieramy za pomocą notepada++. Przy okazji warto zmienić nazwę kopii, która pozostała na pda żeby w razie problemów mieć możliwość uruchomienia wersji oryginalnej. Plik domyślnie będzie otwarty w trybie tekstowym, zupełnie dla nas nieprzydatnym więc trzeba najpierw przełączyć edytor w tryb szesnastkowy:

Następnie trzeba poszukać w pliku odniesienia do biblioteki gx.dll. Czyli wciskamy Ctrl+F, zmieniamy tryb wyszukiwania z "Hexadecimal" na "ANSI string" i wpisujemy jako zapytanie "gx.dll":

Z reguły w pliku występuje tylko jedno takie odniesienie, które musimy zmienić. Dane ASCII po prawej stronie można edytować jak zwykły tekst, więc wystarczy zamienić ostatnie 'l' z "gx.dll" na '_':

Po tej czynności należy plik zapisać i przenieść z powrotem na urządzenie.
Czasem jednak wyszukiwanie gx.dll nie przyniesie żadnych rezultatów, sytuacja taka ma miejsce w na przykład w emulatorze fpsece:

Nie oznacza to od razu, że dana gra nie korzysta z GAPI. Czasem nazwa odniesień do bibliotek dll jest zakodowana w inny sposób (unicode) - zależy to od sposobu linkowania biblioteki. W każdym razie bajty nazwy są wtedy oddzielone zerami. W takiej sytuacji już po wpisaniu w wyszukiwarce "gx.dll" w trybie "ANSI string", należy przełączyć ją na tryb szesnastkowy. Spowoduje to konwersję wpisanego zapytania na odpowiadającą mu sekwencję wartości szesnastkowych:

Teraz wystarczy tylko wstawić pomiędzy wartości poszczególnych znaków zera i ponowić wyszukiwanie:

Podobnie jak w pierwszym przypadku, zamieniamy ostatnią literkę 'l' na '_' i zapisujemy plik, po czym przenosimy go z powrotem na urządzenie, do folderu gry.
Teraz mały eksperyment: próbujemy uruchomić zmodyfikowany plik. Jeśli otrzymamy komunikat, że nie można uruchomić z powodu brakujących skłądników, oznacza to że gra nie chce już korzystać z oryginalnego gx.dll a więc modyfikacja (prawdopodobnie) się powiodła. Po tym eksperymencie rozpakowujemy gx.dl_ oraz GAPI_settings.exe do folderu gry, po czym uruchamiamy program GAPI_settings. Program konfiguracyjny jest w języku chińskim, więc raczej wiele nie uda się z niego wyczytać, jednak proponuję ustawić opcje w sposób następujący:

- Pierwsze pole ustawia jaką rozdzielczość GAPI ma udawać dla pda. Większość programów obsługuje tylko 320x240, więc nie ma sensu tego zmieniać.
- Pierwsza opcja (nieaktywna) odpowiada za skalowanie z zachowaniem proporcji. Nie wiem czemu nie da się jej włączyć - może włącza się automatycznie na XDA Flame?
- Druga opcja aktywuje rozciąganie obrazu na pełny ekran (bez niej gra będzie się wyświetlała w małym prostokącie rogu ekranu).
- Trzecia - rysowanie bezpośrednio na głównej powierzchni. W teorii to może nieco przyspieszyć przerysowywanie ekranu, ale nie zawsze mi działała.
- Czwarta opcja - skalowanie koordynatów rysika. Ponieważ gra jest oszukiwana, że rysuje obraz na ekranie 320x240 należy przeskalować koordynaty rysika tak, żeby np. kliknięcie na środku ekranu było odczytane jako 160,120 (czyli środek wirtualnego ekranu), a nie 400, 240 (czyli rzeczywiste współrzędne rysika), inaczej właściwie nie da się obsługiwać przycisków ekranowych.
Po potwierdzeniu ustawień w katalogu gry zostanie wygenerowany plik gx.ini. W przyszłości będzie można go wykorzystać do innych programów bez potrzeby uruchomiania narzędzia konfiguracyjnego. Wystarczy go skopiować wraz z plikiem gx.dl_ do katalogu kolejnej gry.
I część najważniejsza, czyli jak to wygląda w praktyce (Metroid Fusion emulowany na GBA, Aero Fihters emulowany na SNES i Tomb Raider - natywnie pod WM):
Przepraszam za nieciekawą jakość ale aparat niestety ma wyłączone ręczne ustawienie ostrości w trybie video i nieco głupieje przy tak małej odległości. Sterowanie klawiaturą podłączoną przez USB, bo jakby aparat widział w kadrze jeszcze palce obsługujące grę to zupełnie by zdurniał

Poza tym nieco lepiej wygląda to po otwarciu bezpośrednio na YT (większe okno).
W każdym razie widać jak to w ogóle chodzi. Jak na mój gust nawet da się grać w emulowane tytuły

"Metroid: Zero Mission" z GBA już zdążyłem przejść używając do sterowania D-Pada i przycisków ekranowych. Kakt, że czasem zdarza się zacięty przycisk (tosia raportuje przycisk jako wciśnięty nawet po puszczeniu), ale nie zdarzało się to na tyle często żeby zepsuć zabawę.
Oczywiście sporo zależy od samej gry i np. "Duke Nukem 3D" na GBA już chodzi znacznie gorzej i trudno uznać ten tytuł za grywalny, nie wspominając o problemach ze sterowaniem - często trzeba tam używać kilku przycisków na raz co jest dość trudne przy układzie klawiszy toshiby. G900.
Kilka uwag:
- Wygląda na to, że niektóre gry odczytują rozdzielczość ekranu bezpośrednio z systemu, a nie z GAPI (np. Call Of Duty). Więc jeśli program po uruchomieniu ze zmodyfikowanym gapi wygląda nieprawidłowo (poprzesuwane przyciski, wyświetlanie obrazu tylko w wąskim poziomym pasku na środku ekranu), można spróbować uruchomić ją z wVGAfix-em. Gra wciąż będzie wyświetlana na pełnym ekranie, ale odczytanie rozdzielczości jako VGA a nie wVGA spowoduje, że wyświetlany obraz będzie miał prawidłowe proporcje.
- Część gier może odmówić uruchomienia pomimo, że edycję wykonaliśmy prawidłowo. Może to być spowodowane tym, że plik był podpisany. Wtedy jakakolwiek zmiana zawartości spowoduje że podpis będzie nieprawidłowy. System z reguły nie sprawia problemów z plikami zupełnie pozbawionymi podpisu, ale mimo to jeśli plik jest podpisany, ale podpis jest błędny, odmówi uruchomienia. W takiej sytuacji trzeba przed edycją zdjąć podpis za pomocą programu unsigner - po prostu przeciągamy dany plik na ikonkę unsigner.exe, ale najlepiej żeby oba były w tym samym katalogu.
Sam program i więcej informacji można zaleźć tu:
http://forum.xda-developers.com/showthread.php?t=432041
Po edycji pliku można go znów podpisać programem signer (program i instrukcja w wątku podanym powyżej).
- Czasem może się zdarzyć że w pliku exe nie da się odnaleźć odwołania do gx.dll mimo, że najwyraźniej korzysta z GAPI. Nie jestem specjalistą w tej dziedzinie, ale chyba może to być spowodowane tym, że plik jest spakowany (np. upx-em), lub w jakiś sposób zaszyfrowany (np. w celu utrudnienia dekompilacji).
- Czasami z kolei zdarza się przeciwna sytuacja - istnieje odniesienie do gx.dll, ale modyfikacja nic nie daje (chyba pocket quake tak miał). Może się to zdarzyć kiedy gra korzysta z GAPI jedynie do odczytu stanu klawiszy i rysika, a obraz rysuje w inny sposób.
- Nie jestem do końca programistą, więc pomimo wszelkich starań część informacji technicznych może się okazać nie do końca prawidłowa. Wobec tego będę wdzięczny za ewentualne uwagi w przypadku znalezienia jakiejś ewidentnej bzdury

Uff, ale się rozpisałem

Mam nadzieję, że nie pójdzie to na marne i komuś pomoże
