ASM13S Partikkelisydän

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
Thudney
Newcomer
Posts: 26
Joined: Mon Aug 27, 2007 10:18 pm
Location: Finland
Contact:

ASM13S Partikkelisydän

Post by Thudney »

Assyillä toteutin tälläisen. Apuja tuli mm. vieressä istuneelta atomilta & msqrt:ltä. Tässä on esimerkki/tutoriaali muodossa mitä tässä tapahtuu. Koodissa käytetään muistia yms nopeutuksia. Selitän tässä kuinka ne toimivat, sikälimikäli olen ymmärtänyt ne oikein.

Jos pelkän koodin perässä tulit niin selaile tämä viesti loppuun!

Koodi on ensin tehty, sen jälkeen optimoitu koonsa puolesta ja tämänjälkeen viimeistelty parilla nopeusmuunnoksella jotka lisäävät pari riviä ja muistikomennot.

Code: Select all

Const sw=700'jos vaihdat, säädä myös sw2!
Const sh=1000
Const sw2=350'sw2=sw/2
SCREEN sw,sh',32,0
Alustetaan näyttöruutu, tässä koodissa käytetään muuttujia ScreenHeight() & ScreenWidth() komentojen sijaan koodin lyhyyden vuoksi. sw2 muuttuja on sijoitettu alustettavaksi myöskin tänne. Toiminnaltaan kertoo vain näytön leveyden jaettuna kahtia, koska tämä toimii nopeammin ja lyhyemmin koodissa kuin jakaisi joka kohdassa arvon kahdella, jakolasku on hitaampi kuin muisti siirto. Ruudun koko on aika optimaalinen tähän, pienempää ei oikeastaan kannata kokeilla, suurempi kyllä toimii. Fullscreen palanen on kommentissa jotta se aukeaa windowedina, voi halutessaan säätää koon oman ruudun kokoiseksi.

Code: Select all

SetFont LoadFont("arial",1)
Ladataan jokin satunnainen ( tässätapauksessa arial ) fontti muistiin koolla 1. Koko on tärkeä jotta printillä saadaan myöhemmin aikaan ruutubufferi siirto yhdellä ylöspäin.

Code: Select all

Dim c(359)
For i=0 To 359
    h#=i/60.0
    x#=1-Abs((h Mod 2)-1)
    c(i)=(255 Shl 24)+((x*((h<2 And h>=1) Or (h>=4 And h<5))+(h<1 Or h>=5))*255 Shl 16)+((x*(h<1 Or (h>=3 And h<4))+(h>=1 And h<3))*255 Shl 8)+(x*(h=>5 Or (h>=2 And h<3))+(h>=3 And h<5))*255
Next i
Luodaan ja alustetaan väriarvotaulu. Jos koodi olisi tehty rivirajoitteisena tämä laskelma olisi suoritettu joka framessa, mutta koska rajoitusta ei tälläkertaa ole, voidaan se suorittaa ennen päälooppia & jokaista framea jolloin looppikoodi toimii nopeammin. Väriarvon hausta kiitokset msqrt:n tekemälle funktiolle josta tähän on koodi kutistettu suoritusnopeutta&kokoa hakiessa.

Code: Select all

tb=MakeMEMBlock(20)
PokeFloat tb,0,sw2
PokeFloat tb,4,650.0
PokeFloat tb,12,6.0
PokeFloat tb,16,11.0
Luodaan ja alustetaan muistiblockki, tätä tullaan myöhemmin käyttämään type-esiintymän alustamiseen koska memcopy on nopeampi kuin alustaa 5 muuttujaa, vaikka alustuksia joudutaan muokkaamaan vähän on tämä ratkaisu tässätapauksessa nopeampi. Huomioi, että jos alustat useita type-esiintymiä samoilla arvoilla voi toimintaa nopeentaa tällätavoin.

Code: Select all

k=WrapAngle(k+1)
Lisätään muuttujaan k 1 ja wrapangle kääntää muuttujan arvon 0-359 suoraan muuttujaan. Muuttujalla saadaan oikea väriarvo haettua väriarvo taulusta joka toteutetaan ennen type-esiintymä alustusmuisti luontia. Mikäli koodi olisi rivirajoitettu, tämän jälkeen, ilman seuraavaa pokeinttiä, olisi värilaskurikoodi tässä hidastamassa loopin pyörimistä.

Code: Select all

PokeInt tb,8,c(k)
Lisätään type-esiintymän alustusmuistiin väriarvo, jota myöhemmin käytetään pikselin piirtoon.

Code: Select all

b=0
Repeat
b+1
Until b=150
Koska cb, niin tuo on nopeampi kuin vastaava for looppi. kyseinen b arvo lisää joka framella uusia piirrettäviä pisteitä.

Code: Select all

a=Rand(0,360)
l=Rand(1,12)
d.ds=New(ds)
MemCopy tb,0,ConvertToInteger(d),12,20
d\x=d\x+l*Sin(a)
d\y=d\y+l*Cos(a)
d\sX=d\sX+Rnd(-.7,.7)
d\sY=d\sY+Rnd(-.7,.7)
Eli ylemmän for->repeat kikan avulla toteutetun loopin sisältö:
Satunnoidaan 2 arvoa.
Luodaan uusi type-esiintymä partikkeli tyypistä.
Kopioidaan partikkelin arvot muistista type-esiintymään, koska useampi arvo, on tämä nopeampi.
Muokataan vähän äskeisellä muistisiirrolla toteutettuja arvoja, jos koodi olisi ollut jossain rivimäärä rajoitteisessa kisassa, olisi tässäkohin ollut tyyppialustus suoraan.

Code: Select all

Lock
For d.ds=Each ds
 d\l+1
 d\sY-.4
 If d\l>40 Then d\sX-.5
 d\x+d\sX
 d\y+d\sY
 If d\x>sw2 And d\x<sw And d\y>0 And d\y<sh Then
  PutPixel2 d\x,sh-d\y,d\c
  PutPixel2 sw-d\x,sh-d\y,d\c
  drops+2
 Else 
  Delete d
 EndIf
Next d
Unlock
Koska loopissa piirretään pisteitä PutPixel2 komennolla lukitaan loopin ulkopuolella näyttöpuskuri.
Käydään jokainen pikseli for loopissa läpi ja piirretään taululle kahtena toisen ollessa kloonisijainti. Toisinkuin ylemmässä, tässä for loopissa ei ole niin kauheaa ongelmaa nopeuden kannalta, miksi? koska cb tekee ylimääräisen tarkistuksen numeroiden kanssa ja tästä aiheutuu että repeat on nopeampi.
Myöskin lasketaan vähän sijainteja ja sellaisia. Ja muistetaan poistaa näyttöpuskuri lukko! Tuossa tarkistetaan Iffissä ennen pikselien siirtoa onko pikseli tietyllä alueella käyttäen sw2 muuttujaa sw/2 jakolaskun sijaan, jakolaskun ollessa huomattavasti hitaampi kuin muuttujasiirron on tämä huomattavasti nopeampaa.

Code: Select all

Print ""
DrawScreen OFF
Ylempänä mainitsin fontista ja koon tärkeydestä. Eli tässäkohin ensin print siirtää taustabufferia fonttikoon verran ylöspäin, tämän jälkeen DrawScreen työntää taulun ruudulle, off komennon perässä meinaa ettei puskuria tyhjennetä, jolla saadaan aikaan tuo hieno sateenkaariefecti <3.

Code: Select all

Type ds
    Field x#
    Field y#
    Field c
    Field sX#
    Field sY#
    Field l As Byte
EndType
Const sw=1920
Const sh=1080
Const sw2=960'sw2=sw/2
SCREEN sw,sh,32,0
SetFont LoadFont("arial",1)
Dim c(359)
For i=0 To 359
    h#=i/60.0
    x#=1-Abs((h Mod 2)-1)
    c(i)=(255 Shl 24)+((x*((h<2 And h>=1) Or (h>=4 And h<5))+(h<1 Or h>=5))*255 Shl 16)+((x*(h<1 Or (h>=3 And h<4))+(h>=1 And h<3))*255 Shl 8)+(x*(h=>5 Or (h>=2 And h<3))+(h>=3 And h<5))*255
Next i
tb=MakeMEMBlock(20)
PokeFloat tb,0,sw2
PokeFloat tb,4,650.0
PokeFloat tb,12,6.0
PokeFloat tb,16,11.0
drops=0
Repeat
    SetWindow Str(FPS())+"drops: "+drops
    k=WrapAngle(k+1)
    PokeInt tb,8,c(k)
    b=0
    Repeat
        b+1
        a=Rand(0,360)
        l=Rand(1,12)
        d.ds=New(ds)
        MemCopy tb,0,ConvertToInteger(d),12,20
        d\x=d\x+l*Sin(a)
        d\y=d\y+l*Cos(a)
        d\sX=d\sX+Rnd(-.7,.7)
        d\sY=d\sY+Rnd(-.7,.7)
    Until b=150
    drops=0
    Lock
        For d.ds=Each ds
            d\l+1
            d\sY-.4
            If d\l>40 Then d\sX-.5
            d\x+d\sX
            d\y+d\sY
            If d\x>sw2 And d\x<sw And d\y>0 And d\y<sh Then
                PutPixel2 d\x,sh-d\y,d\c
                PutPixel2 sw-d\x,sh-d\y,d\c
                drops+2
            Else 
                Delete d
            EndIf
        Next d
    Unlock
    Print ""
    DrawScreen OFF
Forever
DeleteMEMblock tb
Ja tässä tämä koodi on kokonaisuudessaan, koodi on toteutettu Assembly 2013 summer tapahtuman aikana, rivimäärä on käynyt ~106?
Resoluutiosäätö on aika selvää, mutta for->repeat säädössä oleva "until b=150" vaikuttaa pikselimäärän luontiin, mitä isompi luku sitä useamman pikselin tämä luo, omalla koneella toimii tässä kohin "220" ilman drops laskuria pomppii fps ~58-61

Kysymyksiä, kommentteja ja ehdotuksia voi heitellä.
Ja viimeiseksi
http://www.youtube.com/watch?v=Yn6wz498Pzk
Last edited by Thudney on Fri Dec 13, 2013 4:53 am, edited 1 time in total.
User avatar
valscion
Moderator
Moderator
Posts: 1599
Joined: Thu Dec 06, 2007 7:46 pm
Location: Espoo
Contact:

Re: ASM13S Partikkelisydän

Post by valscion »

Thudney wrote:Assyillä toteutin tälläisen. Apuja tuli mm. vieressä istuneelta atomilta & msqrt:ltä. Tässä on esimerkki/tutoriaali muodossa mitä tässä tapahtuu. Koodissa käytetään muistia yms nopeutuksia. Selitän tässä kuinka ne toimivat, sikälimikäli olen ymmärtänyt ne oikein.
Uuh, aika mehevää! Ja kiitos selityksistä, niitä oli mukava lukea :) Harmiksi täytyy vain todeta, että koodi heittää itselläni ainakin muutaman sekunnin ajon jälkeen MAVia. Onkohan kaikki muistikikkailut ja putpixelit varmasti ok-paikoissa?
cbEnchanted, uudelleenkirjoitettu runtime. Uusin versio: 0.4.1 — Nyt myös sorsat GitHubissa!
NetMatch - se kunnon nettimättö-deathmatch! Avoimella lähdekoodilla varustettu
vesalaakso.com
Thudney
Newcomer
Posts: 26
Joined: Mon Aug 27, 2007 10:18 pm
Location: Finland
Contact:

Re: ASM13S Partikkelisydän

Post by Thudney »

Normi cb:eellä ajettaessa toimii esimerkissä olevalla toisella resoluutiolla joka on aika minimi. cbe yms en koittanut. Ei oo fullhd ruutua joten tuosta resoluutiosta en tiedä mikä on tuossa valmiiksi copypastettavassa koodissa. Efekti alkaa vasta parin sekunnin jälkeen sateenkaareutumaan ylöspäin.
Post Reply