atarionline.pl Rysowanie pikseli w Action! - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1: CommentAuthorZelgadis
    • CommentTime24 Dec 2020 zmieniony
     
    Hej wszystkim,

    Na wstepie zycze wesolych Swiat, duzo zdrowia i wszystkiego co najlepsze :).

    Ktos moglby mi doradzic jak zaczac z pisaniem wlasnej procedury do wyswietlania pikseli w Action! w jakims trybie graficznym. Z tego co czytalem to domyslny PLOT wywoluje procedure OS ktora ma spory overhead i najlepiej napisac swoja. Jednak nie wiem kompletnie od czego zaczac, skad wiedziec gdzie jest pamiec obrazu by moc w niej zapisywac bajty ktore beda odpowiadaly pikselom jaka jest organizacja pamieci ekranu w tym trybie itd. itd.

    Tak w ogole ktory tryb polecacie najbardziej do tworzenia gry? W jakim trybie najczesciej powstawaly gierki?

    Z gory dziekuje za pomoc i jeszcze raz wesolych Swiat!
    • 2:
       
      CommentAuthorsun
    • CommentTime25 Dec 2020
     
    Najczęściej to chyba jednak tekstowy antic 4.
  1.  
    @Zelgadis

    Tak jak napisał SUN - ale jako konsultant IT odpowiem "to zależy" :)

    Najpierw zapytałbym czy wiesz - jaki problem próbujesz rozwiązać rysowaniem w trybie graficznym? Grom na korzyść prędkości - wyszło użycie trybu znakowego, ale to wciąż nie ma różnicy od tego jak można prosto rozwiązać problem rysowania w Action!
    Jeśli chcesz Hi-res w trybie ANTIC 15 (0x0F), to najprościej zajrzeć na PLOT napisany w kodzie maszynowym przez Arka Łukszo (Gizmo) oraz Kubę Husaka -> ->link<-
    Ja na początku drogi zacząłem od zrozumienia jak działa Display List i napisałem program dla Antic, żeby mieć kontrolę nad pamięcią obrazu. Oczywiście mogą mnie zjeść eksperci, za tę herezję, ale podstawowe tryby Antic, bez udziwnień, mają odwzorowanie mapowe - fragment pamięci bajt po bajcie odpowiada za to co narysuje ANTIC i a wartości bitowe - za to co pokoloruje GTIA. Takie uproszczenie pozwoliło mi zrozumieć koncepcję koloru piksela na ekranie i jak na razie mi wystarcza.

    Na start polecę jak zawsze - ->link<-
    Warto zawsze mieć pod ręką Mapę Pamięci ATARI ->link<-

    W programach Action! warto zacząć od najważniejszej sztuczki ludzkości

    BYTE ARRAY P = $00


    Ta magiczna linijka definiuje tablicę bajtową P, na obszar pamięci od adresu $00, co umożliwia bezpośredni dostęp do pamięci (np. rejestrów :)

    P($D01A)=0 ; zapis wartości 0 do rejestru koloru i jasności "tła" COLBK 


    Oczywiście można też się pokusić o wstaiwenie "komórki" w obszar pamięci:

    Y=10
    X=20
    WIDTH=40 ; przykład !!!

    ADDR=X+(Y*WIDTH)

    P(ADDR)=31 ; okrągłą liczba mersena w 1/4 wartości bajta :)


    Na ty etapie już można pokusić się o zabawę z kolorami:

    Bardziej zaawansowany przykład -

    BYTE ARRAY DIST = [
    $70 ; EMPTY ROW
    $70 ; EMPTY ROW
    $4D $00 $80 ; LMS - adres obszaru pamięci 0x8000
    $04 $04 $04 $04 $04 $04 $04 $04
    $04 $04 $04 $04 $04 $04 $04 $04
    $04 $04 $04 $04 $04 $04 $04
    $41 ; TU POWINIEN BYĆ PODANY ADRES DIST, ale zadziała bez]

    CARD SDLSTL=$230 ; 560 dziesiętnie
    CARD DL=$230

    DL=DIST
    SDLSTL=DIST


    I mamy ustawiony tryb ANTIC 0x0D, gdize masz 40 bajtów na linię obrazu ->link<-
    Przykład wcześniejszy z bezpośrednim adresowaniem, zadziała.

    do Display List - polecę narzędzie naszego kolegi Bocianu: ->link<-
    • 4: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    Dzieki wielkie za odpowiedzi ;). A pytanko co do trybu znakowego w grach - to w jaki sposob tworzone byly software'owe sprity w trybie znakowym ? Ja myslalem, ze gry byly w calosci w trybie bitmapy i potem takie software'owe sprity to bylo poruszajace sie tlo ;).

    No ten kurs Action! tdc bardzo mnie interesuje, no ale niestety spoznilem sie na niego i czekam, az zostana opublikowane zapiski ;)
  2.  
    @zelgadis

    znalazłem jeszcze takie coś:
    GR15 - ->link<-

    GR8 - ->link<-

    Ale to nie wiem czy działa, nie potrzebowałem sprawdzać - ta procka od Kuby i Arka, działa na 100%

    Co do "soft sprites" tu się nie wypowiem, jak rozgryzałem np. "Robbo" i "Lasermanię" - to jest to zrobione "na znakach" - co drugą linię zmienia się zestaw znaków, świetnie sprawdza się w grach z planszą blokową. Z tego co widzę, to inne polskie światowe szlagiery - Adam is Me i Laura, zrobione są tą samą metodą. I słusznie, po co zmieniać coś co działa IDEALNIE?
  3.  
    @zelgadis

    nie mogę przejść obojętnie bez podania sztuczki programistycznej z Warsztatów Action!

    CARD ARRAY FY(30)


    czyli w skrócie stablicowanego mnożenia, z pierwszego przykładu

    zamiast
    ADDR=X+(Y*WIDTH)


    rozszerzamy PROC INIT
    FOR Q=0 TO 24 DO FY(Q)=Q*40 OD


    a następnie używamy:
    P(ADDREKR+FY(Y)+X)=31


    gdzie ADDREKR to zmienna przechowująca adres w pamięci zawierający dane wyświetlanego ekranu.
    • 7: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    Dzieki :). A ktos moze wypowie sie jak wyglada to w grach typu Misja czy Fred? Tutaj postacie sie poruszaja plynnie wiec nie wyglada jakby to bylo na znakach robione ale moge sie mylic. Wiec zastanawia mnie jak mieszane byly takie sprity ze znakowym trybem w ktorym wyswietlana byla reszta planszy.

    @mkolodziejski

    Dzieki wielkie za te sztuczki! Na pewno wprowadze je w zycie :). Jak cos ciekawego jeszcze Ci sie przypomni z warsztatow to chetnie przygarne ta wiedze ;))
  4.  
    @zelgadis

    wybacz, że znowu ja, ale - gry to teatr iluzji :) jak dema - pokazują coś co wydaje się czymś nieco innym - to ich duża zaleta - "oszukują widza" - to dlatego są takie atrakcyjne.

    Akurat Freda omawialiśmy na ostatnim Środowisku Prasowym - może niekoniecznie wszystkie techniczne szczegóły, ale na pewno kilka detali padło - zwróć uwagę, że tło jest "powtarzalne" - zbudowane jakby z klocków, to wskazówka na to, że jednak to są "znaki" lub zbiory "znaków" a postacie są duże, wielokolorowe i poruszają się płynnie poza "gridem" - to podpowiada, że to sprzętowe sprite'y (duszki/pociski). Nie sprawdziłem jak było w tym przypadku, ale sprytni programiści, używają kilku duszków i przesuwają je razem jako jedna postać, kiedy "ANTIC dojedzie" do miejsca rysowania innej postaci - zmieniana jest zawartość banków pamięci duszków i efekt jest osiągnięty.

    Jestem dopiero na etapie początkowym zabawy duszkami, ale jak zobaczysz co nasz Mentor TDC na warsztatach pokazywał - Virus Invaders - zobacz dyskietki z archiwów, tam są wszystkie źródła - rysowane wiele postaci obok siebie, a warto też rzucić okiem na inne jego produkcje - mnie pod tym względem zaciekawił Patrol In The Space ->link<- - gdzie rakieta to kilka duszków.

    ps. serio zajrzyj do ATRów z warsztatów, w środku jest mnóstwo źródeł, dokładny opis co było zmieniane i pokazywane, kod jest na tyle prosty i zwięzły, że przez pierwsze ćwiczenia można spróbować przebrnąć samodzielnie.

    Tam znajdziesz też dużo różnych sztuczek i "odkryć" np.
    - funkcje do synchronizacji CPU z konkretną linią rastra wyświetlanego
    - zabawy z dźwiękiem "sampli" generowanym na podstawie zawartości ROM Atari (jak w grach od Zeppelin Games)
    - wczytywanie "zasobów" z dyskietki (grafika z programu Graph 2 Font, fonty, binarne tablice chociaż teraz można je dołączyć do programu Action! w źródłach np. korzystając z ->link<-
    - dużo sztuczek z pomiarem wydajności rysowania przy okazji metod efektywnego umieszczania napisów na ekranie (np. score)
    • 9: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    @mkolodziejski - Dzieki za odpowiedz :). No to ciekawe jest, bo gracz jest zrobiony z duszkow ale reszta rzeczy ? To sa pomnozone duszki sprzetowe tez? Do zrodel chetnie zagladne bo pewnie sporo sie z tego naucze - jednak fajnie by bylo jakby te kursy byly dostepne skoro sa zarchiwizowane. Ja jestem w stanie nawet za takie filmy zaplacic byle by miec do nich dostep ;).
  5.  
    @Zelgadis - tak, wiele postaci można zrobić z duszków na tym samym ekranie. Jednocześnie. Cechą sprzętowej obsługi duszków jest to, że zostaną narysowane tam gdzie bedzie to konieczne. Są ograniczenia, ale zobacz na to: ->link<- a konkretnie na to nagranie - ->link<- - to co widać to duszki. Dużo duszków.
    • 11:
       
      CommentAuthorKaz
    • CommentTime25 Dec 2020 zmieniony
     
    • 12: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    O to ciekawe :). To fajne rzeczy mozna robic na tych sprzetowych duszkach ;). Probowalem zrobic cos w kierunku ogarniecia DL i odczytac sobie adres poczatku DL. Napisalem cos takiego:
    BYTE C
    BYTE Chr

    PROC Main()

    Graphics(1)
    C=Peek($230)
    Print(C)
    Chr=GetD(7)

    RETURN

    Ale w rezultacie program wydrukowal mi jakies krzaki zamiast mniej znaczacego bajtu adresu startu DL.
    • 13: CommentAuthortebe
    • CommentTime25 Dec 2020
     
    dużo duszków ale tego samego kształtu

    tutaj (C64) ->link<- od 5 min są 72 duszki, w całym demie możemy podejrzeć duszki wykorzystane do realizacji kolejnych efektów
    • 14: CommentAuthorxorcerer
    • CommentTime25 Dec 2020
     
    Bardzo fajny trop z tym debuggerem, bo on pozwala debugować nie tylko C64 ale też i A-8bitowe ->link<-
    • 15: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    Ok debuggerem w Alltirra chyba udalo mi sie znalezc DL:
    70 70 70 46 80 1E 06 06 06 06 06 06 06 06 06 06 06 06 06 9F 02 02 02 41 5E 9D

    Adres poczatku ekranu to bedzie 158(1E) * 256 + 128(80) ? Chyba cos nie tak licze bo co prawda narysowalem jakis znak na ekranie, ale to bardziej na jego srodku a nie na poczatku wiec jestem blisko ale troche cos za duzy ten adres policzylem


    Jak prawidlowo trzeba to wyliczyc? Powyzszy wzor znalazlem na "Mapping the Atari" ale pewnie do roznych trybow rozne wzory sa
    • 16:
       
      CommentAuthorbocianu
    • CommentTime25 Dec 2020
     
    w debugerze altirry masz komendę:
    .dumpdlist
    • 17: CommentAuthormkolodziejski
    • CommentTime25 Dec 2020 zmieniony
     
    @Zelgadis - znacznie szybciej będzie użyć wymienione przeze mnie narzędzie Bocianu do skonstruowania swojej własnej DL ->link<- - prędzej czy później będziesz chciał ją zmodyfikować :)

    @Xorcerer - debugger jest super, pozwala MONITOROWAĆ zmiany w pamięci, ale nie udało mi się przeskoczyć możliwości skopiowania fragmentów choćby charsetu ;(

    pozwoliłem sobie nieco poprawić Twój przykład :)

    ze sztuczek - kompilacja powoduje wstawienie w MONITORze litery "R", a po zakończeniu "E" - w celu ułatwienia pętli developmentu :)

    MODULE

    BYTE SAVMSCL = 88, ; lsb SCREEN
    SAVMSCH = 89, ; msb SCREEN
    R = $D20A, ; random
    KEY = $2FC ; keyboard

    CARD SCREEN

    BYTE ARRAY P = $00
    CARD ARRAY FY(30)

    PROC WAIT=*(BYTE F)[$18$65$14$C5$14$D0$FC$60]

    PROC INIT()
    SCREEN=SAVMSCL+256*SAVMSCH
    [96]

    PROC MAIN()
    GRAPHICS(1)

    INIT()

    WHILE KEY#28 DO
    P(SCREEN) = R&31
    WAIT(5)
    OD

    SNDRST()
    GRAPHICS(0)
    KEY=42
    SET 764=40
    [96]
    • 18:
       
      CommentAuthormgr_inz_rafal
    • CommentTime25 Dec 2020 zmieniony
     
    Do czytania/zapisywania kawałków pamięci służy `.readmem` i `.writemem`.
  6.  
    @mgr_inz_rafal - w 64XE Debugger? bo w Altirra to tak
  7.  
    W Altirra, rzecz jasna. Sry, pewnie nie ogarnąłem :)
    • 21: CommentAuthorZelgadis
    • CommentTime25 Dec 2020
     
    To w jaki sposob odczytywac wartosci z pamieci uzywajac samego Action!? Bo robienie Peek i potem printowanie tego wyswietla krzaczki zamiast wartosci spod komorki pamieci ;). A nie ukrywam jak przyjdzie mi folia do klawiatury do mojego 65XE to skusze sie by na prawdziwym sprzecie sie bawic i wtedy juz altirra debuggerem sobie nie podejrze pamieci ;). Ale chyba w Action jest monitor to w sumie tym moglbym sobie odczytywac wartosci :)
  8.  
    @Zelgadis - w Action! jest bardzo praktyczny monitor, podglądanie zawartości pamięci osiągniesz przez polecenia:
    ? ADRES
    * ADRES


    po szczegóły odeślę do instrukcji, bo ja niespecjalnie się polubiłem z tym sposobem przeszukiwania.
    • 23: CommentAuthorZelgadis
    • CommentTime25 Dec 2020 zmieniony
     
    @mkolodziejski - Dziekuje bardzo za Twoja pomoc w ogarnieciu przeze mnie tego wszystkiego :). Wszystkim pozostalym rowniez dziekuje. Pierwsze kroki za mna, juz potrafie rysowac znaki poprzez edycje pamieci obrazu juz zdefiniowanej display listy. Jutro sobie sprobuje ogarnac swoja display liste.
    Ten Action! zaczyna mi sie coraz bardziej podobac - jak na rok 1983 to jest znakomite narzedzie do tworzenia na Atarku. Szkoda, ze nie zyskal wiekszej popularnosci.
    • 24: CommentAuthormkolodziejski
    • CommentTime26 Dec 2020 zmieniony
     
    @Zelgadis

    oj tak, jak słusznie zauważyłeś - Action! mimo składni wywodzącej się z pradziadka Algol'a 60 - potrafi nieźle namieszać w głowie programiście - dopóki się nie oswoisz z "dziwacznymi konstrukcjami"

    - definicja przy deklaracji - "przypina" (nowoczesny aspekt znany jako "two-fold binding" np. w AngularJS, lub późniejszym TypeScript) zmienną do wartości rejestru/komórki/-ek pamięci - działa w obie strony
    - definicja przy deklaracji CARD dla adresu (CARD to dwa bajty) - wskazany adres "przypina" od razu LSB i MSB adresu i sąsiada (jako wartość niewymaga przekształcenia pozycyjnego - dla przykładu CARD TEMP=$230 jest równoważne BYTE TEMPLSB=$230, BYTE TEMPMSB=$231, tylko TEMP zawiera już gotową liczbę 16bitową, a pojedyncze bajty wymagają przekształcenia pozycyjnego - TEMP=TEMP1*256+TEMP2
    - nie ma drzewa wywołań - np. FUNCTION(FUNCTION2(x), y) nie zdziała - zgłosi ERROR 8 - błąd składni, prosto to rozwiązać przez ekstrakcję FUNCTION2(x) i przypisanie do tymczasowej zmiennej
    - wszystkie zmienne zajmują globalną przestrzeń adresową (ST - Symbol Table), mimo zasięgu określnego w ich deklaracjach - przypilnuje kompilator, to jeśli będziemy mieli dwie zmienne o tej samej nazwie - w zasięgu lokalnym i zasięgu globalnym, przypisanie zostanie zrealizowane przez ostatnią wykonaną operację
    - przypisanie do CARD zmiennej BYTE ARRAY - spowoduje wstawienie w komórki wskazywane w CARD (two-way binding !) ADRESU tablicy

    ps. użyłem dwóch zmiennych bo robię tak w celu przechowania w lokalnym kontekście aktualnie zmienianej DListy - niefortunnie skracany przykład stracił ten sens bo obie zmienne (SD i SDLSTL) wskazują na to samo w tym samym kontekście. Wybacz, moje niedopatrzenie.

    Skonsolidowany materiał: ->link<- :)
    • 25: CommentAuthorZelgadis
    • CommentTime26 Dec 2020
     
    @mkolodziejski - Dziekuje za jak zwykle bardzo wyczerpujaca i bezpretensjonalna odpowiedz :). Chyba jeszcze nie zapomniales jak byles cieleciem nawiazujac do dawnego powiedzenia "Zapomnial wol jak cieleciem byl" i bardzo to w ludziach cenie ;).

    P.S
    Skasowalem pytania myslac, ze sa za glupie ale widze, ze zdazyles odpowiedziec :D.
  9.  
    @Zelgadis

    najważniejsze, żebyś samodzielnie próbował - Action! ma swoje "humory", ale to bardzo wygodne i przyjemne narzędzie.
    • 27: CommentAuthorZelgadis
    • CommentTime26 Dec 2020 zmieniony
     
    No juz sobie swoja DLke zrobilem, dziala ;). Rysowanie obramowania planszy, wyswietlenie gracza i poruszanie nim juz mam naskrobane -
    malo ale powoli idzie do przodu w kierunku napisania swojej pierwszej gry na Atari ;). Juz troche ogarnalem tego Action!, poczytalem troche manuala z 2018 roku na AtariWiki i coraz bardziej mi sie to podoba :).

    Fajna stronke znalazlem do ogarniecia DLI i innych bajerow -
    ->link<-

    Czytam sobie i poki co wszystko kumam ;)
    • 28:
       
      CommentAuthortdc
    • CommentTime28 Dec 2020
     
    Ho! Ho! Ho! Chciałoby się powiedzieć Panowie!;) Cytując pewnego rubasznego staruszka ;))

    W wolnej chwili przeczytam Wasze posty;)
    • 29: CommentAuthorZelgadis
    • CommentTime29 Dec 2020 zmieniony
     
    Hejo, mam pytanie. Zrobilem sobie wskaznik na tablice i teraz chcialbym przypisac wartosc do zmiennej z adresu na ktory wskazuje tablica. Cos w tym stylu

    BYTE ARRAY Array1 = [10 20 30 40 50]
    BYTE POINTER Ptr
    BYTE Variable

    PROC Main()

    Ptr = @Array1
    Variable = (wartosc spod adresu na ktory wskazuje Ptr) <- tego nie wiem

    RETURN

    @Edit

    Dobra, ogarnalem :D. Trzeba bylo zrobic tak

    BYTE ARRAY Array1 = [10 20 30 40 50]
    BYTE POINTER Ptr
    BYTE Variable

    PROC Main()

    Ptr = Array1
    Variable = Ptr^
    PrintBE(Variable)

    RETURN
    • 30:
       
      CommentAuthorKaz
    • CommentTime30 Dec 2020
     
    Zelgadis - jak użyjesz znaczników [ code ] i [ /code ] to program stanie się czytelniejszy:

    "Hejo, mam pytanie. Zrobilem sobie wskaznik na tablice i teraz chcialbym przypisac wartosc do zmiennej z adresu na ktory wskazuje tablica. Cos w tym stylu

    BYTE ARRAY Array1 = [10 20 30 40 50]
    BYTE POINTER Ptr
    BYTE Variable

    PROC Main()

    Ptr = @Array1
    Variable = (wartosc spod adresu na ktory wskazuje Ptr) <- tego nie wiem

    RETURN


    @Edit

    Dobra, ogarnalem :D. Trzeba bylo zrobic tak

    BYTE ARRAY Array1 = [10 20 30 40 50]
    BYTE POINTER Ptr
    BYTE Variable

    PROC Main()

    Ptr = Array1
    Variable = Ptr^
    PrintBE(Variable)

    RETURN
    "
    • 31: CommentAuthorZelgadis
    • CommentTime30 Dec 2020
     
    O, dzieki Kaz za info :)