OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 28.03.2024, 11:23

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 15 ] 
Autor Zpráva
PříspěvekNapsal: 03.06.2017, 22:36 
Offline
Radil

Registrován: 21.10.2013, 09:25
Příspěvky: 286
Has thanked: 161 times
Been thanked: 116 times
Rozhodl jsem se po čase pokračovat v započatém, viz toto vlákno http://oldcomp.cz/viewtopic.php?f=50&t=2179&start=15#p23662
Kde byly nejaké základy MicroChess :) kterým chci dát lepší kabát.

Tak jsem si nakreslil šachovnici a animaci selekce políčka (tři frame) pro výběr dané figurky.

Problém jedna: samotná animace selekce je příliš rychlá a nevím jak ji zpomalit?
Problém dvě: jak správně vykreslovat nebo připravit data aby to neblikalo?

Zatím to řeším tak, že vezmu pozadí a xoruji ho s framem selekce, pak zopakuji tím vymazu puvodní a tak třikrát. Jenže to bliká :(

Tady jsem nahrál ukázku, je to MOV formát. A má to 80MB :(
https://drive.google.com/file/d/0By8kgmnDyuCkVHNSdW5kRzdxYVk/view?usp=sharing


Nahoru
 Profil  
 
PříspěvekNapsal: 04.06.2017, 08:18 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Preco nepokracujes v povodnom vlakne ?

Zakladne PMD85 obecne neposkytuje ziadne prostriedky na synchronizaciu vykreslovania so zobrazovanim, takze v principe sa kolizii s lucom vyhnut nevies. Existuje rozsirenie kde si mozes zapnut prerusenie od videoprocesora (synchronne s V-sync ako na ZX Spektre) ale nie kazde PMD to ma.

Pokial chces vyznacit nejaky kurzor aby uzivatel videl na ktorom policku je, skus napr. animovanu ciarkovanu ciaru okolo policka, nachadzajucu sa 2-3 pixely smerom dovnutra od okraja policka. Po kazdych 40 alebo 60 ms vykreslis ciarku znovu ale pattern ciarky bude posunuty o pixel.

Nejaka vhodna zdrzovacia slucka (ld bc,cislo:loop dec bc:ld a,b: or c: jp nz,loop) pomoze aj pri tvojom sucasnom xorovani celeho policka vyberovym vzorom, ale tam by som uz volil casy vecsie, idealne 8*50 az 16*50 ms. Druhou moznostou je vyuzit casovas 8253 (to ma kazde PMD), nim dokazes presne urcit cas bez ohladu na to kolko toho casu zaberie cela rezia okolo vykreslovania.


Nahoru
 Profil  
 
PříspěvekNapsal: 04.06.2017, 22:22 
Offline
Radil

Registrován: 21.10.2013, 09:25
Příspěvky: 286
Has thanked: 161 times
Been thanked: 116 times
Busy píše:
Preco nepokracujes v povodnom vlakne ?

Protože jsem myslel že by to mohlo být zajímavé i pro ostaní, tak aby to nezapadlo v jiném vlákně.

Busy píše:
Zakladne PMD85 obecne neposkytuje ziadne prostriedky na synchronizaciu vykreslovania so zobrazovanim, takze v principe sa kolizii s lucom vyhnut nevies. Existuje rozsirenie kde si mozes zapnut prerusenie od videoprocesora (synchronne s V-sync ako na ZX Spektre) ale nie kazde PMD to ma.

Pokial chces vyznacit nejaky kurzor aby uzivatel videl na ktorom policku je, skus napr. animovanu ciarkovanu ciaru okolo policka, nachadzajucu sa 2-3 pixely smerom dovnutra od okraja policka.

No něco podobného mám použito, ale točí se tak rychle že to jeden nepozná :)

Busy píše:
Po kazdych 40 alebo 60 ms vykreslis ciarku znovu ale pattern ciarky bude posunuty o pixel.

Nejaka vhodna zdrzovacia slucka (ld bc,cislo:loop dec bc:ld a,b: or c: jp nz,loop) pomoze aj pri tvojom sucasnom xorovani celeho policka vyberovym vzorom, ale tam by som uz volil casy vecsie, idealne 8*50 az 16*50 ms.

Skusím tu spožďovací smyčku

Busy píše:
Druhou moznostou je vyuzit casovas 8253 (to ma kazde PMD), nim dokazes presne urcit cas bez ohladu na to kolko toho casu zaberie cela rezia okolo vykreslovania.

Ano vím, myslím že Libor Lasota to popisoval při nějaké tvorbě na svých původních stránkách. Ale já to zatím bez toho abych viděl ukázku nedám :(


Nahoru
 Profil  
 
PříspěvekNapsal: 05.06.2017, 08:57 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
mmartinka píše:
Busy píše:
Druhou moznostou je vyuzit casovas 8253 (to ma kazde PMD), nim dokazes presne urcit cas bez ohladu na to kolko toho casu zaberie cela rezia okolo vykreslovania.
Ano vím, myslím že Libor Lasota to popisoval při nějaké tvorbě na svých původních stránkách. Ale já to zatím bez toho abych viděl ukázku nedám :(
To je velmi jednoduche. Tento sposob ja pouzivam pri simulacii 50 Hz prerusenia v porte ZX romky na PMD.
Inicializacna rutinka, volana raz na zaciatku:
Kód:
     ld   a,#64    ;; 8253 casovac 1 mode 2
     out  (#5F),a
     ld   a,#A0    ;; Konstanta pre 20ms cas
     out  (#5D),a
A v programe potom staci volat tento test:
Kód:
     in   a,(#5D)   ;; Precitame hodnotu casovaca 1 z 8253
old: cp   #55       ;; Ak je ina ako minule znamena to ze uplynulo 20ms
     ret  z
     inc  a         ;; Hodnotu citaca inkrementneme kvoli spravnemu vyhodnoteniu
     ld   (old+1),a ;; a ulozime si ju pre buduce porovnanie.
     ret
Vystup z rutinky je:
NZ=uz uplynulo dalsich 20ms
Z=este neuplynulo.

Samozrejme na blikanie kurzorom na sachovnici je cas 20ms malo, je preto vhodne si spravit slucku ktora pocka (napr.) osemkrat 20ms a az potom zmeni stav policka.


Nahoru
 Profil  
 
PříspěvekNapsal: 05.06.2017, 23:54 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 168
Has thanked: 25 times
Been thanked: 225 times
Busy píše:
A v programe potom staci volat tento test:
Kód:
     in   a,(#5D)   ;; Precitame hodnotu casovaca 1 z 8253
old: cp   #55       ;; Ak je ina ako minule znamena to ze uplynulo 20ms
     ret  z
     inc  a         ;; Hodnotu citaca inkrementneme kvoli spravnemu vyhodnoteniu
     ld   (old+1),a ;; a ulozime si ju pre buduce porovnanie.
     ret
Vystup z rutinky je:
NZ=uz uplynulo dalsich 20ms
Z=este neuplynulo.

znamena to ze citac nemoze nikdy nadobudnut hodnotu 0 ?
totiz v pripade zeby citac po hodnote 255 nadobudol hodnotu 0, by tato rutinka preskocila cely jeden 20ms krok (z pohladu vysledneho Z/NZ).
v pripade, ze po 255 nasleduje hodnota 1 sa rutinka len oneskori o jeden prechod, co nie je zas az tak velka nepresnost (samozrejme zalezi ako casto sa ta rutinka vola).


Nahoru
 Profil  
 
PříspěvekNapsal: 06.06.2017, 07:02 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
ub880d píše:
znamena to ze citac nemoze nikdy nadobudnut hodnotu 0 ?
totiz v pripade zeby citac po hodnote 255 nadobudol hodnotu 0, by tato rutinka preskocila cely jeden 20ms krok (z pohladu vysledneho Z/NZ).
v pripade, ze po 255 nasleduje hodnota 1 sa rutinka len oneskori o jeden prechod, co nie je zas az tak velka nepresnost (samozrejme zalezi ako casto sa ta rutinka vola).
Nulu dosiahnut moze, ale nikdy nebude mat hodnotu 255, lebo cita len do #A0.

Ale aj keby sa nejaky 20ms interval sem-tam omylom pridal ci ubral, tak na vyslednom blikani riadenom casom 8x 20ms si to aj tak (temer) nikto nevsimne :)


Nahoru
 Profil  
 
PříspěvekNapsal: 06.06.2017, 07:59 
Offline
Radil
Uživatelský avatar

Registrován: 13.05.2013, 17:48
Příspěvky: 529
Bydliště: Košice
Has thanked: 423 times
Been thanked: 265 times
Len pre úplnosť, i keď to zrejme nemá vplyv na funkčnosť, čítače 8253 svoju hodnotu dekrementujú.

_________________
https://pmd85.borik.net - PMD 85 Emulátor, PMD 85, PMD 32-SD
https://pp01.borik.net - PP 01 Emulátor, PP 01, SD-ROM Modul


Nahoru
 Profil  
 
PříspěvekNapsal: 06.06.2017, 08:59 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Pre istotu som sa pozrel ako presne to v porte zx romky vlastne robim a toto je ten (spravny) sposob:
Kód:
rutint in   a,(#5D)      ;; Precitame hodnotu casovaca 1 z 8253
countx cp   #55          ;; Ak je vecsia ako odpametana, znamena to ze
       call nc,#0038     ;; uplynulo 20ms a poctivo rucne zavolame interrupt rutinku
       inc  a            ;; Hodnotu citaca inkrementneme kvoli spravnemu vyhodnoteniu
       ld   (countx+1),a ;; a ulozime si ju pre buduce porovnanie.
       ret
Inicializacia 8253 je ta ista.

V tomto rezime 8253 cita citac (ako pise rombor) smerom dole, od predvolby az do nuly. Jedna cela perioda od predvolby az po nulu pre predvolbu #A0 trva prave tych 20ms. Princip rutinky je taky, ze ak sa v citaci objavi hodnota vecsia ako sme nacitali v predchadzajucom zavolani, vieme ze citac zase "pretiekol" a tym padom od minuleho "pretecenia" uz uplynulo 20ms a mozeme vykonat potrebne cinnosti (v tomto pripade volanie call #38).

Predpoklada to ale ze rutinka bude vzdy volana minimalne raz za 20ms. Lebo ked nie, jej detekcia ci uz uplynulo 20ms zavisi viacmenej od nahody (ci zrovna bude mat citac vecsiu alebo mensiu hodnotu nez naposledny nacitanu). V pripade ze potrebujeme odmerat vecsi interval a pocitame N-krat 20ms, zavolanie rutinky po viac ako 20ms na zaciatku pocitania intervalu moze sposobit chybu ze namieto N namieriame N-1 krat 20 ms. Co v pripade blikania zvoleneho policka sachovnice az tak vadit nebude.

Pokial chceme mat formu rutinky ktora nevola podprogram ale vrati priznak ci uz uplynulo 20ms alebo nie, staci vynechat ten call:
Kód:
rutint in   a,(#5D)      ;; Precitame hodnotu casovaca 1 z 8253
countx cp   #55          ;; Ak je vecsia ako odpametana, znamena to ze uplynulo 20 ms
       inc  a            ;; Hodnotu citaca inkrementneme kvoli spravnemu vyhodnoteniu
       ld   (countx+1),a ;; a ulozime si ju pre buduce porovnanie.
       ret
Vystup: NC=uz uplynulo 20ms, C=este neuplynulo.


Nahoru
 Profil  
 
PříspěvekNapsal: 06.06.2017, 20:44 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 168
Has thanked: 25 times
Been thanked: 225 times
Busy píše:
Kód:
rutint in   a,(#5D)      ;; Precitame hodnotu casovaca 1 z 8253
countx cp   #55          ;; Ak je vecsia ako odpametana, znamena to ze uplynulo 20 ms
       inc  a            ;; Hodnotu citaca inkrementneme kvoli spravnemu vyhodnoteniu
       ld   (countx+1),a ;; a ulozime si ju pre buduce porovnanie.
       ret
Vystup: NC=uz uplynulo 20ms, C=este neuplynulo.


busy, ja len dufam, ze ti je jasne ze tato rutinka (oproti tej povodnej, ku ktorej som sa pytal otazku) funguje uplne odlisne. [hint]povodna rutinka menila "rutinkovy" citac len raz za ~160 zmien citaca 8253ky a tato ho meni vzdy ked sa zmeni hodnota citaca 8253[/hint]

a tiez ze v povodnej rutine mas komentar, ktory si neskor sam vyvratil ;] ("Precitame hodnotu casovaca; Ak je ina ako minule znamena to ze uplynulo 20ms" vs. "Jedna cela perioda od predvolby az po nulu pre predvolbu #A0 trva prave tych 20ms.")


Nahoru
 Profil  
 
PříspěvekNapsal: 06.06.2017, 22:01 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Ano, preto som napisal ze spravna je az ta druha rutinka. Ta prva je urcena pre situaciu ked kazda zmena pocitadla casovaca znamena uplynutie stanoveneho casu (pouzivam to pre simulaciu haltu ale s tym ze pocitadlo sa neberie z 8253 ale najnizsi bajt systemovej premennej FRAMES). A to "inc a" sa tam dostalo omylom.


Nahoru
 Profil  
 
PříspěvekNapsal: 07.06.2017, 21:00 
Offline
Radil
Uživatelský avatar

Registrován: 13.05.2013, 17:48
Příspěvky: 529
Bydliště: Košice
Has thanked: 423 times
Been thanked: 265 times
Inou alternatívou na "presné" časovanie, je využitie vysielača sériovej linky. Tento spôsob bol použitý v hre Hlípa a ja som ho potom použil v hre Plotting (i keď tam som si zvolil časovanie inak a nie celkom vhodne).

Opäť je tu nutné použitie časovača CT1 (resp. CT0 viz ďalej), takže sa môže zdať, že je to zbytočne "naokolo", ale je to napriek tomu jednoduché a funkčné riešenie.

Presné časovanie je teda realizované pomocou USARTu tak, že sa odošle byte do USARTu, vykonajú sa potrebné rutiny a následne sa čaká na vyprázdnenie vysielacieho buffra USARTu.
USART je nastavený na 1 štart bit, 8 dátových bitov a 2 stop bity. To je celkom 11 bitov. Pri časovacej konštante 1707 trvá vyslanie 1 bitu: 1 / 2.048 MHz * 1707 = 833,4961 µs, celý byte teda 9,1684 ms.
Možno sa pýtate, prečo nie je časovacia konštanta rovno zvolená tak, aby to bolo, povedzme, 20 ms, čo je pekná okrúhla hodnota. Dôvodom je kompatibilita s PMD 85-1, kde časovač CT1 nie je štandardne pripojený na USART, ale hodiny do USARTu sú pevne dané na 1200 Hz = 1 / 833,4961 µs.

A aby to nebolo také priamočiare ;), tak na C2717 sú hodiny pre USART, na rozdiel od PMD 85, privedené z CT0. Takže úvodná inicializácia bude vyzerať takto:
Kód:
Init:
        ; najprv inicializácia USARTu
        xra  a
        out  1Fh        ; nutné pre spoľahlivý prechod
        out  1Fh        ; do povelového režimu USARTu
        out  1Fh
        mvi  a,50h      ; reset USART 8251
        out  1Fh
        mvi  a,0EDh     ; async, 8N2, k=1
        out  1Fh
        mvi  a,23h      ; RX=OFF, TX=ON, /RTS=0, /DTR=0
        out  1Fh
        ; hodiny pre USART 8251
        ; pre PMD 85
        mvi  a,76h      ; PIT 8253 CT1, mód 3, WORD, BIN
        out  5Fh
        mvi  a,0ABh     ; deliaca konštanta 06ABh = 1707
        out  5Dh
        mvi  a,06h
        out  5Dh
        ; pre C2717
        mvi  a,36h      ; PIT 8253 CT0, mód 3, WORD, BIN
        out  5Fh
        mvi  a,0ABh     ; deliaca konštanta 06ABh = 1707
        out  5Ch
        mvi  a,06h
        out  5Ch
        ; odošli byte = spusti "odpočítanie" prvého "frejmu"
        out  1Eh
        ret
Pre samotné "presné časovanie" je potom potrebná rutina, ktorá si počká na začiatok ďalšieho frejmu.
Kód:
Wait:   in   1Fh        ; prečítaj stav USARTu
        rrc             ; bol už odoslaný celý byte?
        jnc  Wait       ; ak nie, čakaj ďalej
        out  1Eh        ; inak spusti "odpočítanie" ďalšieho frejmu
        ret
A samotné použitie môže byť napr. takéto:
Kód:
MainLoop:
        call Wait       ; počkaj si na ďalší frejm
        ; nasledujúci kód by nemal trvať dlhšie ako ~9 ms
        call TestKey    ; otestuj klávesnicu
        call MoveSpr    ; posuň sprajty
        ... ďalší kód, ktorý sa má vykonať v jednom frejme ...
        jmp  MainLoop

Malou nevýhodou je, že na jeden frejm pripadá iba 9 ms, ale za 9 ms sa dá stihnúť pomerne mnoho a kód sa dá rozvrhnúť tak, že sa v jednotlivých frejmoch budú vykresľovať a vykonávať rôzne veci. Teda napr. prekreslenie sprajtov bude ob-niekoľko frejmov, čo ale vizuálne nevadí.

Samozrejme, toto bol len príklad použitia, ale princíp je vždy rovnaký, či už sa jedná o toto, alebo Busyho riešenie - vhodne načasovať vykresľovanie a vyhodnocovanie "udalostí", aby bol pohyb všetkého na obrazovke plynulý a ideálne neblikavý.

_________________
https://pmd85.borik.net - PMD 85 Emulátor, PMD 85, PMD 32-SD
https://pp01.borik.net - PP 01 Emulátor, PP 01, SD-ROM Modul


Nahoru
 Profil  
 
PříspěvekNapsal: 08.06.2017, 21:23 
Offline
Radil

Registrován: 21.10.2013, 09:25
Příspěvky: 286
Has thanked: 161 times
Been thanked: 116 times
Díky za rady, myslím že je to tady pěkně polopaticky vysvětlené.

Tady je ukázka a myslím že jsem dosáhl optimalního.
Opět mov formát a cca 70MB
https://drive.google.com/file/d/0By8kgmnDyuCkcTkwYkVPVnVvZEk/view?usp=sharing


Nahoru
 Profil  
 
PříspěvekNapsal: 08.06.2017, 21:41 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Vyzera to dobre :)

Skus ciaru animovat nie na uplnom okraji policka, ale o jeden pixel smerom dovnutra.
Aby okolo ciary este zostal este jeden pixel plochy policka.


Nahoru
 Profil  
 
PříspěvekNapsal: 08.06.2017, 21:54 
Offline
Radil

Registrován: 21.10.2013, 09:25
Příspěvky: 286
Has thanked: 161 times
Been thanked: 116 times
To bych mohl, ale nechci aby mi selekce zasahovala do figurek, jenže ty už mám nakreslené a tak bych je musel vše překreslit :(. No uvidím předělat se to dá i dodatečně ;)


Nahoru
 Profil  
 
PříspěvekNapsal: 08.06.2017, 21:55 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3642
Bydliště: Bratislava
Has thanked: 371 times
Been thanked: 788 times
Tak potom mam dalsi tip - sprav tu animovanu ciaru hrubu 2 az 3 pixely a potom zasahovanie do figurok nebude az tak rusive :)


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 15 ] 

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 4 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz