2 puan yazan GN⁺ 2023-07-29 | 1 yorum | WhatsApp'ta paylaş
  • Adaptive Tile Refresh (ATR), Commander Keen 1~3’ün EGA’nın yavaş tam ekran yenilemesinden kaçınmak için ekranın tamamını değil, yalnızca değişen karoları yeniden çizecek şekilde geliştirdiği bir kaydırma tekniğidir
  • EGA mode Dh, 320x200 16 renkli ekranı 4 düzleme (C0~C3) ayırarak saklar; 32KiB’lik tüm ekran her karede ISA veri yoluna yazıldığında yaklaşık 5fps ile sınırlı kalır ve 60Hz yenileme zorlaşır
  • ATR, sanal ekran içindeki dikey ve yatay hareketi CRTC_START, OFFSET, PEL yazmaçlarıyla işler; kenara ulaşıldığında jolt ile ekran referansını geri alır ve yalnızca gerekli karoları VRAM üzerine yazar
  • jolt maliyeti yeniden çizilecek karo sayısına bağlıdır; Commander Keen 1 örneğinde 250 karodan yalnızca 40 karo değişmiş, yani tüm ekranın sadece %16’sı yeniden çizilmiştir; çok sayıda tekrar eden karo içeren harita tasarımı performansı belirler
  • Commander Keen 4~6’da ATR yerine, 64KiB VRAM aperture’ının wraparound davranışından yararlanarak sürekli panning yapıp yalnızca yeni ortaya çıkan kenar şeritlerini çizme yöntemine geçildi; bazı Super VGA kartlarında başlatılmamış belleğe girilmesi nedeniyle uyumluluk sorunları oluştu

EGA’da karşılaşılan bant genişliği sınırı

  • Commander Keen, EGA (Enhanced Graphic Adapter) takılı PC’lerde en iyi şekilde çalışıyordu; grafik programlama, yapılandırma yazmaçları ve VRAM’e eşlenen 64KiB bellek penceresi üzerinden yapılıyordu
  • EGA, dahili verileri 4 düzlemde, C0, C1, C2, C3 içinde saklar
    • C0, her 4 bitlik piksel değerinin en düşük anlamlı bitini (LSB) saklar
    • C3, en yüksek anlamlı biti (MSB) saklar
    • Her düzlem 200 satırdan ve satır başına 40 bayttan oluşur
  • 4 bankalı yapı, CRT ekranına yetişecek bant genişliğini sağlamak için tasarlanmıştı ve CRTC 4 baytı paralel okur
  • Commander Keen’in kullandığı EGA mode Dh, 320x200 çözünürlük ve 16 renk sunar
    • mode 10h gibi, 64 renk değeri arasından mürekkebi yeniden yapılandıran yöntemi kullanmaz
    • mode Dh içinde de varsayılan 16 renk içindeki palet renkleri değiştirilebilir; bu, Commander Keen’in basit fade in/out efektlerinde kullanılır

Adaptive Tile Refresh’in kaçındığı tam ekran yeniden çizimi

  • ATR’nin çözdüğü temel darboğaz bant genişliğidir
  • 320x200 pikselin 4 bitlik değerlerini, yani yaklaşık 32KiB veriyi her karede yazmak ISA veri yolu için fazla büyük bir yüktür
  • Tüm ekranı her seferinde yenileyen basit bir döngü yaklaşık saniyede 5 kare seviyesinde kalır
  • EGA’da 4 banka aynı anda yazmanın bir yolu da vardır; ancak ekran temizleme veya Wolfenstein 3D’deki sütun kopyalama için yardımcı olsa da Commander Keen’in kaydırma sorununa uygun değildir

Yazmaçlarla yapılan akıcı kaydırma

  • ATR önce VRAM içinde ekrandan daha büyük bir sanal ekran oluşturur ve CRTC’nin okumaya nereden başlayacağını belirleyen CRTC_START değerini değiştirerek görüntüleme alanını hareket ettirir
  • Dikey kaydırma görece basittir
    • Görünen ekranın üstüne ve altına 16’şar satır eklendiğinde düzlem başına 40 x 232 = 9,280 bayt kullanılır
    • Ekranı bir satır yukarı hareket ettirirken CRTC_START 40 bayt artırılır
    • Bir satır aşağı hareket ettirirken CRTC_START 40 bayt azaltılır
  • Yatay kaydırma OFFSET yazmacı ile PEL yazmacını birlikte kullanır
    • OFFSET 2 olarak ayarlandığında satırlar arasına 16 bayt dolgu eklenir ve sanal ekranın solunda ve sağında 16’şar piksel boşluk oluşur
    • CRTC_START 1 artırıldığında düzlem yapısı nedeniyle ekran 8 piksellik adımlarla hareket eder; bu fazla kabadır
    • Horizontal Pel Panning, yani PEL yazmacı, CRTC_START sonrasında en fazla 7 biti atlatıp piksel düzeyinde yatay kaydırmayı mümkün kılar
  • Gerçek sağ-sol hareket, koordinatın 8’e bölünmüş değeriyle CRTC_START ayarlanıp koordinatın kalanıyla (% 8) PEL ayarlanarak yapılır

jolt ve karo düzeyinde kısmi yenileme

  • Sanal ekranın kenarına ulaşıldığında ATR, sanal ekranı tekrar merkeze hizalamak için jolt uygular
  • Tüm ekranı yeniden çizmek yaklaşık 200ms sürüp 5fps’ye düşürdüğü için jolt, tam yeniden çizim yerine yalnızca değişen karoların üzerine yazacak şekilde çalışır
  • Commander Keen seviyeleri 16x16 karolardan oluşur
    • Sanatçı karoları çizdiğinde derleme sistemi her karoya benzersiz bir ID verir
    • Seviye tasarımcısı, 2D editörde karo ID’lerini yerleştirerek haritayı oluşturur
    • Motor, sanal ekranda hangi karo ID’lerinin bulunduğunu izler
  • jolt anında mevcut sanal ekran durumu ile tekrar merkeze hizalanmış hedef durumun karo ID’leri karşılaştırılır
    • Aynı karo atlanır
    • Yalnızca farklı karolar VRAM üzerine yazılır
  • jolt verimliliği yeniden çizilecek karo sayısıyla ters orantılı olduğundan, oyun tasarımcısının tilemap’i çok sayıda tekrar eden karo içerecek şekilde kurması gerekiyordu
  • Commander Keen 1 örneğinde, sağa doğru akıcı hareket sırasında sanal ekran sona erip 16 piksel sola jolt oluştuğunda 250 karodan yalnızca 40 karo değişir
    • Yeniden çizilen oran tüm ekranın %16’sıdır
  • Arka planın üzerine sprite katmanı çizilir
    • Motor, sprite’ların üzerine yazdığı dirty karo koordinatlarının listesini tutar
    • Her yeni karede dirty listeyi dolaşarak arka plan karolarını geri yükler, ardından sprite’ları yeniden çizer

Çift arabellek ve ikinci üçlemenin drifting tekniği

  • Görsel artefaktlardan kaçınmak için tüm sistem iki framebuffer ile çoğaltılır
    • CRTC biri okurken diğerine VRAM’in başka bir konumunda yazılabilir
    • Her arabellek (320 + 32) * (200 + 32) * 4 / 8 = 40,832 bayt kullanır
    • Çift arabelleğin tamamı 40,832 * 2 = 81,664 bayttır ve IBM’in özgün EGA kartındaki 64KiB’yi aşar
  • VileR’e göre 64KiB ile donatılan tek kart özgün IBM EGA kartıydı; 1986~1987 civarında çıkan EGA klonlarının çoğunda 256K vardı ve Commander Keen’in çıkış zamanında 256K’dan düşük EGA kartı neredeyse yoktu
  • Commander Keen 1~3’te ATR’nin gerektirdiği tekrar desenleri ekranda belirgindir, ancak Commander Keen 4~6’da aynı özellik göze çarpmaz
  • İkinci Keen üçlemesi, CRTC_START 64KiB bloğunun sonuna ulaştığında tekrar bloğun başına dönen wraparound davranışından yararlanır
    • Ekranı sürekli panning yapar ve yalnızca yeni görünen kenar karo satırlarını çizer
    • jolt ortadan kalktıkça benzer renkte tekrar alanları oluşturma ihtiyacı azalır
  • Bu yöntem yeni bir özellik eklemekten çok jolt’u ortadan kaldıran bir iyileştirmeye yakındır
    • İki çift arabellek öğesi VRAM alanında aynı hızla drift ettiği için birbirleriyle çakışmaz
    • Çoğu durumda iyi çalışır
  • Bazı Super VGA kartlarında sorun çıkar
    • Standarttan farklı uygulamalara ve daha büyük belleğe sahip kartlarda, sondan başa wraparound yapmak yerine gerçekten var olan ama başlatılmamış belleğe girilebiliyordu
    • Carmack, standart dışı birçok karta ayrı ayrı uyum sağlamak yerine, ekranın sonuna ulaşıldığında hitch’i göze alıp tüm ekranı yukarı kopyalayan kolay çözümü seçti
  • Bu drifting tekniği, karoları ve sprite’ları VRAM’de tutup hızlı VRAM-to-VRAM kopyalama kullanma yöntemini engellemiş olabilir; ancak her karede çizilecek miktar çok az olduğundan büyük bir sorun olmamış olabilir

1 yorum

 
GN⁺ 2023-07-29
Hacker News yorumları
  • Commander Keen 4~6’daki kaydırmanın akıcılığına PC’de yıllarca hiçbir oyun yaklaşamadı; oyunlar 256 renkli grafiklere geçtikten sonra bile durum böyleydi.
    John Carmack’ın olağanüstü teknik çalışması ve Adrian Carmack’ın 16 renk paletli sanatı sayesinde id, 1990’larda bir süre PC’de en iyi görünen platform oyunlarını yapmış sayılır.
    Adrian Carmack, daha ünlü Carmack’ın akrabası değil ama bana göre 16 renk paletinin gizli ustası.

    • Klasik Commander Keen oyunlarının tamamının Aralık 1990 ile Aralık 1991 arasında geliştirilip yayımlanmış olması epey tuhaf geliyor.
      Grafik ve oynanıştaki ilerleme hızı gerçekten inanılmazdı.
      İlk oyundaki değişim: https://en.wikipedia.org/wiki/Commander_Keen_in_Invasion_of_...
      Son oyuna kadarki değişim: https://en.wikipedia.org/wiki/Commander_Keen_in_Goodbye,_Gal...
      O zamanlar çocukken bizzat oynamıştım; işlerin bu kadar hızlı gerçekleştiğini unutmuşum.
    • 1990’larda bir süre en iyi görünen PC platform oyunu denince ben Prince Of Persia’yı seçerdim.
      Commander Keen’i küçümsemek istemem ama PoP’un görselleri ve oyun mekaniği, dönemin standartlarına göre benzersizdi diye düşünüyorum.
      Yaklaşık 7 yaşındayken ilk oynadığımda büyülü bir izlenim bırakmıştı; bugün de en sevdiğim platform oyunu olduğu için biraz önyargılıyım tabii.
      Elbette PoP’ta hiç kaydırma yok; orası Commander Keen’in kara büyüsü.
    • Belki bugünden geriye bakmanın etkisidir ama bu tür yenilikçi geliştirmenin önemli bir kısmı, günümüz geliştirme pratikleriyle karşılaştırınca oldukça basit görünüyor.
      “Bellek yavaş, o yüzden sadece değişenleri yeniden çizelim” fikri bugün neredeyse bariz sayılır.
      Yine de 4~6. bölümlerdeki optimizasyonlar ilginç. 1~3. bölümlerde tamponun wrap etmeyeceği varsayımı yüzünden tüm işi yapmışlar; gerçekte wrap edince o işin boşa çıkması da ilginç.
    • Jazz Jackrabbit nasıl peki? O oyunda da VGA kaydırma gerçekten akıcıydı.
  • Windows 98’de DirectX 5 ile tile tabanlı bir oyun yapmıştım; başta bu yazıda anlatılana benzer bir yöntem uygulamıştım.
    Ekran kaymıyordu ama çok sayıda tile’ı yeniden çizmek gerekebildiği için durum biraz daha basitti.
    Sonunda o kodun tamamını söküp attım; çünkü RIVA TnT kartta tam ekranı çizmenin maliyetini profillediğimde geçen süre o kadar küçüktü ki ölçülemiyordu bile.
    PC geliştirmede EGA dönemini kaçırdığıma seviniyorum. O dönemde olsaydım muhtemelen hiçbir şeyi tamamlayamazdım.

    • Ben tam tersine böyle düşük seviyeli programlamayı severdim.
      Çarpma yerine bit kaydırmayla optimizasyon yapmak, kritik kodu assembly ile yazmak, işlemciler geliştikçe tek seferde 16 bit ya da 32 bit yazmak gibi şeylerdi.
      Elimde az kaynak olduğundan yerel kütüphanedeki kitaplardan ve txt dosyalarıyla dolu disketlerden sürekli öğrenirdim.
      Çok genç ve deneyimsiz olduğum için tamamladığım bir şey olmadı ama akıcı dikey kaydırma yapmıştım, yatay kaydırmayı da neredeyse çalıştırmıştım; ayrıca dönen bir 3D küp için çift tamponlama da uygulamıştım. Derinlik tamponlama, matematik ve satır bazlı poligon çizimi de buna dahildi.
      Sonra DirectX çıkınca makineyle temas noktası kayboldu; dönen 3D küp de fazla kolaylaştığı için eğlencesi kalmadı.
    • O zaman bile en yavaş grafik kartıyla en hızlı grafik kartı arasındaki fark ciddi biçimde açılmıştı.
      Veri yolu 8 bitten 16/32 bite genişliyor, grafik kartları posted writes destekleyerek CPU’nun daha az beklemesini sağlıyor, CPU da hızlandıkça hızlı sistemler 640x480x256 ekranı saniyede 300 kareden fazla yazabiliyordu.
      Bu durumda muhtemelen önbelleğe alınmış sistem belleği tamponu ve DMA kopyası vardı ya da çizimi blitter üstlenmiş olabilir. Ama Windows 98 döneminde bile düşük maliyetli 3D kartların bazıları CPU erişiminde çok yavaştı; eski ISA veri yolu kartlarından ancak biraz daha iyi düzeydeydiler.
      Ekran çözünürlüğü çok yükseldiği için bugün bazı açılardan yeniden biraz tersine dönmüş durumda. 4K tam ekranı saniyede 60 kare yeniden çizebilseniz bile buna verimli demek zor.
      Oyunlar genelde hâlâ her şeyi yeniden çiziyor ama masaüstü bileştiriciler, yeniden çizilen alanı azaltmak için katmanları donanım düzlemlerine dinamik olarak atamak gibi epey optimizasyon yapıyor.
  • Aynı dönemde başka bir oyun şirketinde çalışıyordum; ikinci yaklaşımla aynı kaydırma tekniğini kendim bulmuştum.
    Bunun o kadar şaşırtıcı bir şey olduğunu düşünmüyorum. O sırada aynı problemi çözmeye çalışıyor olsaydınız muhtemelen benzer bir sonuca varırdınız.
    PC speaker üzerinden örneklenmiş ses çalmak için kendi PWM ses sürücümü de yapmıştım; sanırım başkaları da hep bunu yapıyordu.
    Hepimiz konsola geçmeden önce PC yeterince sevilmedi. Hornet’in 8088 MPH gibi demolarını görünce hâlâ heyecanlanıyorum.

    • Yayımlanmış bir oyunsa karşılaştırabilmek için adını söyleyebilir misin? Benzer çözümlerin çoğu kişinin aklına gelmiş olacağına katılıyorum ama oynayınca aynı hissi verip vermediğini merak ediyorum.
    • O kadar büyük bir mesele değilse, o dönemin üst seviye kaydırmalı platform oyunları arasında bile neden bu kadar çok takılan oyun vardı?
      Eğlenceli bir oyunun olmazsa olmazı değil ama Keen’in özellikle 10MHz altı gibi düşük donanımda gösterdiği akıcılık o dönem göz açıcıydı.
    • Ün çoğu zaman icadın kendisinden değil, ticarileştirme ve pazarlama becerisinden gelir.
      Binlerce yıl boyunca bilinmeden kalmış sayısız harika icat olmuş olmalı.
      Ben de LinkedIn’den 10 yıl önce benzer bir şeyi “icat” etmiştim ama başarılı biçimde ticarileştiremedim. Çoğu icadın geniş kitlelerce bilinmediğini düşünüyorum.
      Bu yüzden birçok startup iki kişiyle başlar: bir uzman ve bir iş insanı.
      Dolayısıyla yanlış değil. Bu icat kendi başına özel olmayan bir şey olabilir; ama yenilik, fayda ve başarılı ticarileştirmenin birleşmesiyle özel hâle geldi.
  • Mükemmel kitap Masters of Doom, Keen’in Mario tarzı, yani yatay kaydırmalı bir oyun olduğunu anlatır
    id, Mario’yu PC’ye portlama seçeneği olarak bu teknolojiyi Nintendo’ya önermişti; ancak Nintendo reddetti ve böylece Keen doğdu
    PC oyunları için dev bir sıçramaydı ve yeni bir PC oyunları çağını başlattı
    Yine de hâlâ tam anlayamadığım şey şu: NES ile PC teknolojisi arasında ne bu kadar farklıydı da Nintendo yatay kaydırmayı PC’den birkaç yıl önce gerçekleştirebildi?

    • EGA özünde büyük bir framebuffer sunar
      EGA grafik modunda çizgi, daire, tek tek pikseller gibi istediğiniz herhangi bir şeyi çizebilirsiniz; zaten bu şekilde kullanılmak üzere tasarlanmıştı
      Ama kaydırma bedava değildir. Belleği doğrudan kopyalamanız gerekir ve bağlantı verilen yazının gösterdiği gibi kaba kuvvetle yaparsanız ISA veri yolu bant genişliği sınırı yüzünden saniyede ancak yaklaşık 5 kare alırsınız
      NES ve diğer 8/16 bit oyun konsolları keyfî şeyler çizmek için tasarlanmamıştı. Tile render etmek için tasarlanmıştı
      Arka plan tile ızgarasını tanımlayıp kaydırma ofseti vermeniz yeterlidir. Sprite’lar da benzer çalışır ama bağımsız hareket edebilir. Bunların hepsi saniyede 60 kare olarak bedavaya gelir
      Dezavantajı, keyfî şeyleri kolayca render edememenizdir. Örneğin bir yere tek bir piksel boyamak isterseniz epey ağır bir dolambaçlı yol gerekir
      Bu, Nintendo’nun IBM’den önce “çözdüğü” bir sorun olmaktan çok; IBM’in genel amaçlı bilgisayarlar ve statik grafikler için genel amaçlı bir grafik sistemi yapıp her piksel üzerinde ince ayarlı kontrol sunmasıydı. Bir EGA karta bakarsanız içinde bolca silikon bulunan epey büyük bir cihazdır
      Nintendo ise tile’ları itip kaydırmaya yönelik çok daha basit bir özel amaçlı grafik sistemi yapmıştı
    • Aslında SMB3 portunu yapıp Nintendo’ya göstermişlerdi
      Nintendo kabul etmeyince yeni asset’ler yaptılar ve bu daha sonra Keen’e dönüştü
      Portun videosu burada: https://youtu.be/1YWD6Y9FUuw
    • Emin değilim ama bildiğim kadarıyla NES’te sprite manipülasyonu için özel bir grafik çipi vardı; PC’de ise bunların hepsini yazılımla yapmak gerekiyordu
    • Yazıdaki yöntem, bağımsız piksel framebuffer’ı kullanarak donanımın yönettiği tile’ları yazılımla taklit etme biçimi
      NES tarafı için https://www.nesdev.org/wiki/PPU iyi bir başlangıç noktası gibi görünüyor
      Asıl zorluk “yatay kaydırmanın nasıl yapılacağını bulmak” değil; yatay kaydırmalı bir oyun motorunu tamamen farklı bir sistemin bellek alanı ve bant genişliği kısıtları içinde iyi görünecek şekilde uyarlamak
    • NES ve GB sanırım tile tabanlıydı
      Katmanları olan sprite tabanlı oyunlar yapıldığı için 2D’yi “hızlandırma” biçimi oldukça mantıklıydı
  • Lex Fridman’ın John Carmack röportajında her oyunun başlıca yeniliklerinin hepsi üzerinden geçiliyor
    Gerçekten ilginç bir bölüm; vaktiniz varsa şiddetle tavsiye ederim. Yaklaşık 5 saat sürüyor

  • Commander Keen Goodbye Galaxy’deki neredeyse tüm gizli unsurları bildiğime inandığım günleri hâlâ hatırlıyorum
    Okul arkadaşlarım, okuldan sonra okul bilgisayarlarında oynadıkları bölümlerdeki sırları bana sorarlardı

    • Kıskandım. Benim okuduğum okulda, konuştuğum insanlar arasında Commander Keen’i duymuş olan tek inek bendim
  • fabiensanglard.net’i görünce hemen tavsiye ediyorum

  • Framebuffer başlangıcını scanline bazında ayarlayınca dikey kaydırmanın nasıl çalıştığını anladım, ama yatay kaydırmanın framebuffer’ı ciddi biçimde bükmeden nasıl mümkün olduğu başta net değildi
    Biraz daha düşününce bunun silindirin yan yüzeyine resim çizmeye benzediğini fark ettim. Görüntünün sol kenarını nereye çizerseniz çizin, silindiri döndürüp CRTC_START ve PEL yazmaçlarını ayarlayarak görüntünün tamamını net biçimde görmenin her zaman bir yolu var
    “Ekranın kenarına ulaşıldığında, basit bir çözüm olarak takılmayı göze alıp tüm ekranı yukarı kopyalıyorlardı” kısmı da ilginç
    Keen’i başlatırken genelde “VGA compatibility mode enabled” gibi bir mesaj çıktığını hatırlıyorum; bunun ne anlama geldiğini hep merak etmiştim

  • Commander Keen gerçekten sevimli küçük bir oyundu
    Yeniden çalıştırmanın bir yolunu bulmam gerek
    Ama bunu nasıl çalıştırmak en iyisi olur? “Yetişkin” olduktan sonra yaklaşık 20 yıldır Windows kullanmıyorum; Debian’da nasıl oynayabilirim?

    • Hemen oynanabiliyor: https://archive.org/details/msdos_Commander_Keen_1_-_Maroone...
    • Katılmıyorum. Bu, herhangi bir nedenle bilgisayara erişimi olan ama Nintendo’su olmayan çocuklar için bir oyundu
      O dönemde bilgisayarlar konsollardan yaklaşık 10 kat pahalıydı; genelde bunun nedeni de yetişkinlerin, çocuğun ne yapması gerektiği konusunda güçlü fikirleri olmasıydı
      NES ve Genesis oyunlarıyla karşılaştırınca ruhu eksik. O zamanlar sevmiştim ama yakın zamanda DosBox’ta tekrar oynayınca kesinlikle aynı seviyede olmadığını hissettim
    • DosBox eski VGA oyunlarını çok iyi çalıştırıyor ve tarayıcı içinde olmak üzere neredeyse her platformda çalışıyor: https://archive.org/details/msdos_Commander_Keen_1_-_Maroone...
    • Muhtemelen DosBox’tır
    • Commander Keen ve Jill of the Jungle, eskiden PC ile ilk tanışmamı sağlayan oyunlardı. Gerçekten güzel anılar
  • Birkaç yıl önce ikinci yöntemi uygulamıştım; sadece ön kenarı çizmek bile çok yavaştı
    Ancak C ile yazmıştım ve assembly programlamayı doğru dürüst öğrenmiş değilim
    https://github.com/geon/kate/blob/master/src/platform/dos/eg...