Retrospektif: Mission GenocideOldum olası pek severim Aralık ayını. Yılbaşı hazırlıklarına çok önceden başlar, o sene satın aldığım tüm oyunları Aralık ayı içerisinde tekrar gözden geçiririm. Bir bakıma o yılın retrospektifini yaparım. Tıpkı 1987 Aralık ayında olduğu üzere…
Ancak, o sene bir istisna oldu! 1987’nin bitişine günler kala yeni yıl hediyem geldi:
Mission Genocide. Karaköy İskelesi’ndeki gazeteciden satın aldığım Amstrad Computer User dergisi Temmuz sayısının kapağındaki "the smoothest shoot-em-up ever" ibaresini okuduğum günden beri,
"Spindizzy’nin programcısı Paul Shirley’nin elinden çıktığına göre, elbet vardır bir hikmeti!" diyerek heyecanla bekliyordum bu oyunu. Firebird tarafından 1.99 GBP fiyatla satışa sunulan, "budget price" kategorisine giren, cep yakmayan bir oyundu bu. Genelde bu tür oyunlar, 7-10 GBP fiyata satılan "full price" oyunların yanında ikinci sınıf olarak nitelenir, biraz küçümsenerek bakılırdı. Acaba bu da o vasat oyunlardan biri miydi? Amstrad Computer User dergisi, her zaman olduğu üzere biraz abartmış olabilir miydi?
"Denemeye değer!" diyerek, oyunu kasetten yüklemeye başladım. "Loading Screen" olarak bilinen yükleme ekranlarına karşı takıntı derecesinde özel ilgi ve bilgim olması sebebiyle, büyük bir heyecanla nefesimi tuttum… Birkaç dakika sonra karşıma çıkan mezar taşı kadar soğuk, estetikten yoksun, adeta 1984 yılından kalma naftalin kokulu bir Amsoft oyunu kalitesizliğindeki yükleme ekranını görünce, tam anlamıyla hayal kırıklığına uğradım. İçimden,
"Zaten 2 poundluk oyun bu kadar olur!" dedim.
Sabırla oyunun yüklenmesini bekledim.
"Keşke daha hızlı yüklese de, kurtulsam şu berbat çizimden!" diye düşünürken, nihayet çilem doldu. Adeta görme engelliler için hazırlanmış olan ana menü karşıma çıktı! Font ve renk seçimi yarama tuz döktü. Artık hiç şüphem yoktu; bu oyun, tıpkı fiyatı gibi "ucuz" bir oyundu.
İçimden lanet okuyarak, oyuna başlamak için ateş tuşuna bastım… O anda elektrik çarpmışa döndüm; 50Hz ekran tazeleme hızında adeta arcade edası ile yağ gibi akan bir shoot’em-up karşıma çıktı. Ağzım açık kaldı!
Bir an için,
"Acaba Atari’de River Raid mi oynuyorum?" diye şüpheye düştüm, bocaladım. Kafamda dönüp duran
"Z80’de bunu yapmak mümkün mü?", "Acaba CRTC’yi nasıl programladı?", "Her 20ms’de bir ekran kaydırırken, sprite basmak için gereken zamanı nereden buldu?" benzeri sorular sebebiyle oyunu oynamayı bıraktım. Yerimden kalkıp pencereye gittim, derin derin düşünmeye başladım. Tam anlamıyla teknik bir aydınlanmaydı bu… Sağolsun annem, tatlı bir tonla imdadıma yetişti;
"Çok daldın evladım, şunu kırtla da zihnin açılsın" diyerek, her akşamüzeri olduğu üzere kakaolu bisküvi eşliğinde çayımı getirdi. Bir yandan mutlu-mesut bisküvimi çaya batırırken, öte yanda da kafamın içinde kuyruğunu kovalayan tilkileri dizginlemeye çalışıyordum. Artık elimde kadim dostum Alcofribas’ın başının etini yiyebileceğim yeni bir gündem maddesi vardı!
Hemen kolları sıvadım. Sanyo M7700K model teybime, dönemin nadide stereo kanallarından olan Polis Radyosu’ndan özenle kaydettiğim Jean-Michel Jarre’ın 1981 yılı konser albümü
Les Concerts en Chine (The Concerts in China) kasedini koydum. Amstrad Computer User’daki makaleyi tekrar tekrar okudum… Metinde ilgimi çeken tek cümle şu oldu;
"The graphics within Mission Genocide are stored compressed in four colors, and to generate them Paul uses his own sprite designer".
Bu cümlede iki sıradışılık vardı:
1.) Oyun Mode 0’da çalışıyor. Bu modda toplam 16 renk var. Acaba Paul Shirley neden sadece 4 renk kullanmış olabilir?
2.) Sözü edilen 4 rengin compress edilmesiyle kastedilen nedir?
Oyunu tekrar açtım. Bir yandan oyunu oynarken, bir yandan da ekrandaki renkleri saymaya başladım. Birkaç dakikalık gözlemin ardından, tüm sprite’ların toplam 4 renk, arka planın da "sprite’lardan farklı" toplam 4 renkten oluştuğunu idrak ettim.
"Sanırım işin sırrı burada! Sprite ve background asla aynı rengi paylaşmıyor. Ayrıca, her iki taraf da 4 renkten fazlasını kullanmıyor" diyerek Amstrad’ımın arkasında takılı olan Romantic Robot Multiface 2’nin freeze tuşuna bastım. CRTC’nin aktif renk register’larına gidip tüm paleti önümdeki kağıda not ettim. Sonra oyunu kaldığı yerden devam ettirip, not ettiğim renkleri Amstrad User Manual’daki renk paleti ile karşılaştırdım. Mode 0’da aynı anda kullanılabilen 16 renkten sadece 8’i kullanılmıştı. Hangi renklerin kullanılmadığını da ayrıca not ettim. Artık elimde kullanılan ve kullanılmayan tüm renkler yazılı olarak mevcuttu.
Amstrad’a reset atıp, BASIC ile Mode 0’da çalışan minik bir routine yazdım. Önce kullanılan renkleri ekrana bastırmak için pixel encoder yazdım, ardından da kullanılmayan renkler için. Elbette basit bir iş değildi bu. Ne de olsa Amstrad’ın abuk mimarisi sebebiyle, Mode 0’da her 2 pixel 1 byte içine paketlenerek ekran hafızasına yazılıyordu. Maalesef bu pixellerin dizilişi de ardışık değildi.
bit 7: pixel 0 bit 0
bit 6: pixel 1 bit 0
bit 5: pixel 0 bit 2
bit 4: pixel 1 bit 2
bit 3: pixel 0 bit 1
bit 2: pixel 1 bit 1
bit 1: pixel 0 bit 3
bit 0: pixel 1 bit 3
Açıkcası, daha pixel encoder’ı yazarken ne olup bittiği kafamda oturmaya başlamıştı.
İlk renk (00) daima şeffaf olacak şekilde;
2 bit = tüm sprite’ların ortak kullandığı 4 renk
2 bit = background’ın kullandığı 4 renk
benzeri bir gruplama yapılmış olmalıydı.
Her pixel için 4 bit (16 renk) yerine sadece 2 bit (4 renk) kullanılıyordu. Demek ki diğer iki bit, sprite’ın arkaplandan temizlenmesi sırasında kullanılmak üzere saklanıyordu. Ekranda aynı anda toplam 8’den fazla renk olmaması, problemi çözmemi hızlandırmıştı. Artık emindim; bu oyun benim kodlamaya alışık olduğum
(sprite AND mask) OR background
yöntemini kullanmıyordu. Sadece bitleri açıp kapatarak sprite yazma/silme işlemlerini gerçekleştiriyordu. Örneğin, arkaplanın üzerine sprite yazabilmek için sprite’a ait bitleri açmak, sprite’ı silmek için de aynı bitleri kapatmak yetiyordu.
Yukarıdaki tabloya göre, t anındaki pixel 0 (byte içine encode edilen ilk pixel)
bit 7: pixel 0 bit 0
bit 5: pixel 0 bit 2
bit 3: pixel 0 bit 1
bit 1: pixel 0 bit 3
olduğuna göre, bu 4 bit aslında 2 + 2 şeklinde paketleniyordu.
bit 7: background bit 0
bit 5: sprite bit 0
bit 3: background bit 1
bit 1: sprite bit 1
Bu durumda,
HL’nin t anındaki sprite pixeli
DE’nin t anındaki background pixeli
temsil ettiğini varsayarsak, sprite basmak için
LD A, (DE)
OR (HL)
LD (DE),A
yeterli oluyordu. Aynı mantıkla,
HL’nin t anındaki orijinal background pixeli
DE’nin t anındaki sprite’lı background pixeli
temsil ettiğini varsayarsak, sprite silmek için
LD A, (DE)
AND (HL)
LD (DE),A
yapmamız yeterliydi. Böylece, arkaplanı sakla/tazele işlemine hiç gerek kalmıyordu. Evet, bu iş için toplam 8 renkten vazgeçmek gerekiyordu, ama elde edilen 50Hz performans için değerdi doğrusu.
Bu olaydan tam 5 sene sonra, Amiga için yazılmış 3 oyunu STe öncesi blittersız Atari ST modellerine port etmem gerekmişti. Zor bir projeydi bu, çünkü Amiga’nın blitter ile yapabildiklerini Atari ST üzerinde sadece M68000 kullanarak yapmak gerekiyordu. İşte tam bu noktada, yukarıda anlattığım teknikten ilham alarak Assembly ile blitter gibi çalışan bir modül yazmış, 3 oyunun port işlemlerinde
Mission Genocide’dan öğrendiğim bit-switch tekniklerine benzer yöntemlerle projeleri tam zamanında teslim edebilmiştim. Sanırım oyun geliştirmenin en keyifli yanı, reverse engineering yaparak kırdığınız her oyundan yeni bir şey öğreniyor olmanız. Bu bağlamda,
Mission Genocide’a ve programcısı Paul Shirley’e teşekkür borçlu olduğumu açıkça ifade edebilirim.
Teşekkür borçlu olan tek kişi ben değilim elbet.
Mission Genocide’ın Z80 ve CRTC uyumu adına sergilediği müthiş performans, Amstrad için yeni bi dönemin habercisi olmuştu. 1987’den sonra piyasaya çıkan native (ZX Spectrum'dan port edilmemiş) Amstrad oyunları, CRTC’nin esnek kullanımı konusunda Paul Shirley’nin açtığı yoldan ilerledi. 2016 yılında preview’ı yayınlandığında çok ses getiren Batman Group oyunu
Pinball Dreams bile, ekranı yukarı/aşağı kaydırmak için
Mission Genocide’ın "rupture" tekniğini
birebir kullanmıştı!
Tüm bunları neden mi anlattım?
Eğer Amstrad üzerinde güzel oyunlar oynamak istiyorsanız, ZX Spectrum’dan port edilenleri değil, Amstrad’a özel kodlanan oyunları oynamanızı tavsiye ederim. Her birinin ilginç hikayesi var.
Mission Genocide gibi içinde birden fazla "trick" içeren oyunlar ise en keyifli olanları. Umarım bir gün onları da kaleme alacak vaktim olur. O güne dek, ilk göz ağrım ZX Spectrum, emektar dostum Amiga, zeropage canavarı C64, vb. platformlar için Retrojen Forum üyelerinin kaleme alacağı oyun/demo tecrübelerini okuyacağımı umuyorum. Bu postun, o heyecanın kıvılcımı olmasını içtenlikle diliyorum.