tr-demoscene

the scene => coding => c64 => Konuyu başlatan: atiflz - 22.05.2008 01:38:58

Başlık: Sprite cogullama
Gönderen: atiflz - 22.05.2008 01:38:58
Sprite'lari alt alta koyunca, ayni stairda 8'den fazla olmamak sartiyla bir suru sprite cizebiliyoruz. Peki Ornegin Space Invaders'da ayni satirda 11 tani dusman oluot, onu nasil hallediyorlar? Iki uzayliyi tek sprite mi yapiyorlar?
Başlık: Sprite cogullama
Gönderen: skate - 22.05.2008 16:36:22
Sprite kullanmıyorlar, karakter seti ya da bitmap ekran kullanıyorlar. Bir çeşit BOB da diyebiliriz ama Amigacılar bu terime itiraz ettiği için kullanmak istemiyorum :)
Başlık: Sprite cogullama
Gönderen: skate - 22.05.2008 16:44:28
ıhtiyacı olan olursa geçen senenin ocak ayında kimin için hazırladığımı hatırlamadığım Türkçe açıklamalar içeren bir multiplexer kaynak kodu buldum. Aşağıdaki linkten kaynak kod ve prg dosyası bulunan zipi indirebilirsiniz.
 
http://www.akaydin.com/c64/codes/skate/multiplexer.zip
Başlık: Sprite cogullama
Gönderen: ssg - 22.05.2008 21:12:03
60hz tariyorsa ve 200 tarama satiri varsa bir tarama satiri 1/12000 saniye aliyor. 0.9khz bi makinada bir cycle 1/900000 saniye tutuyor. bir satir kabaca 75 cycle'da taraniyor. (gerci komodorcular bunu coktan denemistir herhalde, tam sayiyi biliyordur).
 
vic chip'i ve hafiza erisimi yeterince hizli olsa 75 cycle'da yeniden sprite tanimlamak mumkun olabilirmis. anladigim kadariyla degil :)
Başlık: Sprite cogullama
Gönderen: atiflz - 22.05.2008 22:26:34
Yanlis hatirlamiyorsam bir satir taramasi tam 63 dongu suruyor. Bir bellek erisimi ise 3 dongu. Yalniz ayni satira yanyana 8'den fazla hic bir zaman yapilamiyor. Anladigim kadariyla "multiplexing" dene sey sadece ayni sprite'i daha alt satirlarda bir daha kullanarak yapiyorlar sadece.
Başlık: Sprite cogullama
Gönderen: skate - 23.05.2008 14:44:32
vic oldukça karışık bir işleyiş yapısına sahip. tek satırda PAL mode 63, NTSC 65 (eski modeller 64) cycle'a sahip. her ikisinde de aynı satırda 9. sprite'ı göstermek mümkün değil... idi... taa ki crossbow şu demoyu yayınlayana kadar:
 
http://noname.c64.org/csdb/release/?id=48577
 
Bu demoda alt borderda sağ tarafta görüntülenen 9. sprite aslında bir alt satırda yer alıyor ancak bir şekilde üst satırda gösterilebiliyor. bu demodan sonra birçok emulator update yayınlamak zorunda kaldı. ancak bu tekniğin problemi bir alt satırdaki sprite'dan faydalandığı için her iki satırda bir çalışabilmesi. Spriteların birer satır atlayan çizgilerden oluşmasının nedeni de bu.
 
Ama bu trick tam legal sayılmaz açıkçası. Evet yan yana 9. sprite'ı gösterebiliyoruz ancak hala buna cycle yetmiyor. Garip bir durum :)
Başlık: Sprite cogullama
Gönderen: ssg - 23.05.2008 21:55:56
bu demonun bahsi daha once forumda gecmisti ama calistiran bir emulator bulamamistim o zaman. evde de nightlord'un nasa uzay ussu gibi komodor gelsitirme calistirma merkezim olmadigi icin gercek makinada bakamadiydim.
 
simdi youtube'e baktim buldum izledim. eger emulator hatasi degilse sprite'in sadece 24 pixel'i ayni satirda geri kalani alt satira wrap ediyor galiba (gri cizgiler de sprite'in parcasi saniyorum).
 
yine de 30 yildir kimsenin bulamadigini bulmus olmak super tabi.
Başlık: Sprite cogullama
Gönderen: stranger - 30.10.2009 22:19:48
Kendi multiplexer rutinimi yazarken jsr$e544 ile ekranı temizledikten sonra
x koordinatında yer alan Sprite0 ile Sprite1 arasında 1 pixellik boşluk kalıyor
jsr$e544'ün x registerine 1 yüklediğini tahmin ettiğim için(bir alaka yok ama yinede) akümülatörü + x ve y registerlerinin değerini sıfırlamama rağmen sonuç değişmiyor
örn:
jsr$e544
ldx#$00
ldy#$00
lda#$00
.... gibi
 
Tabii ekranı aşağıdaki şekilde temizleyip sorunu çözdüm fakat yinede aklıma takıldı. Nedir bu yahu? VIC 'in bilinmeyen bir yüzüyle mi karşılaştık yine :)
 
ldx#$ff
lda#$20
sta$0400,x
sta$04ff,x
dex
bne *-7
Başlık: Sprite cogullama
Gönderen: skate - 31.10.2009 00:24:02
emin değilim ancak sorunun carry flag ile ilgili olabilir. belki jsr $e544 carry flag'i set ediyordur, sen de aşağıda bir toplama işlemi yaptığında değere 1 ekleniyordur. jsr $e544 sonrasına bir "clc" koymayı dene.
 
tahminim şöyle;
 
jsr $e544
clc
lda #$50 ;herhangi bir değer
sta $d000
adc #$18
sta $d002
 
belki sen clc'yi unutmadıysan bile jsr $e544 öncesine koymuşsundur. böyle birşey olabilir.
Başlık: Sprite cogullama
Gönderen: stranger - 31.10.2009 01:08:26
Haklısın ve teşekkürler Skate clc ile sorun çözüldü.
(Bende Omomatik reklamı hissi yarattı bu cümlem nedense... birde üstüne üstlük sizde kullanın ben memnun kaldım diyesim geldi ,)
Carry bir şekilde set olduğu için ilk toplama işlemimde adc#24 +carry= 25 oluyormuş.
Başlık: Sprite cogullama
Gönderen: stranger - 02.11.2009 14:39:46
Peki alt alta 2 sıra 8'er sprite dizsek. Bunların datalarını sağlıklı bir şekilde ayrı memory bloklarından okutmak mümkün olabilir mi? Biraz bokunu çıkarmak gibi gözükebilir fakat bence bu şekilde kullanılacak 16 renkli bir logo, 3 renkli karakter setinden oluşan bir logodan daha hoş duracaktır. Hemde tahminen hareket ettirmesi renk kodları vb. şeylerle uğraşılmayacağı için daha zahmetsiz olacaktır.
Örneğin üst sırayı $2000 den başlayıp, alt sırayıda mesela $3000 'den başlatıp okutsak...
Başlık: Sprite cogullama
Gönderen: skate - 02.11.2009 15:57:46
tam olarak demek istediğini anlayamadım kardeşim. eğer kastettiğin şey spriteları tekrar ettirirken data maplerini de değiştirmekse zaten multiplexerlar hep böyle kullanılır. ancak 8 sprite'ı birden kullanacaksan ve iki sprite satırı arasında tek bir raster satırı bile ara vermek istemiyorsan bu durumda ufak bir trick kullanmak gerekiyor. Çünkü 8 sprite'ın Y'de yeniden pozisyonlandırılması 1 LDA + 8 STA = 34 cycle tutuyor. Bir de 8 sprite'ın memory maplerini vermek istersek 8 LDA + 8 STA ya da alternatif olarak sıralı spritelar için 1 LDX + 7 INX + 8 STX her iki durumda da 48 cycle tutuyor. 34+48 = 82 cycle 63 cycle'ı geçtiği için üst sıradaki spriteların sonuncusu gösterildikten sonra bir sonraki satıra kadar tüm spriteları değiştirmeye yetmiyor zamanlama.
 
Çözüm: Spriteların adresleri her zaman ekran adresinin $3f8 ilersinde yer alır. Commodore 64 ilk açıldığında ekran adresi $0400'e ayarlanmıştır ($d018'in 4,5,6 ve 7 numaralı bitleri ekran adresinin pozisyonunu belirler). Eğer biz varsayılan ekran adresinin dışında ekran adresleri de kullanacak olursak ekran adresinin pozisyonunu değiştirdiğimizde 8 sprite address pointer'ı aynı anda değişmiş olur. Yani;
 
$07f8 - $07ff : Birinci sprite satırı adresleri
$0bf8 - $0bff : ıkinci sprite satırı adresleri
 
şeklinde önceden ayarlanırsa spriteların Y pozisyonları değiştirildikten sonra sadace $d018'in değeri değiştirilerek 6 cycle'da geçiş yapabilirsiniz. Örnek:
 
lda #$80 ; yeni Y pozisyonu
sta $d001
sta $d003
sta $d005
sta $d007
sta $d009
sta $d00b
sta $d00d
sta $d00f
lda #$24 ; ekran $0800-$0bff arasında
sta $d018
 
bu şekilde 2. satıra geçiş yapılabilir.
 
Ekran adreslerinin $d018 ile nasıl değiştirileceğinin tablosu aşağıdadır.
 
 0 -> %0000 ->  0*$0400 = $0000
 1 -> %0001 ->  1*$0400 = $0400 (Commodore'un varsayılan ekran adresi)
 2 -> %0010 ->  2*$0400 = $0800
 3 -> %0011 ->  3*$0400 = $0c00
 4 -> %0100 ->  4*$0400 = $1000
 5 -> %0101 ->  5*$0400 = $1400
 6 -> %0110 ->  6*$0400 = $1800
 7 -> %0111 ->  7*$0400 = $1c00
 8 -> %1000 ->  8*$0400 = $2000
 9 -> %1001 ->  9*$0400 = $2400
10 -> %1010 -> 10*$0400 = $2800
11 -> %1011 -> 11*$0400 = $2c00
12 -> %1100 -> 12*$0400 = $3000
13 -> %1101 -> 13*$0400 = $3400
14 -> %1110 -> 14*$0400 = $3800
15 -> %1111 -> 15*$0400 = $3c00

Bu değerler byte'ın üst nibble'ına tekabül eder. Yani Hexadecimal olarak $0-$F arası düşünecek olursak bu değerleri;
 
lda $#XY
sta $d018
 
şeklindeki yazılımda X'in yerine koymamız gerekir. Y ise karakter seti ya da bitmap grafik pozisyonunu belirtir. Karakter setini varsayılan pozisyonda kullanacak olursak;
 
ekranı $0400'e almak için;
 
lda #$14
sta $d018
 
ekranı $0800'e almak için;
 
lda #$24
sta $d018
 
ekranı $3c00'a almak için;
 
lda #$f4
sta $d018
 
şeklinde geçiş yapabiliriz. Bu değerler Bank pozisyonundan itibaren geçerlidir. Banklar değiştikçe bankın başlangıç adresi bu değere eklenir. Örneğin $8000-$bfff arasındaki banktaysak son örnek $3c00 yerine $bc00'a işaret edecektir.
Başlık: Sprite cogullama
Gönderen: stranger - 02.11.2009 16:23:11
Örnekle demek istediğimi daha iyi anlatabilirim: Yani demek istediğim şu... Bu örnekte alttaki son 3 sprite'ın datası üstteki ile karışıyor (zaman yetmiyor). Senin trick'i buna uygulamaya çalışacağım gibi gözüküyor. Senin cevaba şimdi detaylı bakacağım.
 
!to"irq7.prg",cbm
ekran0=87
ekran1=ekran0+21+1
irq00=$03
ykor0=ekran0-20
ykor1=(ykor0+21)
* = $0801
!byte $0c, $08, $00, $00, $9e, $32, $30, $36, $31, $00, $00, $00
*=$080d
 
ldx#$00
stx$d020
stx$d021
jsr$e544
lda#$ff
sta$d015
ldx#$00
lda#$55
sta$d000,x
clc
adc#24
inx
inx
cpx#16
bne *-10
sei
lda #$7f
sta $dc0d
lda $d01a
ora #$01
sta $d01a
lda $d011
and #$7f
sta $d011
lda #$30
sta $d012
lda #sta $0314
lda #>irq1
sta $0315
cli
jmp*
 
irq1:
ldx#0
lda# ykor0
sta$d001,x
inx
inx
cpx#16
bne *-7
 
ldx #$00
lda #$80
sta $07f8,x
inx
cpx #8
bne *-6
 
lda #sta $0314
lda #>irq2
sta $0315
lda #ekran0
sta $d012
lda#$01
sta$d019
jmp $ea7e
 
irq2:
;ldx#0
;lda# ykor1
;sta$d001,x
;inx
;inx
;cpx#16
;bne *-7
lda#ykor1
sta$d001
sta$d003
sta$d005
sta$d007
sta$d009
sta$d00b
sta$d00d
sta$d00f
ldx #$00
lda #$c0
sta $07f8,x
inx
cpx #8
bne *-6
lda #sta $0314
lda #>irq1
sta $0315
lda #ekran1
sta $d012
lda#$01
sta$d019
jmp $ea7e
 
 
* = $2000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
 
 
* =$3000
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
!byte %11111111,%11111111,%11111111
Başlık: Sprite cogullama
Gönderen: skate - 02.11.2009 16:39:00
Bu tür cycle kritik durumlarda loop kullanmayı aklından bile geçirme kardeşim, açık olarak yazman lazım loopu. Sonda kullandığın cpx bne v.b. komutlar çok fazla cycle yerler. Anlattığım trick 8 sprite söz konusu olduğunda iç ekran açıkken tek çözüm diyebiliriz. Tek handikapı ekran değişeceği için eğer karakter ekranında birşeyler varsa aynı ekranın birden fazla yerde kopyasının bulunması gerekmesidir.
Başlık: Sprite cogullama
Gönderen: skate - 02.11.2009 16:41:55
örneği test ettim, tavsiyem 16 sprite'da da farklı datalar bulunmasıdır. Ben genellikle multiplexer testleri için çapraz hatları bulunan şekiller kullanırım. Tüm spriteların alanını kaplayacak köşegenleri birleştiren bir X ya da bir üçgen gibi şekiller. Multiplexer hataları çok daha net bir şekilde gözlemlenebilir bu şekilde.
Başlık: Sprite cogullama
Gönderen: stranger - 02.11.2009 16:52:36
Alıntı yapılan: skate;21674
Bu tür cycle kritik durumlarda loop kullanmayı aklından bile geçirme kardeşim, açık olarak yazman lazım loopu. Sonda kullandığın cpx bne v.b. komutlar çok fazla cycle yerler. Anlattığım trick 8 sprite söz konusu olduğunda iç ekran açıkken tek çözüm diyebiliriz. Tek handikapı ekran değişeceği için eğer karakter ekranında birşeyler varsa aynı ekranın birden fazla yerde kopyasının bulunması gerekmesidir.

Zaten alt satır için loopsuz yazmıştım çünkü loop'lu yazınca 3.sprite'tan ilerisini çizemiyor. Bu örnekte ekran adresini ne şekilde değiştirmem gerektiğini yazabilirsen çok makbule geçer :) Çünkü herhalde birşeyi eksik yapıyorum...
 
Birde karakter ekranında birşey varsa birkaç yerde kopyası olması gerekir diyorsun. yani eğer scroll varsa ne olacak? Gerçi spriteların olduğu alanda olmadığı, daha aşağılarda olduğu için herhalde sorun olmayacaktır diye düşünüyorum. Çünkü scroll'un olduğu alana gelene kadar ekranı default yeri olan $0400'e alabiliriz herhalde?
Başlık: Sprite cogullama
Gönderen: skate - 02.11.2009 17:08:42
Ekran adresini öncelikle sen belirleyeceksin. Diyelim ki $3800 ve $3c00'ı kullanmak istedin, yani ilk bankın mümkün olan son iki $400'lük alanını. Bu durumda
 
$3800 için
 
lda #$e4
sta $d018
 
$3c00 için
 
lda #$f4
sta $d018
 
sprite adresleri ise
 
$3800 için
 
$3bf8-$3bff
 
$3c00 için
 
$3ff8-$3fff
 
arasında yer alacaktır.
 
şeklinde geçiş yapabilirsin. Scroll konusunda doğru düşünüyorsun, spriteların bittiği yerden sonra istediğin bir ekrana geçip o ekranda scroll yapabilirsin. Örneğin ekranın üst yarısı (tam sprite multiplex edilen satırın olduğu yere kadar) $3800'ü, alt yarısı ise $3c00'ı gösteriyorsa bu durumda spriteların bitiminde bir değişiklik yapmazsan zaten ekranın alt bölümünde $3c00'dan itibaren olan adresler gösterilecek. Sen önceki rutininde diyelim ki 20. satırdan bir scroll geçiriyorsun ki varsayılanda bu satırın başlangıcı $0400+20*40 = $0720'ye denk geliyor. "$07XX" şeklindeki tüm adresleri "$3fXX" şekline çevirirsen scroll doğru ekranda kaymaya devam edecektir. Kısacası $3c00+20*40 = $3f20 şeklinde hesaplanır $3c00'daki ekran adresindeki scroll satırının hafıza adresi.
Başlık: Sprite cogullama
Gönderen: stranger - 02.11.2009 23:28:03
Skate trick mükemmel şekilde çalışıyor. Eline sağlık. Kodun çalışan halinide buraya paste ediyorum ki ileride belki birilerinin işine yarar yada ilgisini çeker.
 
!to"irq0c.prg",cbm
;Ekran ayarları
ekran0=87 ;2 ila 87 pixeller arası 0.ekran
ekran1=ekran0+21+1 ;buna 21 pixellik sprite uzunluğunu ve 1 pixel fazlalık ilave ettik
ykor0=ekran0-20 ; üst sıradaki spriteların y koordinatı
ykor1=(ykor0+21); alt sıradaki spriteların y koordinatı
* = $0801 ;autorun
!byte $0c, $08, $00, $00, $9e, $32, $30, $36, $31, $00, $00, $00
*=$080d
;$3800'deki ekranı temizle
ldx#0
lda#$20
sta$3840,x
inx
bne *-4

;Ekran rengi siyah
ldx#$00
stx$d020
stx$d021
;ekran siliniyor tüm spritelar açılıyor
jsr$e544
lda#$ff
sta$d015
;x koordinatında $55 'ten başlayıp 24 pixel arayla spritelar diziliyor
ldx#$00
lda#$55
sta$d000,x
clc
adc#24
inx
inx
cpx#16
bne *-10
;interrupt rutini
sei
lda #$7f
sta $dc0d
lda $d01a
ora #$01
sta $d01a
lda $d011
and #$7f
sta $d011
lda #$2
sta $d012
lda #sta $0314
lda #>irq1
sta $0315
cli
jmp*
irq1:
;ekran normal $0400'de
lda #$14
sta $d018
;spritelar y koordinatında diziliyor
ldy# ykor0
sty$d001
sty$d003
sty$d005
sty$d007
sty$d009
sty$d00b
sty$d00d
sty$d00f
;üst spritelar için $c0x$40=$3000 den data alıyoruz
ldx #$00
lda #$c0
sta $07f8,x
inx
cpx #8
bne *-6
;ekran0 ın değeri ile ekranı bölüp diğer irq ya atlıyoruz
lda #sta $0314
lda #>irq2
sta $0315
lda #ekran0
sta $d012
lda#$01
sta$d019
jmp $ea7e
;Alt sıradaki spritelar ile ilgili bölüm
irq2:
ldy# ykor1
sty$d001
sty$d003
sty$d005
sty$d007
sty$d009
sty$d00b
sty$d00d
sty$d00f
;Ekran $3800'de
lda #$e4
sta $d018
;Spritelarda $3c00'da
ldx #$00
lda #$f0
sta $3bf8,x
inx
cpx #8
bne *-6
lda #sta $0314
lda #>irq1
sta $0315
lda #ekran1
sta $d012
lda#$01
sta$d019
jmp $ea7e
* = $3000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
!byte %00000000,%00000000,%00000000
!byte %11111111,%11111111,%11111111
*=$3c00
!byte %11111111,%11111111,%11111111
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %10011001,%10011001,%10011001
!byte %11111111,%11111111,%11111111
Başlık: Sprite cogullama
Gönderen: skate - 03.11.2009 00:02:38
Belki buraya post ederken birşey değiştirmiş olabilirsin ancak post ettiğin kodda sprite pointer adresleri hatalı. Ekran $3800'de olduğuna göre;
 
sta$3ff8,x

satırı
 
sta $3bf8,x
 
şeklinde düzeltilmeli. O zaman da düzgün çalışıyor zaten. Geri kalan kod gayet düzgün çalışıyor, eline sağlık. Multiplexer yapabilmek ve bu tür trickleri kullanabilmek demek çok daha advanced efektler için hazır olduğunu gösteriyor kardeşim. Partide sana göstereceğim birkaç güzel trick var, özellikle Cumartesi geceyarısından sonra bol bol takılırız seninle :)
Başlık: Sprite cogullama
Gönderen: stranger - 03.11.2009 09:27:46
Sanırım yapıştırırken bişeyler oldu. Kodun en son halinde $3800'deki ekranı silmeye gerek kalmıyordu. şu anda pointerları düzelttim+ekranı silme rutini ekledim çalışıyor. Yinede eve gidince bakıcam bende merak ettim.