atarionline.pl DLI i PMG - problem - 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:
         
        CommentAuthorlarek
      • CommentTime14 May 2011 14:05
       
      Chciałem wykorzystać jednego duszka i wyświetlić na ekranie dwa niezależne od siebie obiekty. Jeden w górnej części ekranu, drugi w dolnej. Obiekty mają poruszać się tylko poziomo. Sprawa wyglądała na prostą, a przynajmniej tak mi się wydawało. Mniej więcej w połowie ekranu wrzuciłem przerwanie DL, które „tnie” duszka na pół i wpisuje nową pozycję poziomą dla obiektu dolnego... W przypadku zastosowania DLI dla kolorów ekranu nie ma problemu. Od linii, w której występuje przerwanie na ekranie jest nowy kolor. Z duszkami to nie działa! Zapisanie rejestru HPOSP0 (poziomo pozycja PLAYER0) w trakcie przerwania zmienia położenie całego duszka na ekranie, a nie tylko części, po której wystąpiło przerwanie. Pomyślałem sobie: no tak, przy kolorach mamy rejestry kolorów i ich cienie, a w PMG tego nie ma (jest?). Jak sobie radzicie w takich sytuacjach? Wymyśliłem, że wrzucę dwa przerwania DLI – jedno tuż przed miejscem, w którym ma się pojawić dolny obiekt, a zaraz po nim drugie DLI, które „przywróci” pozycję poziomą, aby górny obiekt wyświetlany był poprawnie. Kiepsko się to sprawdza, bo przez krótką chwilę widać na ekranie, że górny duszek pojawia się na pozycji poziomej odpowiadającej dolnemu i odwrotnie – dolny czasami pojawi się na pozycji górnego. Jest to tylko chwilka, ale jest i dyskwalifikuje takie rozwiązanie. Przecież w grach stosuje się taką technikę i jakoś nie zauważyłem w nich tego niekorzystnego efektu. Co robię źle?
      • 2: CommentAuthorgorgh
      • CommentTime14 May 2011 15:05 zmieniony
       
      najpierw ustawiasz pozycję gracza górnego w vblank a potem przechodzisz do ekranu gry zaraz po tym przerwaniu, powinno pomóc
      poprawka: 1.ustawiasz pozycje gracza w vblank ,2. włączasz duchy na ekranie, 3. jednorazowo przechodzisz na ekran gry, 4. wychodzisz z vblank.
      • 3:
         
        CommentAuthorlarek
      • CommentTime14 May 2011 16:05
       
      Już. Trochę musiałem pozmieniać w procedurze wyświetlania pierwszego obiektu i wygląda, że już jest ok.

      Dzięki Gorgh za zainteresowanie tematem. Nie próbowałem Twojego sposobu. Być może też byłby skuteczny.

      Zastanawia, że nie jest to tak proste, jak w przypadku kolorów... trudno. Ważne, że działa :)
      • 4:
         
        CommentAuthorjhusak
      • CommentTime14 May 2011 22:05 zmieniony
       
      Są rejestry i rejestry-cienie.
      Rejestry-cienie są przepisywane do rejestrów podczas vblank.

      HPOSP* i HPOSM* nie mają rejestrów cieni.
      Kolory mają.
      A pomyśl, co by się działo z dźwiękiem, gdyby rejestry dźwięku miały cienie :)

      Wyłącz vblank i będziesz miał ten sam efekt dla kolorów :)
      • 5:
         
        CommentAuthorlarek
      • CommentTime14 May 2011 23:05
       

      jhusak:

      HPOSP* i HPOSM* nie mają rejestrów cieni
      I wielka szkoda, że nie mają.
      • 6: CommentAuthorBluki
      • CommentTime15 May 2011 00:05
       
      Sprzętowych cieni nie ma, ale można zrobić programowe. Taką możliwość "rozmnożenia" w pionie obiektów PMG daje np. Advan BASIC.
      • 7:
         
        CommentAuthorjhusak
      • CommentTime15 May 2011 01:05 zmieniony
       

      larek:

      I wielka szkoda, że nie mają.


      A dlaczego? piszesz kilkanaście rozkazów i podłączasz się pod przerwanie vblk (np timera1) i masz rejestry cienie.

      Co do obsługi pmg w systemie operacyjnym to nie ma nawet śladu, więc dlaczego miałyby być cienie pozycji?


      Cienie nie tylko służą do update hardwarowych rejestrów, ale także jako kopia do odczytu, gdy odczyt rejestru hardware nie jest możliwy (np. nie odczytasz koloru z rejestru hardwarowego koloru)
      • 8:
         
        CommentAuthorlarek
      • CommentTime15 May 2011 08:05 zmieniony
       

      jhusak:

      A dlaczego?

      A np. dlatego:

      jhusak:

      Cienie nie tylko służą do update hardwarowych rejestrów, ale także jako kopia do odczytu(...)




      jhusak:

      piszesz kilkanaście rozkazów i podłączasz się pod przerwanie vblk

      Bluki:

      (...)ale można zrobić programowe.

      I tu jest sedno sprawy - trzeba to wszystko robić ręcznie...
      Chciałem w prosty sposób "rozmnożyć" duszka, a okazuje się, że to wymaga rozbudowy kodu. Nieznacznej, ale jednak :)
      • 9:
         
        CommentAuthorjhusak
      • CommentTime15 May 2011 10:05
       
      Eee, tam , larek, przecież to jest 5 minut roboty. Robisz raz, masz biblioteczkę, później tylko dołączasz :)

      Tutaj chodzi o to, że:
      - rozwiązanie, które stosujesz jest stosowane może w 5% grach na sprajtach
      - vblk jest maksymalnie krótki i jest w nim tylko to, co się tam znalazło w wyniku kompromisu.
      - system nie używa pmg do niczego
      - w standardowych zastosowaniach tak jak jest, wystarcza.
      - kod systemu został upakowany w 14 kilo, włączając 2 generatory znaków. Naprawdę nie ma tam niepotrzebnych rzeczy. Gdyby była obsługa pmg (tak jak np. tryby graficzne i opreracje na nich), kod by się powiększył o ok. 1 kb, a i tak nikt by z tego nie korzystał. Strata czasu miejsca i pieniędzy.

      Oczywiście fajnie byłoby mieć SO wypasiony, ale to nie do tego służy. Powinna być jakaś biblioteka do obsługi pmg, która by Cię usatysfakcjonowała, a nie zajmowała miejsca wtedy, gdy jest całkowicie niepotrzebna.
      • 10: CommentAuthornosty
      • CommentTime15 May 2011 13:05 zmieniony
       
      Larek, ja sie tego nauczylem calkiem niedawno ale sprobuje sie podzielic.
      Musisz sobie po prostu stworzyc wlasne programowe "rejestry cienie" dla duszkow (pozycje i kolory) dla kazdej strefy poziomej w ktorej chcesz je multiplikowac i zakodowac w przerwaniach ich obsluge.
      Nizej masz gotowy "silnik" ;) dla obslugi graczy P2 i P3 w 2 poziomych strefach, ktorego ja z powodzeniem uzywam.

      Wazne uwagi:
      1. Jesli bedziesz w DLI ustawial kolory i pozycje dla 4 duszkow to nie zmiescisz sie w przerwaniu DLI przed rozpoczeciem kreslenia kolejnej linii. Musisz wiec pamietac o tym zeby duszek ze strefy nizszej (1) nie "dotykal" strefy (0) tylko zeostaw ze dwie linie pixeli jako bezpieczny bufor.
      2. przepisujac swoje rejestry programowe kolorow duchow w DLI zawsze zapisujesz do rejestrow sprzetowych wlasciwych (od $D012), w VBLI do rejestrow sprzetowych cieni (od $02C0)
      3. jesli bedziesz chcial miec wiecej stref to musisz to uwzglednic w procedurze DLI albo zrobic kilka roznych procedur DLI dla kolejnych linii z ktorych kazda bedzie przekierowywala wektor przerwania na kolejną. Ta druga metoda jest szybsza, tak tobi G2F i ja tez taką metodę przyjąłem.
      4. Twoje rejestry programowe (np pozycja_x_p2_0) sa oczywiscie do zapisu i odczytu. Nie musza byc na stronie 0 ale powinny bo to szybsze co dla DLI jest bardzo wazne.

      ;deklaracja rejestrow sprzetowych
      ;pozycje X graczy
      HPOSP2 equ $D002
      HPOSP3 equ $D003
      ;kolory graczy
      COLPM2S equ $02C2 ;cien przepisywany w VBL
      COLPM2 equ $D014
      COLPM3S equ $02C3
      COLPM3 equ $D015

      ;deklaracja rejestrow programowych na stronie 0
      pozycja_x_p2_0 equ $B9 ;pozycja X player 2 w strefie 0
      pozycja_x_p3_0 equ $BA ;pozycja X player 3 w strefie 0
      pozycja_x_p2_1 equ $BB ;pozycja X player 2 w strefie 1
      pozycja_x_p3_1 equ $BC ;pozycja X player 3 w strefie 1
      kolor_p2_0 equ $C1 ;kolor playera 2 w strefie 0
      kolor_p3_0 equ $C2
      kolor_p2_1 equ $C3 ;kolor playera 2 w strefie 1
      kolor_p3_1 equ $C4

      start
      ;ustawienie przerwania DLI
      lda #<dli
      sta VDSLST
      lda #>dli
      sta VDSLST+1
      ;ustawienie przerwania VBLI
      ldy #<vbli
      ldx #>vbli
      lda #$06
      jsr jsetvblv
      lda #128+64 ;wlaczenie DLI + VBL
      sta NMIEN
      ;POCZATEK GLOWNEGO PROGRAMU
      ;jesli gdziekolwiek w programie
      ;chcemy zmienic pozycje lub kolor P2 lub P3
      ;w strefie 0 lub 1 to zamisujemy do rejestrow prgramowych:
      ;np.
      lda #$0 ;czarny
      sta kolor_p2_1
      lda #55
      sta pozycja_x_p2_1
      ;a przepisanie ich do odpowiednich rejestrow sprzetowych
      ;bedzie wykonane na przerwaniach

      ;KONIEC PROGRAMU GLOWNEGO

      ;-----------------------------------------
      ;przerwanie VBLI - synchro pionowej - w czasie gry
      vbli
      php
      pha
      ;ustawiamy pozycje X dla P2 i P3 dla strefy 0
      lda pozycja_x_p2_0
      sta HPOSP2
      lda pozycja_x_p3_0
      sta HPOSP3
      ;ustawiamy kolory P2 i P3 dla strefy 0
      lda kolor_p2_0
      sta COLPM2S ;w vbli trzeba do cienia!
      lda kolor_p3_0
      sta COLPM3S
      pla
      plp
      jmp sysvbv

      dli
      php
      sta dli_1+1 ;zachowanie akumulatora
      ;
      lda pozycja_x_p2_1 ;przed sta WSYNC zeby bylo szybciej
      ;wait__line
      sta WSYNC ;zapis czegokolwiek
      ;ustawiamy pozycje X dla P2 i P3 dla strefy 1 - pod woda
      sta HPOSP2
      lda pozycja_x_p3_1
      sta HPOSP3
      ;ustawiamy kolory P2 i P3 dla strefy 1
      lda kolor_p2_1
      sta COLPM2 ;tu trzeba do sprzetowego!
      lda kolor_p3_1
      sta COLPM3
      ;
      dli_1
      lda #0 ;automodyfikowany!
      plp
      rti
      • 11:
         
        CommentAuthorMaW
      • CommentTime15 May 2011 14:05
       
      Czy tym sposobem da się także obsłużyć graczy z "trzecim kolorem", czy są jakieś przeciwskazania ?
      • 12:
         
        CommentAuthorlarek
      • CommentTime15 May 2011 14:05 zmieniony
       
      Nosty, bardzo dziękuję, ale już w 3 poście pisałem, że z błędem się uporałem :)

      U mnie problem był trochę innej natury. Z rozdwojeniem jednego playera poradziłem sobie szybko. Trochę nagimnastykowałem się z tym, żeby mi duszek nie pojawiał się (mrugnął przez ułamek ułamka sekundy) na niechcianej pozycji. Takie mrugnięcie wynikało ze złej konstrukcji procedurki wyświetlającej playera. Złej, bo przy jej tworzeniu nie uwzględniłem od początku, iż DLI+PMG nie działa w ten sam sposób co DLI+kolor, a jakoś mi się tak wydawało, że powinno :)
      • 13: CommentAuthorxxl
      • CommentTime15 May 2011 17:05
       
      @Nosty: PHP i PLP sa niepotrzebne w Twoich prockach przerwania.

      > albo zrobic kilka roznych procedur DLI dla kolejnych linii z ktorych kazda bedzie przekierowywala wektor przerwania na kolejną.

      albo wlasna procedura obslugi przerwan NMI bedzie obslugiwala tyle ile trzeba wektorow przerwan
      • 14:
         
        CommentAuthorlarek
      • CommentTime15 May 2011 17:05
       

      xxl:

      @Nosty: PHP i PLP sa niepotrzebne w Twoich prockach przerwania.
      PHA/PLA w VBLI też.
      • 15: CommentAuthornosty
      • CommentTime15 May 2011 18:05
       
      @MaW - ja nie znam takich przeciwwskazan

      @XXL - dzieki za pomysl, nie pomyslalem o tym

      @XXL, larek - mozecie rozwinac temat PHP, PHA?
      Przeciez chocby dowlna instrukcja LDA w przerwaniu zmienia zarowno akumulator jak i statusy w rejestrze procesora.
      Czy te dwa stany sa automatycznie zachowywane/odtwarzane przez system w momencie wywolania/powrotu z przerwania?
      • 16: CommentAuthorxxl
      • CommentTime15 May 2011 18:05 zmieniony
       
      nosty, systemowa procedura przerwania vbi juz zachowuje rejestry na stosie a systemowa procedura wyjscia z przerwania zdejmuje te wartosci (mowimy o vbl, bo w przypadku dli zawsze muszisz zachowac rejestr ktory uzyjesz). wiec w Twoim przypadku nie musisz dodatkowo zachowywac akumulatora. jesli natomiast wylaczysz os i zastosujesz wlasna procke rozpoznawania ktora w krotkiej wersji wyglada tak:
      NMI
      bit $d40f ; VBI? DLI?
      bpl _vbi
      _dli ;procka obslugi przerwan dli
      ...
      _vbi ;procka obslugi przerwan vbi
      sta $d40f
      ...

      to musisz ten rejestr ktory uzyjesz wczesniej zachowac.

      wyjsciem z tej procki zawsze jest RTI

      rti zdejmuje ze stosu rejestr znacznikow procesora ktory wczesniej jest tam wrzucany (jak nastapi przerwanie).