Dokładny czas na wielu platformachGry i inne podobne aplikacje wymagają precyzyjnego pomiaru czasu, aby realizować obliczenia związane z fizyką, animacją, itp. Jak niemal wszystko, API potrzebne do tego celu jest różne w zależności od platformy, czyli (głównie) systemu operacyjnego. Dzisiaj chciałbym pokazać, jak wygląda to na dwóch najpopularniejszych systemach: Windows i POSIX (a więc między innymi na wszelkiego typu Linuksach).
Interfejs programistyczny systemu spod znaku okienek udostępnia dwie funkcje od dokładnego mierzenia czasu. Są to QueryPerformanceFrequency i QueryPerformanceCounter. Tę pierwszą wywołuje się tylko raz, a jej wynikiem jest częstotliwość wewnętrznego systemowego zegara, który służy do precyzyjnego pomiaru upływającego czasu. Wyrażana jest ona w liczbie "tyknięć" na sekundę i na dzisiejszym sprzęcie może być bardzo duża, bo liczona w (kilku(nastu/dziesięciu)) milionach.
Druga funkcja jest używana nieporównywalnie częściej, gdyż to ona zwraca aktualną wartość zegara, czyli liczbę jego "tyknięć". Stąd wynika, że obliczenie tej wartości w sekundach wymaga podzielenia rezultatu QPC przez uzyskaną wcześniej częstotliwość:
Używana tu unia LARGE_INTERGER to nic innego, jak zwykła liczba 64-bitowa.
W systemach POSIX-owych rzecz jest odrobinę prostsza, jako że tutaj dokładność zegara jest ściśle ustalona. Funkcja gettimeofday (z nagłówka sys/time.h) zwraca rezultat z precyzją mikrosekundową w postaci struktury timeval:
Część odpowiadającą niepełnym sekundom (pole tv_usec) trzeba więc podzielić przez milion.
Chcąc mieć bardziej uniwersalne rozwiązanie, możemy napisać klasę opakowującą zegar z implementacją kontrolowaną docelową platformą, na którą kompilujemy:
double GetTicks() const
{
#ifdef _WINDOWS
LARGE_INTEGER counter;
QueryPerformanceCounter (&counter);
return counter.QuadPart / (double)freq.QuadPart;
#else
struct timeval tv; gettimeofday (&tv, 0);
return tv.tv_sec + tv.tv_usec / 1000000.0;
#endif
}
};
Można by na koniec zapytać jeszcze, co tak naprawdę znaczy zwracana wartość zegara. Kiedy wynosi ona zero?... Otóż wbrew pozorom odpowiedź na to pytanie nie jest istotna, bo w praktyce interesuje nas tylko interwał czasowy, tj. różnica między dwoma wskazaniami timera. To na jej podstawie liczymy zmianę w prędkościach obiektów, klatkach animacji czy w końcu niezbędnie konieczną do wyświetlenia wartość FPS :)
Jak naprawić GRUB-a
Jeśli oprócz systemu okienkowego rodem z Microsoftu mamy też jakiegoś *niksa, to reinstalacja Windows będzie dla nas miała jeden nieprzyjemny efekt uboczny. Otóż instalatory Okienek radośnie nadpisują sektor startowy dysku (czyli MBR - Master Boot Sector), przez co Windows staje się jedynym systemem dającym się uruchomić w zwykły sposób. Ot, zwyczajowe MS-owe praktyki monopolistyczne ;-)
Jak temu zaradzić? Trzeba oczywiście przywrócić boot sector do właściwego stanu, co oznacza ponowne zainstalowanie używanego przez nas wcześniej bootloadera. W większości przypadków (jeśli mówimy o Linuksie jako drugim systemie) jest nim GRUB; w takim wypadku jego ponowne zainstalowanie wymaga:
Tyle powinno wystarczyć, by po ponownym uruchomieniu komputera z tego dysku pojawiło się nam menu bootowania GRUB-a. Przy odrobinie szczęścia oba systemy będą więc uruchamiały się normalnie ;)
Operacja reinstalacjaWczorajsza premiera Windows 7 to dobry pretekst, żeby nowy system w końcu przetestować - zwłaszcza, że większość opinii, których o nim słyszałem, była zdecydowanie przychylna. W połączeniu z faktem, iż system operacyjny na moim laptopie już od dobrych paru miesięcy domaga się skrócenia swoich cierpień, otrzymujemy tylko jeden logiczny wniosek: czas zakasać rękawy i zabrać się za reinstalację!
Ktokolwiek choć raz zajmował się ponownym stawianiem systemu od zera wie, że czynność ta nie należy do relaksujących. Chociaż drobne komplikacje są praktycznie gwarantowane: a to zapomnimy o jakimś sterowniku, a to zapodziejemy gdzieś numer seryjny systemu, i tak dalej. Posiadanie komputera "zapasowego" (w moim przypadku tradycyjnego - stacjonarnego) znacznie redukuje dolegliwość takich problemów, ale nawet i w tej sytuacji warto się do całej operacji dobrze przygotować.
I właśnie dlatego sporządziłem poniższą listę kontrolną czynności, które dobrze jest wykonać przed rozpoczęciem zabawy w reinstalację systemu. Nie gwarantuję oczywiście, że da się przy jej użyciu uniknąć wszelkich kłopotów. Powinna być ona jednak w dużym stopniu pomocna. A wygląda ona następująco:
Pamiętaj też o wszelkich kluczach produktów czy numerach seryjnych, jeśli któryś z systemów ich wymaga.
Uff, spora ta lista. Jej rygorystyczne przestrzeganie może nie zawsze jest konieczne, ale nie wydaje mi się, żeby mogło komukolwiek zaszkodzić :) Akurat w przypadku tej nieczęsto (i coraz rzadziej) wykonywanej czynności, jaką jest reinstalacja systemu, zbytnia przezorność na pewno nie zawadzi.
Oswajanie pingwinaKilka tygodni temu zostałem "delikatnie przekonany" przez tzw. wyższe czynniki (czyli, jak nietrudno się domyślić, studia) do zawarcia bliższej znajomości z systemem Linux. Nie jest oczywiście tak, że w ten sposób nawiązałem dopiero pierwszy poważny kontakt z tym systemem. O nie, wręcz przeciwnie. Dotąd jednak próby utrzymania bliższych relacji nie skutkowały wieloma sukcesami. Czyżby teraz miało być inaczej?...
To całkiem możliwe, bo przecież Linux jest systemem dla koneserów, którzy uwielbiają, jak to się ładnie określa, "dostosowywać system do swoich potrzeb". Można zatem optymistycznie przypuszczać, że mimo niezbyt korzystnego pierwszego wrażenia produkt spod znaku pingwina będzie zyskiwał przy bliższym poznaniu. Jak dotąd okazało się to mniej więcej prawdą. W każdym razie upływający czas działa w tym przypadku zdecydowanie na korzyść.
Linuksy się bowiem zmieniają i to zazwyczaj na lepsze. Chociażby fakt, że istnieje taka dystrybucja jak Ubuntu, która po prostu działa i nie sprawia żadnych problemów np. ze sprzętem, zdecydowanie przemawia na ich korzyść. W końcu mało kto chciałby wpierw przekopywać się przez pliki konfiguracyjne i (częściej) grupy dyskusyjne, by skonfigurować poprawnie swoją kartę graficzną czy połączenie z Internetem. A zdaje mi się, że mniej więcej tak to wyglądało jeszcze kilka lat temu - naturalnie pod warunkiem, że było się nowicjuszem z dużą dozą samozaparcia, a nie linuksowym ekspertem, dla którego sprawa nie przedstawia większego problemu.
Jednak trzeba od razu wyraźnie stwierdzić: ani Ubuntu, ani jakakolwiek inna dystrybucja Linuksa nie jest realną alternatywą dla wszystkich użytkowników Windows. I jest tak wcale nie dlatego, że do zastosowań domowych Linux jest systemem złym. Chodzi raczej o to, że z pewnego punktu widzenia jest on nawet zbyt dobry. Oferuje on po prostu za dużo, by początkujący użytkownik komputera mógł to wszystko udźwignąć. Co z tego, że okienka są przejrzyste i dobrze zorganizowane, a dostęp do dowolnych opcji nie sprawia problemu? Dla początkującego będzie to nadmiar szczegółów, który go bardzo szybko przytłoczy. Tak, Linux nie myśli za użytkownika i nie prowadzi go za rączkę kreatorami i dymkami z podpowiedziami - i chwała mu za to. Wiele osób uzna to jednak za wadę i będą miały sto procent racji.
Mimo to nie sądzę, aby można było uważać to za problem. Jako system do użytku osobistego Linux powinien bowiem celować raczej w zaawansowanych i ewentualnie średnio zaawansowanych użytkowników komputerów. Mówię oczywiście o takich osobach, które ani nie cierpią na wrodzoną pingwinofilię (bo ich przekonywać nie trzeba), ani nie są zagorzałymi zwolennikami Okienek, którzy nigdy zdania nie zmienią. Jeśli ktoś ma wątpliwości, czy takie osoby w ogóle istnieją, to informuję, że sam do takich właśnie użytkowników od dłuższego czasu należę ;P I dopiero teraz mogę ostrożnie powiedzieć, że Linux powoli staje się dla takich osób całkiem rozsądną alternatywą. Pewnie jednak broda Stallmana urośnie jeszcze o kilka długości, zanim system ten zacznie na poważnie podbierać użytkowników Windowsowi.
Ja sam muszę stwierdzić, że z Linuksem jak najbardziej dałoby się żyć na co dzień. Wymagałoby to oczywiście zmiany kilku nawyków, ale z punktu widzenia użytkownika jest jak najbardziej wykonalne. Niestety (a właściwie stety) jestem też programistą, i to gier (a przynajmniej lubię się tak nazywać ;D) - co sprawia, że myślenie o przesiadce w zasadzie nie wchodzi w grę.
Potrafię przy tym bez problemu podać trzy bardzo konkretne powody takiej postawy. Według istotności, nazywają się one kolejno: DirectX, Visual Studio i .NET. Wiem naturalnie, że istnieje przecież OpenGL. Jestem też całkowicie świadom istnienia niezłych środowisk programistycznych dla Linuksa, w rodzaju Eclipse, KDevelop, Anjuty czy vima + GCC (;-]). I wreszcie, nie umknęło mi również Mono. To wszystko bardzo piękne, ale, jak wiadomo, człowiek jest istotą leniwą, a przyzwyczajenie i wygoda to w tym przypadku niezwykle cenne wartości :)
To jednak nie powinno przeszkadzać w tym, aby znać i cenić dobre rozwiązania - nawet jeśli samemu się z nich (zbyt często) nie korzysta.
POSIX-owaniePOSIX (Portable Operating System Interface) to taki śmieszny "standard dla systemów operacyjnych", opracowany przez znane skądinąd konsorcjum IEEE. Celem jego stworzenia było zapewnienie jak największej zgodności w działaniu (lub niedziałaniu, rzecz jasna) dla aplikacji pracujących pod kontrolą różnych wariantów Uniksa. W tym celu określone jest pokaźnych rozmiarów API, które zajmować ma się takimi rzeczami jak procesy, wątki, sygnały, I/O, gniazda sieciowe, i tak dalej.
To, co POSIX w tym zakresie teoretycznie oferuje, jest w gruncie rzeczy całkiem zadowalające. Standard nie zabrania zresztą, by implementujące go systemy operacyjne dodawały do tego jakąś własną funkcjonalność.
![]()
Dlaczego więc zgodność poszczególnych systemów z POSIX-em jest w przybliżeniu odwrotnie proporcjonalna do ich popularności? :-) Wbrew pozorom te co bardziej znane, jak różnego rodzaju BSD i dystrybucje Linuksa, nie są pod tym względem doskonałe. Jedynie znacznie bardziej specyficzne Solarisy, QNX-y oraz, co ciekawe, Mac OS X spełniają standard POSIX-a w pełni.
A co z naszymi ulubionymi okienkami? W ich przypadku jesteśmy oczywiście bardzo, bardzo daleko... ale tylko do czasu. Windows można bowiem dość prosto doprowadzić do pełnej zgodności przy pomocy takich pakietów jak Microsoft Windows Services for UNIX czy Cygwin. Może to być dobra pomoc dla tych, którzy chcą pisać przenośne aplikacje bez opuszczania przyjaznego środowiska okienek.
Okno na pingwinaCzasami przydaje się posiadanie więcej niż jednego operacyjnego na jednym komputerze. Jeżeli oba używają tego samego systemu plików, to zwykle nie ma problemu z wymianą danych.
A co zrobić, jeżeli tak nie jest - czyli na przykład chcemy dostać się z poziomu Linuxa do plików używanych w Windows lub odwrotnie? W jedną stronę jest łatwo: większość dystrybucji Linuxa obsługuje przynajmniej odczytywanie z partycji NTFS, a niektóre automatycznie montują znalezione woluminy, które korzystają z tego systemu plików.
Jeżeli zaś chodzi o operację odwrotną, to naturalne Windows nie patrzy tak przychylnie na inny system operacyjny. Wbudowana w okienka obsługa różnych systemów plików nie obejmuje ext2 i ext3, czyli tych używanych w ogromnej większości Linuksów. Tutaj mogą pomóc tylko zewnętrzne narzędzia.
Jednym z nim jest Ext2 IFS. Ma on tę zaletę, że działa jak sterownik, a nie np. wtyczka do Eksploratora, Total Commandera czy innego menedżera plików. Dzięki temu podmontowane partycje linuksowe są widoczne w całym systemie.

Można z nich korzystać właściwie tak samo jak z dysków NTFS, czyli odczytywać i zapisywać pliki, katalogi, zmieniać etykiety woluminów, itp. Nie trzeba też kopiować plików tam i z powrotem, aby je modyfikować.
Sam nie używam Linuksa zbyt często, ale taki sterownik jest bardzo wygodny. Chociaż prawdopodobnie dostęp do partycji ext3 z Windows sprawia, że Linuksa uruchamiam nawet jeszcze rzadziej niż wcześniej ;)