Projekt, nad którym będziemy pracować, jest stosunkowo prosty, ale zawiera w sobie ciekawe elementy, szczególnie w kontekście konwersji obrazów na format MacPaint oraz ditheringu. Naszym celem jest przetworzenie obrazu w taki sposób, aby pasował on do ograniczonego rozmiaru wyświetlacza komputerów Mac Plus, który wynosi 512x720 pikseli. Oczywiście MacPaint, program stworzony na te maszyny, ma jeszcze mniejsze okno wyświetlania, ponieważ część pikseli jest zajęta przez pasek narzędzi. W związku z tym rzeczywista szerokość obrazu wyświetlanego w MacPaint wynosi tylko około 400 pikseli.
Naszym zadaniem będzie więc przygotowanie obrazu, zmniejszenie go do odpowiednich rozmiarów, konwersja do odcieni szarości, a następnie zastosowanie algorytmu ditheringu w celu uzyskania czarno-białego obrazu, który będzie odpowiedni do formatu MacPaint. Po zakończeniu procesu obraz zapisujemy w odpowiednim formacie. Istotnym aspektem projektu są dwa kroki: dithering i zapis do formatu MacPaint, dlatego omówimy je dokładniej.
Aby rozpocząć, użyjemy popularnej biblioteki Pythonowej – Pillow, która umożliwia manipulację obrazami. Instalacja biblioteki odbywa się za pomocą prostego polecenia:
Po zainstalowaniu Pillow możemy przejść do kodu, który pozwoli nam wykonać wszystkie niezbędne operacje.
Przygotowanie obrazu
Pierwszym krokiem w naszym projekcie jest wczytanie obrazu z dysku, jego przeskalowanie oraz konwersja do odcieni szarości. Przydatną metodą jest thumbnail(), która pozwala na proporcjonalne zmniejszenie obrazu do wymiarów maksymalnych dla MacPaint. Obraz musi mieć rozmiar nie większy niż 576x720 pikseli, aby zmieścił się w oknie wyświetlania tego programu. Po dokonaniu zmiany rozmiaru obraz zostaje przekonwertowany na odcienie szarości za pomocą metody convert("L"). Zmienna "L" oznacza tryb luminancji, który jest wykorzystywany do reprezentowania odcieni szarości.
W tym kodzie obraz jest najpierw wczytywany i sprawdzany, czy jego rozmiar przekracza dozwolone wymiary. Jeśli tak, zostaje proporcjonalnie przeskalowany. Zastosowanie algorytmu LANCZOS przy zmianie rozmiaru zapewnia najlepszą jakość obrazu.
Algorytm ditheringu
Po przygotowaniu obrazu przechodzimy do jednego z najbardziej interesujących etapów – ditheringu. Dithering to technika stosowana do uzyskiwania efektu „szarej skali” przy użyciu tylko dwóch kolorów, na przykład czerni i bieli. Jednym z najpopularniejszych algorytmów ditheringu jest algorytm rozpraszania błędu (error diffusion). W tym przypadku użyjemy algorytmu Atkinsona, który był wykorzystywany w oprogramowaniu MacPaint.
Dithering polega na tym, że dla każdego piksela obrazu określamy, który z dwóch kolorów – czarny czy biały – jest najbliższy. Następnie obliczamy różnicę pomiędzy wartością szarości piksela a wybranym kolorem, a część tej różnicy rozpraszamy na sąsiednich pikselach. Algorytm Atkinsona rozprasza błąd na sześć pikseli, które znajdują się na prawo i poniżej danego piksela.
Zapis do formatu MacPaint
Po zakończeniu procesu ditheringu, uzyskany obraz zapisujemy w odpowiednim formacie. Proces ten polega na zapisaniu obrazu w formacie, który będzie rozpoznawany przez program MacPaint. Pillow pozwala na zapisanie obrazu do różnych formatów, w tym do GIF-a, jeśli użytkownik tego zażąda.
Inne uwagi
Ważne jest, aby pamiętać, że przy pracy z obrazami MacPaint, obraz musi być odpowiednio przeskalowany i dostosowany do jego wymiarów, aby uniknąć utraty istotnych informacji. Dithering, w tym przypadku algorytm Atkinsona, nie tylko poprawia estetykę, ale również wpływa na autentyczność obrazu, szczególnie w kontekście komputerów Macintosh.
Pillow, mimo że jest potężnym narzędziem, nie rozwiązuje wszystkich problemów związanych z grafiką komputerową, szczególnie w przypadku tak specyficznych formatów jak MacPaint. Wiedza o tym, jak działa dithering, a także zrozumienie algorytmów takich jak Atkinson, może być kluczowe, aby uzyskać pożądany efekt.
Jak działa PPU w NES: Szczegóły techniczne i wpływ na projektowanie gier
W systemie NES PPU (Picture Processing Unit) jest odpowiedzialny za renderowanie obrazu na ekranie, zajmując się zarówno tłem, jak i postaciami (sprite’ami). Jednym z kluczowych aspektów pracy PPU jest zarządzanie pamięcią palety kolorów oraz układem atrybutów, który określa, jak obszary ekranu są kolorowane. Zrozumienie, jak te mechanizmy działają, pozwala twórcom gier lepiej zoptymalizować swoje projekty, by maksymalnie wykorzystać możliwości NES.
Pierwszym elementem, który warto omówić, jest tabela atrybutów. Obszary ekranu w NES są podzielone na 32x32-pikselowe regiony, a każdy z nich ma przypisaną tabelę atrybutów. Tabela ta informuje PPU, jaką paletę kolorów należy zastosować w danym regionie. Każdy wpis w tabeli atrybutów to 1 bajt, który wskazuje na konkretną paletę tła. Dzięki temu różne obszary ekranu mogą mieć różne zestawy kolorów, co umożliwia twórcom gier większą elastyczność w projektowaniu wizualnym. Przykład zastosowania palety ilustruje obrazek z gry Thwaite, gdzie dla każdej zarejestrowanej strefy ekranu wskazano, które palety tła są używane. Ważnym punktem jest to, że palety tła są ograniczone do czterech kolorów, co oznacza, że każda strefa jest w stanie przyjąć tylko jedną z tych palet.
Paleta kolorów w NES jest zdefiniowana przez 3 bajty, z których każdy określa jeden z trzech kolorów. Każdy bajt zawiera 6 bitów, z których wybieranych jest 64 różnych kolorów. W praktyce jednak, ponieważ część z tych kolorów jest bardzo ciemna i bliska czerni, artyści mają do dyspozycji jedynie 54 użyteczne kolory. Przykładowo, jeżeli tło w grze używa palety tła nr 1, możliwe są trzy kolory – odcienie niebieskiego, zieleni i szarości.
Ważnym aspektem pracy PPU jest również zarządzanie pamięcią OAM (Object Attribute Memory). To ona odpowiada za przechowywanie danych dotyczących sprite’ów, czyli obiektów poruszających się na ekranie. NES może jednocześnie wyświetlać maksymalnie 64 sprite’y, z których każdy opisany jest przez 4 bajty w pamięci OAM. Sprite’y mogą być rysowane w dowolnym miejscu na ekranie i mogą mieć różne cechy – na przykład mogą być odwrócone poziomo lub pionowo, a także umieszczone przed lub za tłem. Każdy sprite może korzystać z jednej z czterech dostępnych palet kolorów. Bardzo ważne jest zrozumienie, że sprite’y w NES nie muszą trzymać się sztywno układu siatki pikseli, jak tło – mogą być umieszczone w dowolnym punkcie ekranu.
Każda gra NES musi mieć odpowiednią synchronizację pomiędzy rysowaniem tła a sprite’ów. PPU pracuje z rozdzielczością 256x240 pikseli, co oznacza, że ekran składa się z 240 linii (scanlines), z których każda zawiera 256 punktów (dotów). Proces rysowania ekranu odbywa się od lewej do prawej, od góry do dołu, a każda linia jest rysowana na ekranie podczas jednego cyklu PPU. Cały ekran jest renderowany 60 razy na sekundę w systemie NTSC (lub 50 razy w systemie PAL), co daje 60 klatek na sekundę (FPS). Warto zauważyć, że proces rysowania nie odbywa się natychmiastowo, ale rozciąga się na cały cykl od odświeżenia ekranu, co wpływa na to, kiedy i jak programy mogą zmieniać dane w pamięci PPU. Okresy hblank i vblank (pomiędzy scanlines i klatkami) to momenty, kiedy można zmieniać zawartość pamięci PPU, co pozwala na synchronizację z rysowaniem obrazu.
Pamięć palety w NES jest ograniczona do 4 palet tła oraz 4 palet dla sprite’ów, z których każda składa się z trzech kolorów. Oznacza to, że wszystkie elementy na ekranie muszą być odpowiednio zaprojektowane, by zmieściły się w tych limitach. Gdy program tworzy obraz na ekranie, musi uwzględnić te ograniczenia, a także sposób, w jaki kolory są mieszane, by uniknąć niepożądanych efektów wizualnych.
Poza tym, ważnym aspektem jest to, jak pamięć w NES jest wykorzystywana przez sam procesor. PPU ma swoją pamięć dedykowaną do przechowywania tablic wzorców (pattern tables) oraz tabel atrybutów, a także palet kolorów. Wszystko to jest ograniczone przez pamięć 2KB, co oznacza, że projektowanie gier na NES wymaga bardzo starannego planowania i optymalizacji wykorzystania tej pamięci, by jak najlepiej wykorzystać możliwości systemu.
Zrozumienie szczegółów działania PPU oraz związanych z nim ograniczeń jest kluczowe przy tworzeniu gier na NES. Ograniczona paleta kolorów, pamięć RAM i złożoność synchronizacji z procesorem wymagają od twórców nie tylko umiejętności technicznych, ale również kreatywności, by jak najlepiej wykorzystać dostępne zasoby. Warto również zwrócić uwagę na fakt, że różnice w standardach wideo (NTSC vs PAL) wpływają na sposób wyświetlania kolorów, co powinno być uwzględnione przy projektowaniu wizualnym gry.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский