Gönderen Konu: Sid Meier Pirates'i nasıl yazmış bakalım  (Okunma sayısı 143 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 3042
  • Advanced User Simulator
    • ae unutmadan
Sid Meier Pirates'i nasıl yazmış bakalım
« : 11 Nisan 2025, 16:28:10 »
baktım dashersw Lale işini götürüyor, orayı ona bıraktım, ben pirates! a geçtim. ZX Spectrumda pirates! olmaması büyük sıkıntı benim için. Olacak iş değil?!!?!!111 Yani şu release listesine bakın:

1987 (PC Booter)
1987 (Commodore 64)
1987 (Amstrad CPC)
1988 (Apple II)
1988 (Apple IIgs)
1988 (Macintosh)
1989 (Atari ST)
1989 (PC-98)
1989 (PC-88)
1990 (Amiga)
1991 (NES)
1994 (DOS)

Tamam hepsinin ortak yanı bir disk sürücüsünün olması, ama bidakka 1987 sonlarında spectrum +3 çıkmıştı aslında, yani isteseler 88,89 ya da 90 yılında spectruma çıkarabilirlermiş.

Başka olmayanlar, AtariXL, MSX, Acorn, BBC micro, Oric, Sam Coupe vs.

Şimdi işin ilginci Sid Meier aslında Atari XL coderi, Microprose Atari XL ile başlıyor. Ama bu oyun orjinal olarak commodore 64'de yazılmış. Koda ilk bakışta görünen şey şu: 60 kb'lık bir cbm basic listesi var, oyundaki birçok şey burada görülebiliyor.

Bu bağlamda eh ben de retro ekmeğimi basic'den çıkardığım için dedim "ne kadar zor olabilir yaaani?" Bakalım şu basic koduna, yapalım bir düzgün port bre!
...a few moments lateğğ...
Pişmanım. Beklediğimden çok daha fazla makine kodu içeriyor.

Ama yine de bazılarına ilginç gelebilecek bilgiler olabilir, burada paylaşacağım.     Bu arada göz atmak isteyenlere proje sayfası burada: https://github.com/ref-xx/PiratesZX

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 3042
  • Advanced User Simulator
    • ae unutmadan
Ynt: Sid Meier Pirates'i nasıl yazmış bakalım
« Yanıtla #1 : 11 Nisan 2025, 16:57:46 »
Şimdi hemen başlayalım, şimdiye kadar neler yaptım?

1. C64 disk imajlarından dosyaları extract ettim. 127 dosya var. Buradaki sorun şu, hiçbir arşivde c64 pirates disklerinin orjinal haline rastlamadım. Tosec dahil tüm oyun arşivlerinde aynı ESI (başta kartal imajı ile başlayan) paketleri mevcut. Ben de bunu kullandım. Crack meselesi çok şaşırtıcı çünkü amiga/spectrum komünitesi bu konuda çok titizdir, c64 komünitesi sınıfta kaldı. Demoscene'i altından çeksek c64 diye birşey kalmayacak sanki. Ayrıca ileride bahsedeceğim Nostalgia release'i var, bu çok iyi bir paket, orjinal makinede oynamak isteyenler bunu kullanmalılar. Bu release 2013 yılında çıkmış ve orjinalinde 2 disket olan oyunu tek yüzlü tek disket haline getiriyor. Emülatörde çalışıyor, daha hızlı yükleniyor, düzgün cracklenmiş ve trainer ile şenlendirilmiş. Süper paketlendiği için bu sürümle ilgilenmedim.

2. İlk olarak disketlerde üç adet BASIC dosyasını çıktı aldım. Fakat cbm basic her kelimenin ilk iki harfini kullanıyor. Yani var=5 demek va=5 demek aslında. Ayrıca ifadeler arasında boşluk olmasına gerek yok. Eh ram da az olduğundan Sid kardeşimiz bunları belleğe zumuşturmuş adeta. Örnek:

 
Kod: [Seç]
1010 f=192:t=228:l=8:gosub10:bf=192*kp:f$="chars.dta":gosub17790
1012 ifsn<0thenc=0:t(c)=peek(prs):goto1040
1015 z=0:gosub8700:ifsn>1thenfori=5tosn*4:readx:nexti
1020 fori=1to4:readx:t(i)=x:nexti
1021 ifsn<6thenfori=sn*4to23:readx:nexti
1025 t$="are you an¿":fori=1to4:a=bf+t(i)*80-80:ift(i)=0then1035
1030 t$=t$+" ":forj=0to19:t$=t$+chr$(peek(a+j)):nextj:t$=t$+"£"
1035 nexti:x=10:y=5:gosub8000:pokeprs,t(c)

pek okunaklı değil... toplamda 2000 satır kod  ve  5-6bin kadar ifade olduğundan elle düzeltmek de çok iş. Bu durumda yardımımıza 10 sene önce yazılmış bir programcık geliyor ama tabiiki çalıştıramadım ben onu, sonra kodunu paylaşmışlar neyse ki, fork ettim, güncelledim ve çalıştırdım:
https://github.com/ref-xx/CommodoreBasicReformatter
Kod: [Seç]
1012 if sn<0 then c = 0 : t(c)= peek(prs) : goto 1040
1015 z = 0 : gosub 8700 : if sn>1 then for i = 5 to sn*4 : read x : next i
1020 for i = 1 to 4 : read x : t(i)= x : next i
1021 if sn<6 then for i = sn*4 to 23 : read x : next i
1025 t$ = "are you an?" : for i = 1 to 4 : a = bf+t(i)*80-80 : if t(i)= 0 then 1035
1030 t$ = t$+" " : for j = 0 to 19 : t$ = t$+chr$(peek(a+j)) : next j : t$ = t$+"?"
1035 next i : x = 10 : y = 5 : gosub 8000 : poke prs,t(c)
Tamam şimdi biraz daha okunur oldu. Yetmez ama evet. Başta bunları bir text editörde comment etmeye başlamıştım ama heryer pokeler, fonksiyonlar, sublar karmakarışık oldu. Dedim bu kod içinde kolayca gezebilmeliyim, Önce akıllı bir textbox iken bir anda kontrolü kaybedip başka birşey yazıverdim.
https://github.com/ref-xx/BasicFlowgen
Bu goto/gosub/return gibi zıplamalarla gidip gelmeleri kendisi işaretliyor. üstelik tek tıkla o satıra zıplayabiliyorsunuz. Takibi kolay oluyor.

Kod: [Seç]
1025  t$ = "are you an?"                                                                                                                     
  :     for i = 1 to 4                                                                                                                         
  :     a = bf+t(i)*80-80                                                                                                                       
  :     if t(i)= 0 then 1035     
1030  t$ = t$+" "                                                                                                                             
  :     for j = 0 to 19                                                                                                                         
  :     t$ = t$+chr$(peek(a+j))                                                                                                                 
  :     next j                                                                                                                                 
  :     t$ = t$+"?"                                                                                                                             
                                                                                                                                               
  1035  next i                                  1025:3                                                                                         
  :     x = 10                                                                                                                                 
  :     y = 5                                                                                                                                   
  :     gosub 8000                                                                                                                             
  :     poke prs,t(c)                                                                                                                           
                                                                                                                                               
  1040  poke 53269,0                            1012:2                                                                                         
  :     a = bf+t(c)*80-80                                                                                                                       
  :     for j = 0 to 12                                                                                                                         
  :     poke pty+3+j,peek(a+20+j)                                                                                                               
  :     next j                                                   

Sonuçta basic kodunu incelemeye başladım, rutinlerin ne yaptığını öğrendikçe işaretleyip tanımını yazıyorum.

Basic bulguları:
# RND
Pirates rastgele sayı oluşturmak için sid çipinin gürültü üretecini kullanıyor. Bu sebeple oyunun başında sid çipinden bir noise ürettirip test yapıyor, eğer değer değişmezse çipin arızalı olduğunu bildiriyor. Bu bana epey enteresan geldi. Ve noise hattı arızalı bir sürü Sid varmış, hatta bir yayıncı pirates oyununu incelerken kendi c64'ünün arızalı olduğunu bu sayede farketmiş.

Kod: [Seç]
6000  t$ = "the random number generatoRin this
       computer (sid chip -?"                 
6010  t$ = t$+"osc. 3) is not functioninGcorre
      ctly.  program will noT"               
6020  t$ = t$+"work unless this is repaired?"
6030  gosub 12500                             
:     poke 53280,10                           
:     x = 3                                   
:     y = 6                                   
:     gosub 8000                             
:     return                                 

# SidTran
Anladığım kadarıyla oyun aslında Basic ile yazılmamış. Sid Meier'in kendi kullandığı bir programlama dili olan SIDTRAN ile yazılmış. Bu dil daha sonra gerekli basic kodunu üretebiliyor. Bu basic kodunun karmaşa sebebini açıkıyor gibi, insan okusun diye üretilmemiş.  Bu işi detaylı öğrenmek için sid meier'in kitabını sipariş ettim, halen okuyorum.

Oyunun kendine ait değişkenleri (altın, karakter detayları vb) bir basic değişkeninde değil bellekteki adreslerde tutuluyor. Yani para kazandığınızda:
para=para+100
demiyor, onun yerine index=3, value=100 diyip bir subrutin çağırıyor, bu rutin de bellekteki uygun pozisyonu güncelliyor.
Aslında son derece basit ve etkili ama korkunç bir karmaşa bu. Sonuç olarak bunun sebebi makine kodu rutinlerinin de değişkenlere kolayca erişmesi aslında.
devam edecek...


Çevrimdışı Hifly

  • Retro Meraklısı
  • ***
  • İleti: 214
Ynt: Sid Meier Pirates'i nasıl yazmış bakalım
« Yanıtla #2 : 12 Nisan 2025, 09:20:22 »
Harika bir çalışma olmuş. Gri hücrelerine sağlık. Programlama konusunda çok bilgili değilim ama anlayabildiklerim bile bana vay be dedirtti. Reverse engineering zor ama oldukça keyifliye benziyor.