7.2. Ako tvoriť hry

                                                    ... pre počítač Ondra

Tip 1. Ak písať hry, tak pre rozlíšenie s čo najmenším počtom riadkov!

Ako sa dá dočítať v sekcii Grafika, počet riadkov ovplyvňuje výslednú rýchlosť (za predpokladu správneho nastavenia čítačov). A v hrách, ale aj v iných porgramoch, sa každý výkon navyše bude hodiť.

Pre porovnanie, ZX Spectrum má 192 TV liniek, 3,5MHz takt procesora, čiže 3 500 000 T/s (strojových cyklov za sekundu). Oproti tomu má Ondra takt procesora 2MHz, a pri plnom zobrazení zostáva len 365 000T/s, čo je približne desatina výkonu. Ak je teda z akéhokoľvek dôvodu potrebné plné rozlíšenie na výšku, treba písať procedúry nenáročné na počet strojových cyklov, ktoré sú veľmi rýchle a kompenzujú tak slabý výkon počítača. Ak je to možné, a neohrozí to vizuál hry, je možné na čas zastaviť zobrazovanie a náročné úlohy vykonať bez obrazu.

Tip 2. Zobrazenie postáv musí byť optimalizované v čo najväčšej možnej miere!

Čím viac je v hre pohybujúcich sa postáv a čím sú väčšie, tým komplikovanejšie je ich zobrazenie v reálnom čase tak, aby nedochádzalo k výslednému blikaniu. Pri zobrazovaní pohybujúcich sa postáv (angl. sprites) je potrebné vykonať tri kroky:

- vymazať postavu v predošlej polohe

- uložiť podklad, kde bude umiestnená postava (bude slúžiť na vymazanie v nasledujúcom cykle)

- vykresliť postavu

Každý z týchto krokov je časovo náročný. Aby sa zabránilo efektu blikania, musia všetky tri kroky prebehnúť v čase, kedy neprebieha zobrazovanie dotknutej časti obrazu. To je hlavne v čase zobrazenia okrajovej časti (border), v čase zatemnenia, príp. v čase, ktorý predchádza alebo nasleduje vykresleniu postavy. Keďže Ondra počas vykresľovania obrazu má odstavený procesor, posledne spomenutý čas nie je možné využiť na generovanie postáv vo VideoRAM, ale ani na samotnú prípravu tohto procesu. Na všetky činnosti teda zostáva čas cca 3,65ms na každý polsnímok (20ms). Za tento krátky čas musí dojsť k zmazaniu aj vykresleniu postavy, aby nedošlo k efektu blikania. Akonáhle medzi vymazaním a vykreslením dôjde k zobrazeniu čo i jedinej polsnímky, je efekt blikania videteľný! Jediný spôsob, ako správne načasovať činnosti mazania a zobrazenia do vymedzeného času, je synchronizácia cez prerušenie, ktoré generuje VSYNC. Po prerušení je k dispozícii 4962T do času, kým prácu procesora preruší požiadavka na DMA a začne zobrazovanie. To je príliš málo času na veľa činností, preto sa používa nieľko trikov, ako v tomto krátkom čase vykonať čo najviac. Vždy sa jedná o prípravu dát na zobrazenie (teda časovo náročných výpočtových operácii) a následné rýchle zobrazenie (teda rýchly zápis pripravených dát do VideoRAM). Kým na ZX Spectre môže príprava dát prebiehať počas zobrazovania, Ondra tento benefit nemá a všetky operácie musia byť vykonané mimo času zobrazovania. Veľký problém nastáva, ak sa postavy majú prekrývať, t. j. obraz sa skladá z viacerých navzájom čiastočne prekrytých postáv prípadne aj pozadia. Vtedy je bezpodmienečne nutné poskladať obraz v inej časti pamäte (buffer, shadow Video RAM), a následne až potom vytvoriť dáta pre rýchle zobrazenie.

Prekrývajúce sa obrazce boli

zložené v tieňovej VideoRAM.

Všetkých päť a bez blikania.

Aby to celé bolo ešte komplikovanejšie, adresovanie VideoRAM na počítači Ondra je doslova šialené. Kým adresovanie stĺpcov vyšším bajtom adresy nespôsobí až také problémy (len málokedy možno použiť inštrukciu LDIR), adresovanie riadkov pri zamenených bitoch zbernice (čo je obrovská a zbytočná chyba návrhu počítača Ondra) znemožňuje dosiahnuť primeranú rýchlosť počas vykresľovania a obmedzuje vyýber algoritmov pre túto činnosť.

Ukážka niekoľkých spôsobov rýchleho vykreslenia s rozdielnou elimináciou adresovania riadkov:

a) vyberanie dát zo zásobníka a ukladanie do Video RAM

                

         LD    SP, nnnnn

        LD    HL, VideoRAM

        LD    B, 16

CYC:    POP    DE       ; 10T

        LD    (HL), E   ;  7T

        DEC    H        ;  4T

        LD    (HL), D   ;  7T

        INC    H        ;  4T

        RLC    L        ;  8T

        DEC    L        ;  4T

        RRC    L        ;  8T

        DJNZ   CYC      ; 13T

    Spolu 52T

        LD    SP, nnnnn

        LD    HL, VideoRAM

        LD    A, L

        LD    B, 16

CYC:    POP    DE       ; 10T

        LD    (HL), E   ;  7T

        DEC    H        ;  4T

        LD    (HL), D   ;  7T

        INC    H        ;  4T

        RLCA            ;  4T

        DEC    A        ;  4T

        RRCA            ;  4T

        LD     L, A     ;  4T  

        DJNZ   CYC      ; 13T

    Spolu 48T

b) vyberanie dát zo zásobníka vrátane adresy riadku a ukladanie do Video RAM

        LD    SP, nnnnn

        LD    B, 16

CYC:    POP    DE       ; 10T

        POP    HL       ; 10T

        LD    (HL), E   ;  7T

        INC    H        ;  4T

        LD    (HL), D   ;  7T

        DJNZ   CYC      ; 13T

    Spolu 38T

c) priame ukladanie kódom (ktorý môže byť modifikovaný počas prípravy)

         LD    B, 16

        LD    HL, VideoRAM

CYC:    LD    (HL), n0  ; 10T

        DEC    H        ;  4T

        LD    (HL), n1  ; 10T

        INC    H        ;  4T

        RLC    L        ;  8T

        DEC    L        ;  4T

        RRC    L        ;  8T

        DJNZ   CYC      ; 13T

    Spolu 48T

Metóda b) sa javí ako najrýchlejšia na vykreslenie, je však náročnejšia na prípravu dát, lebo pre každý riadok treba vypočítať a uložiť hodnotu adresy Video RAM. Pokiaľ ide naozaj o čas, nemusí sa využiť cyklus, ale kód sa naklonuje za sebou 16-krát. Teda pre postavu 16x16 bitov (32 bajtov) je čas spracovania 608T. Pri už spomínaných 4962T, sa jedná o vykreslenie 8 takýchto postáv, ale keďže ich treba aj mazať, prakticky je teda možné vykesliť počas jedného polsnímku 4 postavy. Ak by bol na vykreslenie využitý celkový čas práce procesora, dostali by sme sa až k 11 postavám, s mazaním teda iba 5. V takom prípade by sa vykreslovanie muselo už synchronizovať s prerušením z predchádzajúceho polsnímku, za ktorým by musel nasledovať program s fixnou dĺžkou 4962T. Pozor, pri mnohých hrách je síce používaný základný vzor s rozlíšením 16x16 bitov, ale vzhľadom na ilúziu pohybu sú jeho jednotlivé fázy rozkreslené v matrici 24x16, čo značne zťažuje vykreslovanie.

Vykresľovanie je možné urýchliť tým, že sa najskôr vykreslia párne a potom nepárne mikroriadky, čím sa eliminujú operácie RLC, RRC (zredukujú sa na jednu sadu).

Časovanie zobrazenia: 1- ukončenie príprav dát a začiatok čakania na VSYNC (procesor stojí na inštrukcii HALT),

2 - VSYNC a čakanie na DMA v pevne načasovanej slučke, 3 - DMA - Ondra zobrazuje video, procesor stojí,

4 - začiatok vykreslovania z fronty, 5 - koniec vykreslovania ešte pred ďalším DMA, teda všetko sa stihlo načas

pred ďalším zobrazeným polsnímkom, k blikaniu teda nemôže dôjsť.

Správne načasovanie, hneď po skončení DMA sa začína vykresľovanie z fronty.

Maximálny počet pohybujúcich sa objektov

veľkosti 16x16px je päť počas jedného polsnímku,

ďalšie objekty sa môžu dokresliť v nasledujúcom cykle.

Tip 3. Jemný (bitový) pohyb postáv nech zostane len snom

Pokiaľ programátor koketuje s bitovým pohybom postáv, pokúša sa o nemožné. I keby boli všetky šablóny postáv vytvorené s bitovým posunom (pre-shifted), ak sa majú postavy pohybovať dostatočne rýchlo naprieč obrazovkou, nezostáva dosť výpočtového výkonu na všetky potrebné operácie. Netreba preto uvažovať o jemnejšom pohybe ako posun o štyri bity.

Tip 4. Podklad nech radšej zostane prázdny

Ak treba pri vykresľovaní postáv zohľadniť aj podklad, jedná sa o operáciu OR alebo XOR medzi jednotlivými prekrývajúcimi sa bajtami, ktoré spolu s operáciami výberu a zápisu meneného bajtu zaberajú drahocenný čas. Čisté pozadie je teda správna voľba.

Aký je rozdiel pri synchronizovanom vykresľovaní oproti bežnému vykresľovaniu možno vidieť na príklade ku knižnici SPRITES, ktorá zobrazuje oba spôsoby.