PicoVGA - displej VGA/TV na Raspberry Pico

PicoVGA - displej VGA/TV na Raspberry Pico
Miroslav Němeček Pridal  Miroslav Němeček
  852 zobrazení
3
 0
Arduino a príbuzné platformy

Knihovna PicoVGA umožňuje výstup z Raspberry Pico na VGA monitor nebo na PAL/NTSC televizor, se zaměřením na snadné použití v technické a herní praxi. Poskytuje 4 grafické překryvné vrstvy s průhledností, téměř 30 formátů frame bufferů, které lze spolu libovolně kombinovat, a díky tomu si vystačí s omezenou velikostí RAM paměti. K úspoře RAM paměti přispívá i omezení výstupu na 8 bitů.

Procesor RP2040 obsahuje 264 KB paměti RAM. Pro výstup obrazu ve vyšším rozlišení to není mnoho, a proto je potřeba pamětí RAM velmi šetřit. V technické praxi a pro retro hry (pro dokonalejší hry procesor nemá výkon) plně postačí 8-bitový grafický výstup ve formátu R3G3B2 (tedy červená 3 bity, zelená 3 bity a modrá 2 bity). Výstup v 16 nebo 24 bitech v běžné praxi není smysluplný, protože Raspberry Pico nemá dostatek paměti ani výkonu k poskytnutí tak velkého objemu dat v jiných oblastech než krátká dema. S využitím techniky ditheringu lze i při 8-bitovém výstupu dosáhnout zajímavé výsledky zobrazení.

Chcete-li si knihovnu vyzkoušet, stačí v nejjednodušším případě vzít 8 rezistorů, propojit jimi výstupy GP0 až GP7 s RGB konektorem VGA nebo SCART TV, HSync (CSync) připojit na GP8, sluchátka na GP19 a nahrát demo program přes USB (programy jsou v balíku knihovny připravné již přeložené). Je-li potřeba ovládání z klávesnice, spustit konzolový program např. begPutty, ale většina programů funguje i bez klávesnice.

Základní schema zapojení.

Licenční podmínky: Zdrojové kódy knihovny PicoVGA a zdrojové kódy ukázkových programů knihovny PicoVGA jsou k dispozici volně k dalšímu použití a modifikacím. To se nevztahuje na některé grafické a zvukové prvky (jako jsou např. zvuky ve hře Pac-Man) a na definice scén hry Sokoban, neboť se k nim vztahují autorská práva třetích stran a mohou uplatňovat jiné podmínky šíření.

Vlastnosti knihovny PicoVGA

  • 1 základní vrstva a 3 překryvné vrstvy s průhledností, s využitím modulu PIO0
  • 8-bitový výstup ve formátu R3G3B2
  • výstup na VGA monitor v rozlišení 256x192 až 1280x960
  • výstup na televizor v prokládaném módu PAL nebo NTSC v rozlišení až 1024x576 nebo 848x480
  • téměř 30 formátů frame bufferů: grafika 8/4/2/1 bitů, dlaždice, texty, speciální formáty (grafy)
  • barevné palety pro textové režimy a grafické formáty s omezenou bitovou hloubkou
  • frame buffery různých formátů lze v obraze spolu libovolně kombinovat do pásů a segmentů
  • RLE komprese obrazu (vhodné pro kresby)
  • módy průhlednosti s volitelnou klíčovou barvou
  • hardwarové sprajty v překryvných vrstvách
  • výstup vrstev jen do určených výstupních pinů (barevné roviny)
  • automatická konfigurace videomódu podle zadaného rozlišení a časování
  • automatické přetaktování procesoru podle požadovaného rozlišení
  • knihovna používá 2. jádro procesoru, pro hlavní program je vyhrazeno 1. jádro
  • doplňkově PWM zvukový výstup (nemusí být použit)

Zde příklad výstupu na televizor v prokládaném (interlaced) módu, s redukcí z VGA konektoru na SCART TV konektor. Redukce VGA/SCART obsahuje jen jednoduché propojení pinů konektorů, případně ještě 1 rezistor pro blanking signál.

Zásady pro použití knihovny PicoVGA

Generování obrazu na Raspberry Pico je záležitost limitního využití procesoru a je mu nutné podřídit ostatní činnosti procesoru. Při použití PicoVGA knihovny je nutné pamatovat na několik zásad:

Knihovna běží vždy na druhém jádru procesoru a program na prvním jádru. Renderování obrazu je schopné jádro procesoru zcela vytížit a zpravidla je pro další využití nevyužitelné. Oddělení funkcí jader má výhodu i v tom, že jádra se navzájem neovlivňují a není potřeba vzájemné uzamykání. První jádro jednoduše používá zápis do frame bufferů a druhé jádro obsahy frame bufferů zobrazuje, aniž je mezi nimi nutná nějaká komunikace. Tím se celková práce usnadní a urychlí.

Je-li přece jen druhé jádro málo vytížené (např. při zobrazení 8-bitové grafiky, která se jednoduše přenáší pomocí DMA přenosu), lze ho využít též na práci hlavního programu. Je však nutno počítat s některými omezeními - program v druhém jádru by neměl používat přerušení (narušovalo by činnost renderovací funkce), interpolační jednotku by měl používat s opatrností (renderovací funkce její stav neuchová) a nesmí zakázat přerušení.

Důležitou zásadou je, že všechna data, ke kterým má mít PicoVGA knihovna přístup, musí být uložena v paměti RAM. Externí paměť flash je pomalá a nelze použít pro renderovací funkce. Pokud by se např. měl zobrazit obrázek z paměti flash, je nutné ho nejdříve zkopírovat do bufferu v paměti RAM a potom renderovací funkci předat ukazatel na kopii obrázku v RAM. Pokud by se jí předal ukazatel na obrázek ve flash, pomalý přístup k flash by způsoboval výpadky obrazu. Kromě obrázků to platí např. i pro fonty a vzory dlaždic.

Při rozvrhování obrazu je nutné počítat s omezenou rychlostí vykreslování. Některé módy se vykreslí velmi rychle (např. 8-bitová grafika se jen přenáší z frame bufferu pomocí DMA) a některé módy jsou velmi náročné na vykreslování - např. renderování sprajtů v pomalém režimu. Při použití náročného vykreslování se může stát, že některá videolinka se nevyrenderuje dostatečně rychle v potřebném čase a obraz se rozpadne (vypadne synchronizace). V takových případech je nutné použít jiný mód, nebo zmenšit vykreslovanou plochu (doplnit ji jinými módy, rychlejšími - např. po stranách obrazu doplnit ovládací prvky tvořené dlaždicemi), zmenšit rozlišení obrazovky nebo zvýšit rychlost hodin procesoru. Videolinky jsou renderovány samostatně a proto jde vždy jen o obsah na jedné videolince, videolinky se navzájem neovlivňují. Např. rychlost vykreslování sprajtů otestujete tak, že umístíte všechny sprajty vedle sebe horizontálně (nejnáročnější případ) a ověříte, zda nevypadne synchronizace obrazu.

Opatrnosti je třeba dbát i v případě použití DMA přenosu. DMA se používá k přenosu dat do PIO. Přestože se při přenosu využívá FIFO mezipaměť, může znamenat použití jiného DMA kanálu zpoždění renderovacího DMA kanálu a tím i výpadek obrazu. Přetížení DMA může nastat např. při rychlém přenosu většího bloku dat v RAM paměti. Ovšem největším zatížením je DMA přenos dat z flash paměti. V tom případě DMA kanál čeká na načtení dat z flash přes QSPI a blokuje tak renderovací DMA kanál.

Generátoru obrazu je nutné podřídit i frekvenci hodin procesoru. Před inicializací videomódu knihovna vypočítá potřebnou frekvenci systémových hodin tak, aby časování odpovídalo požadavku a aby byla rychlost procesoru dostatečná pro potřebné rozlišení obrazu. Je dobré zpočátku si vypočtenou frekvenci hodin vypsat pro kontrolu na konzole. Je možné knihovně zakázat změnu systémových hodin, nebo jí předepsat jen určitý rozsah, v tom případě mohou být některé módy nedosažitelné (nebo se obraz může rozpadat).

Obrazové buffery musí být zarovnané na 4 bajty (32-bitové slovo procesoru) a obrazové segmenty musí být horizontálně zarovnané na 4 pixely - to se týká horizontální pozice segmentu, jeho šířky, zarovnání (wrapx) a offsetu (offx). Zarovnání se netýká vertikálního směru. Toto omezení je nutné z toho důvodu, že obrazová informace se přenáší do PIO řadiče pomocí 32-bitového DMA přenosu, a ten musí být zarovnaný na 32-bitové slovo. Jedno 32-bitové slovo obsahuje 4 pixely (1 pixel má 8 bitů), proto i horizontální data v obraze musí být zarovnána na 4 pixely. Nelze tedy dělat jemné horizontální skrolování obrazu po 1 pixelu (omezení se netýká vertikálního skrolování), ale pouze po 4 pixelech. Výjimkou jsou pomalé sprajty, které se vykreslují softwarově do videolinky, a mohou se proto posouvat po 1 pixelu. Stejně tak se omezení netýká softwarového vykreslování do framebufferu (např. vykreslení obrázku do videopaměti může proběhnout na jakoukoliv souřadnici).

Instalace

Knihovna PicoVGA je připravena pro zjednodušený překlad ve Windows prostředí, kdy vyžaduje pouze instalaci ARM-GCC překladače. Překlad pro Linux není připraven, tuto oblast přenechávám někomu znalejšímu Linux prostředí. ;-)

K překladu potřebujete ARM-GCC překladač. Ten si můžete stáhnout zde - klikni

V současnosti by se jednalo o verzi gcc-arm-none-eabi-10-2020-q4-major-win32.exe. Doporučuji překladač nainstalovat do složky C:\ARM10 a při instalaci vypnout volbu pro přidání cesty do PATH. Jednotlivé verze překladače nejsou vždy až tak úplně zaměnitelné a je proto praktické mít nainstalováno více verzí (složky C:\ARM9, C:\ARM8 atd.) a cestu do použité verze překladače přidat až uvnitř povelového souboru. Tímto způsobem jsou připravené i překladové soubory v PicoVGA. Budete-li chtít změnit cestu do složky překladače, naleznete ji v překladových souborech _c1.bat a _boot2\c.bat. Nechcete-li používat více verzí překladače, ponechte instalaci do implicitní složky a ponechte zapnutou volbu pro přidání cesty do PATH, překlad bude fungovat správně také.

Knihovnu PicoVGA rozbalte do nějaké složky. Kamkoliv, kde budete chtít pracovat. ... A tím je instalace ukončena. :-)

Další doporučení pro snadné použití RaspberryPicoSDK knihoven ve Windows naleznete v popisu "Snadný překlad Raspberry Pico pod Windows" - klikni

Schéma zapojení

Nepředkládám zde celkové zapojení které jsem použil, protože knihovna vznikla jako součást retro herního počítače s Raspberry Pico a je zatím ve vývoji. Zde je zjednodušené schéma zapojení výstupu na VGA monitor (doplněno o zvukový PWM výstup):

Synchronizační výstup má formát synchronizační směsi CSYNC (composite synchro, HSYNC + VSYNC). Počítačové monitory podporují smíšenou synchronizaci CSYNC. Signál se přivádí na vstup HSYNC (označovaný též jako CSYNC). Na pin VSYNC konektoru VGA je přiveden zvukový výstup, to pro případ výstupu na televizor. VGA monitor má na tomto pinu vstupní impedanci 75 ohmů, díky tomu se audio signál utlumí a VGA monitor ho ignoruje a nepovažuje za vertikální synchronizaci. Po zasunutí audio konektoru se výstup na VGA monitor odpojí a zvukový signál je vyveden ven (např. na audio sluchátka).

Televizor je připojen na VGA výstup přes redukci, která jednoduše propojí piny VGA konektoru s příslušnými piny SCART konektoru. V tomto případě se využije i audio signál přivedený na VGA konektor. Není tak nutné, aby zařízení obsahovalo i speciální konektor pro televizor. Napětí 5V z pinu 9 se využije jako ovládací napětí pro SCART konektor - pin 16 SCART konektoru (Blanking) se připojí přes odpor 100 ohmů a pin 8 (Switch) se připojí přímo.

Není zde zakresleno připojení klávesnice. Všechny ukázkové programy jsou připravené tak, aby bylo možné použít ovládání programu přes konzoli na USB virtuálním portu. Stačí Pico připojit k PC přes USB kabel, kterým probíhá programování, a spustit konzolový program (např. begPutty), který se připojí k virtuálnímu USB COM portu. Bližší popis připojení naleznete v popisu SDK.

Začlenění do projektu

Při začlenění PicoVGA knihovny do projektu je nejjednodušší cestou použít některý již existující ukázkový projekt. Pro maximální jednoduchost jsou do projektů začleněny všechny zdrojové soubory. Překlad sice trvá o něco déle, ale nevyžaduje úpravy výběru a pořadí překládaných souborů, čímž se výsledně práce zjednoduší.

Při začlenění knihovny do již existujícího projektu je potřeba převzít složku _picovga, která obsahuje zdrojové soubory knihovny PicoVGA. V souboru global.h naleznete hlavičkové soubory *.h, které se do projektu začleňují (_picovga/define.h atd.). Přidávané překládané soubory naleznete v souboru Makefile.inc. Jednak skupina souborů v assembleru "ASM picovga" a jednak C zdrojové kódy "C picovga".

Knihovna PicoVGA vyžaduje při překladu soubor vga.pio, přeložený pomocí překladače pioasm.exe do souboru vga.pio.h. V aktuální složce projektu vyhledává soubor include.h, který obsahuje seznam všech hlavičkových souborů, včetně vga.pio.h.

Dále v aktuální složce vyhledává soubor vga_config.h. Ten obsahuje nastavení knihovny PicoVGA, jako např. velikost renderovacích bufferů. Souboru vga_config.h si většinou všímat nemusíte. Musíte do něj zasáhnout obvykle v těchto případech:

  • Když použijete rozlišení displeje větší než 640x480 pixelů. Typicky v konfiguračním souboru bývá nastaveno maximální rozlišení 640x480. Tento údaj je nutné při větším rozlišení upravit, aby si knihovna rezervovala větší buffery pro renderovací funkce.
  • Druhým případem, kdy musíte konfiguraci upravit, je nedostatek paměti RAM. Je zde ještě nějaká rezerva, na které můžete nějakou paměť uspořit. Jednak můžete snížit nastavené rozlišení MAXX, MAXY a MAXLINE až na reálnou hodnotu. Dále můžete snížit počet vrstev LAYERS až na skutečně použitou hodnotu (v rozsahu 1 až 4). A konečně můžete snížit počet segmentů a pruhů na skutečnou hodnotu SEGMAX a STRIPMAX (minimum 1).
  • Třetím případem je použití velkého množství pruhů a segmentů displeje. Běžně jsou zde nastaveny hodnoty 8 pruhů (=horizontální pásy) a 8 segmentů (=vertikální rozdělení každého pásu).

Překlad projektu

Všechny demo příklady v PicoVGA jsou již připravené přeložené (přeložený soubor má vždy jméno program.uf2) - přeloženo pro VGA monitor a USB konzolovou klávesnici. Stačí je jen nahrát do Pico spuštěním e.bat (="Export"). Budete-li chtít v kódu něco měnit, nový překlad zajistíte spuštěním c.bat (="Compile"). Ve FAR jen stiskněte c<Enter>. Vyčištění překladu provedete spuštěním d.bat (="Delete"). Smažou se všechny přechodné soubory a ponechá se jen výsledný přeložený soubor program.uf2.

Během překladu je zajištěno, že při úpravách souborů *.c, *.asm a *.cpp se překládají jen změněné soubory, ne celý projekt. Není tedy nutný kompletní překlad po každé změně kódu. Není zde ovšem zajištěn překlad v závislosti na hlavičkových souborech *.h, na to je potřeba pamatovat. Tedy běžně překládat zrychleně pomocí c.bat a jen po podstatnějších změnách v *.h nebo při podezřelém chování nejdříve vymazat starý překlad pomocí d.bat a provést pak plný překlad.

V základní složce PicoVGA naleznete ještě soubory c_all.bat a d_all.bat - slouží k hromadnému přeložení nebo pročištění překladu všech demo programů.

V souboru Makefile, nacházejícím se u každého projektu, naleznete nastavení projektu. Zpravidla si vystačíte s tím, že budete přidávat další zdrojové soubory *.c k proměnné CSRC a soubory *.cpp k proměnné SRC. Budete-li do projektu přidávat hlavičkové soubory *.h, přidávejte je do souboru src\include.h. Odkaz na include.h uvedete na začátku každého souboru *.c a *.cpp.

Přeložený program můžete do Pico nahrát buď přetažením myší, nebo povelovým souborem e.bat. Pro ten účel je užitečné disk pojmenovat jednotně např. R: (=Raspberry). Přejmenování se provede ve správě počítače - přes Tento počítač / Spravovat. Nebo upravit jméno disku v souboru _e1.bat.

Složky

V PicoVGA naleznete následující složky:

  • _boot2 - Zavaděče 2. stupně.
  • _exe - program elf2uf2 pro export přeloženého programu z formátu elf2 do formátu uf2, a pioasm, překladač programů pro PIO. Programy jsou připraveny pro 64-bitový systém Windows. Pro 32-bitový systém použijte knihovny ze složky 32bit.
  • _picovga - knihovna PicoVGA, spolu s podpůrnými programy
  • _sdk - knihovní soubory SDK. Struktura je zjednodušená oproti originálnímu SDK. Všechny *.c soubory se nacházejí v jedné složce a všechny *.h soubory ve složce include.
  • _tinyusb - knihovna TinyUSB pro obsluhu USB portu.
  • _tools - utility pro obsluhu překladu z knihovny MinGW, jako je program "make.exe" atd.
  • _www - obsah této www stránky s popisem.

Ostatní složky obsahují demo příklady.

Inicializace videomódu

Videomód lze inicializovat buď zjednodušeně samotnou funkci Video() nebo podrobněji pomocí následujících funkcí.

  • Video(u8 dev, u8 res, u8 form, u8* buf, const void* buf2) ... Zjednodušená inicializace videomódu. Popis funkce a parametrů naleznete ve vga_vmode.h. Tato funkce v sobě zahrnuje následující funkce uvedené zde níže. Podporuje jen 1 segment displeje a má omezený repertoár formátů a rozlišení, ale v některých případech může stačit. Funkci stačí předat jen ukazatel na frame buffer, což je pole u8 o dostatečné velikosti pro obrazová data. Funkce používá implicitní globální struktury knihovny (Cfg, Vmode, Canvas), jinak je možné v programu používat implicitní globální struktury libovolně. Při použití funkce Video nejsou následující inicializační funkce potřebné.
  • multicore_launch_core1(VgaCore) ... První funkce, která by měla být volána v projektu, spustí druhé jádro procesoru s PicoVGA knihovnou.
  • void VgaCfg(const sVgaCfg* cfg, sVmode* vmode) ... Příprava struktury pro nastavení videomódu. Struktura sVgaCfg (popis ve vga_vmode.h) obsahuje požadované vlastnosti videomódu - požadované rozlišení displeje, minimální frekvence procesoru a požadované časování signálu sVideo* (též ve vga_vmode.h), případně ještě požadovaný mód překryvné vrstvy. Můžete nejdříve zavolat funkci VgaCfgDef, která přednastaví strukturu na implicitní parametry - rozlišení 640x480, VGA displej, frekvence procesoru 120 až 270 MHz. Funkce VgaCfg připraví strukturu popisovače sVmode, která se později předá nicializační funkci. V této chvíli ještě k žádným operacím nedochází, pouze se počítá potřebné nastavení. Po výpočtu je možné některé položky struktury sVmode ještě dokorigovat. V knihovně jsou připraveny globální struktury Cfg a Vmode, které lze pro funkci použít. Požadované rozlišení obrazu a časování signálu jsou dvě na sobě nezávislé vlastnosti. U časování jste omezeni jen počtem videolinek obrazu, ale jinak v jejich rámci můžete nastavit jakékoliv rozlišení obrazu. Např. u PAL a NTSC obrazu můžete nastavit VGA rozlišení obrazu. Chcete-li zajistit univerzálnost programu, aby ho bylo možné spouštět jak na VGA monitoru, tak na televizoru, použijte VGA rozlišení 640x480 nebo 320x240 (příp. 512x400 a 256x192, kvůli omezení RAM). Při změně displeje stačí jen zvolit časování VGA/PAL nebo NTSC, pro program se rozlišení nemění.
  • set_sys_clock_pll(Vmode.vco*1000, Vmode.pd1, Vmode.pd2) ... Nastavení systémových hodin. Funkce VgaCfg vypočetla potřebnou frekvenci procesoru, vypočtené hodnoty se předají funkci pro nastavení systémových hodin. Funkci VgaCfg lze zadat požadovaný limit frekvence.
  • ScreenClear(pScreen) ... Vymazání displeje a inicializace struktury displeje. Minimálně tato funkce by měla být volána před inicializací videmódu. Inicializuje strukturu popisovače obsahu displej na kterou ukazuje pScreen (obvykle to je implicitní struktura knihovny Screen) tím že nastaví počet segmentů na 0. Obrazovka bude černá, dokud ji nenaplníme popisovači obsahu (viz níže).
  • VgaInitReq(&Vmode) ... Inicializace videomódu. Funkce předá knihovně ukazatel na popisovač formátu, který vygenerovala funkce VgaCfg. Ve skutečnosti tato funkce inicializaci videomódu neprovede, pouze knihovně v druhém jádru procesoru předá ukazatel a pak čeká na potvrzení ukončení inicializace. Je-li potřeba videomód změnit (týká se to změny časování videosignálu a změny typu překryvných vrstev), je nutné nejdříve zastavit generování obrazu voláním funkce VgaInitReq s parametrem NULL, a teprve až potom zavolat funkci s novým nastavením videomódu.

Volání programu druhého jádra

Není-li druhé jádro příliš vytížené generováním obrazu, lze mu předat požadavek k provedení funkce. Generování obrazu to neovlivní, pouze se může stát, že při velké zátěži generátoru pojede požadovaná funkce pomalu. Funkce nesmí používat přerušení, nesmí zakázat přerušení a může být omezeno použití hardwarového interpolátoru (přerušení displeje jeho stav neuchová).

  • Core1Exec(void (*fnc)()) ... provedení funkce jádrem 1.
  • Bool Core1Busy() ... test, zda je jádro 1 zaneprázdněné prováděním funkce.
  • Core1Wait() ... čekání na ukončení funkce v jádru 1.

Nastavení módu obsahu displeje

Při zobrazení obrazu je pro knihovnu výchozí ukazatel pScreen. Ukazuje na strukturu sScreen, která popisuje obsah displeje. Raspberry Pico má omezenou velikost paměti RAM a nemůže pojmout obraz ve velkém rozlišení. Proto je nutné obraz skládat z menších segmentů tak, aby se minimalizovaly části náročné na paměť.

Poznámka: Následující popisy formátu obrazu se týkají pouze základní obrazové vrstvy 0. Ta jediná může obsahovat segmenty v různém formátu. Překryvné vrstvy 1 až 3 jsou na formátu základní vrstvy nezávislé, sdílejí s ní jen celkovou plochu displeje, ale používají svůj vlastní formát obrazu.

  • ScreenClear(sScreen* s) ... Vynuluje struktury popisovače displeje, čímž provede vymazání displeje. Tuto funkci je vhodné zavolat vždy na začátku vytváření nové definice obsahu obrazovky (inicializace segmentů).
  • sStrip* ScreenAddStrip(sScreen* s, int height) ... Funkce přidá na konec definice obrazovky nový horizontální pruh o zadané výšce počtu videolinek. Maximální počet pruhů je určen konstantou STRIPMAX (implicitně 8) v souboru vga_config.h. Bez přidaných segmentů je pruh prázdný (černý).
  • sSegm* ScreenAddSegm(sStrip* strip, int width) ... Funkce přidá na konec pruhu nový obrazový segment o zadané šířce. Segment bude obsahovat jeden formát obrazu. U naprosté většiny formátů musí být šířka násobkem 4 (násobek 4 pixelů).

Následují funkce pro nastavení konkrétního formátu obrazového segmentu. Definici segmentu sSegm naleznete ve vga_screen.h. Jsou zde i některé parametry, které nejsou funkcemi řízeny: offx určuje horizontální posun obrazu (horizontální skrolování). U naprosté většiny formátů musí být horizontální skrolování v násobcích 4. Parametr offy určuje vertikální skrolování. To lze provádět jemně po linkách. Porametr wrapx určuje zarovnání, po kterém se obsah bufferu opakuje. Je tak možné např. zobrazit obrázek dlaždicově nebo naopak vytvořit virtuální obrazovku větší než displej. Tento parametr musí být opět násobkem 4. Podobně parametr wrapy určuje vertikální opakování obrazu. Parametr dbly zdvojí vertikální linky. To lze použít u obrazu s malým horizontálním rozlišením.

Parametr 'wb' funkcí udává délku linky v bajtech. Parametr 'data' je ukazatel na frame buffer s grafickými daty. Parametr 'font', u funkcí pro text, je ukazatel na font. Font je 1-bitový mono obrázek s 256 znaky na řádek. Každý znak je široký 8 pixelů, délka linky tedy je 2048 pixelů (256 bajtů). Vertikálně může mít font libovolný rozměr - výšku fontu udává parametr 'fontheight'. Seznam fontů, které jsou k dispozici, naleznete ve složce _picovga\font.

  • ScreenSegmColor(sSegm* segm, u32 col1, u32 col2) ... Segment bude vyplněn barvou (GF_COLOR). Parametry col1 a col2 představují barvy 4 pixelů pro sudou a lichou linku. Segment tak může namísto spojité barvy obsahovat barevný rastr. K sloučení barev 4 pixelů lze použít makro MULTICOL.
  • ScreenSegmGrad1(sSegm* segm, const void* data, int wb) ... Segment bude vyplněn barevným gradientem (GF_GRAD1). Gradientem je 1 linka 8-bitových pixelů. Gradientem lze horizontálně posouvat parametrem offx.
  • ScreenSegmGrad2(sSegm* segm, const void* data, int wb) ... Gradient se 2 linkami, sudá a lichá (GF_GRAD2).
  • ScreenSegmGraph8(sSegm* segm, const void* data, int wb) ... 8-bitová grafika 256 barev (GF_GRAPH8). Každý pixel je 1 bajt. Tento mód patří k nejrychlejším, data se z frame bufferu jednoduše posílají do PIO řadiče pomocí DMA přenosu. Ovšem také k nejnáročnějším na paměť. Reálně se do paměti vejde obraz o rozlišení maximálně 512x400 pixelů (EGA videomód).
  • ScreenSegmGraph4(sSegm* segm, const void* data, const void* trans, int wb) ... 4-bitová paletová grafika 16 barev (GF_GRAPH4). V 1 bajtu jsou 2 pixely (první pixel je ve vyšších 4 bitech bajtu). Funkce vyžaduje překladovou tabulku palet, která se vygeneruje následující funkcí:
  • GenPal16Trans(u16* trans, const u8* pal) ... Vygenerování překladové tabulky palet pro funkci ScreenSegmGraph4. Překladová tabulka je 256 položek o rozměru 16 bitů, v paměti tedy zabere 512 bajtů. Tabulka je použita během zobrazení k interním účelům, musí být zarovnána na 4 bajty a musí být k dispozici po celou dobu zobrazování segmentu. Vstupem funkce je tabulka palet, což je 16 položek barev o rozměru 1 bajt.
  • ScreenSegmGraph2(sSegm* segm, const void* data, const void* trans, int wb) ... 2-bitová paletová grafika 4 barvy (GF_GRAPH2). V 1 bajtu jsou 4 pixely (první pixel v nejvyšších 2 bitech). Funkce vyžaduje překladovou tabulku palet, která se vygeneruje následující funkcí:
  • GenPal4Trans(u32* trans, const u8* pal) ... Vygenerování překladové tabulky palet pro funkci ScreenSegmGraph2. Překladová tabulka je 256 položek o rozměru 32 bitů, v paměti tedy zabere 1024 bajtů. Tabulka je použita během zobrazení k interním účelům, musí být zarovnána na 4 bajty a musí být k dispozici po celou dobu zobrazování segmentu. Vstupem funkce je tabulka palet, což jsou 4 položky barev o rozměru 1 bajt.
  • ScreenSegmGraph1(sSegm* segm, const void* data, u8 bg, u8 fg, int wb) ... 1-bitová mono grafika 2 barvy (GF_GRAPH1). V 1 bajtu je 8 pixelů (první pixel v nejvyšším bitu). Funkce vyžaduje barvu pozadí bg a popředí fg.
  • ScreenSegmMText(sSegm* segm, const void* data, const void* font, u16 fontheight, u8 bg, u8 fg, int wb) ... Mono text (GF_MTEXT). U mono textu je barva popředí a pozadí platná pro celý segment. V obrazové paměti jsou jednotlivé znaky, 1 bajt je jeden znak.
  • ScreenSegmAText(sSegm* segm, const void* data, const void* font, u16 fontheight, const void* pal, int wb) ... Atributový text (GF_ATEXT). U atributového textu představuje každý znak dvojice bajtů. První bajt je ASCII hodnota znaku, druhý bajt je barevný atribut. Vyšší 4 bity atributu představují barvu pozadí, nižší 4 bity atributu je barva popředí. Barvy se překládají z tabulky palet o 16 barvách.
  • ScreenSegmFText(sSegm* segm, const void* data, const void* font, u16 fontheight, u8 bg, int wb) ... Text s barvou popředí (GF_FTEXT). U textu s popředím představuje každý znak dvojice bajtů. První bajt je ASCII hodnota znaku, druhý bajt je barva popředí. Barva pozadí je společná, udává ji parametr 'bg'. Za zmínku stojí, že implicitní fonty knihovny obsahují ve vyšší polovině fontů (bit 7 nastaven) invertovanou nižší polovinu fontu - tím lze zajistit znak s volitelnou barvou pozadí.
  • ScreenSegmCText(sSegm* segm, const void* data, const void* font, u16 fontheight, int wb) ... Text s barvou (GF_CTEXT). U textu s barvou zabírá každý znak 3 bajty. První bajt je ASCII hodnota znaku, druhý bajt je barva pozadí a třetí bajt je barva popředí.
  • ScreenSegmGText(sSegm* segm, const void* data, const void* font, u8 fontheight, u8 bg, const void* grad, int wb) ... Text s gradientem (GF_GTEXT). V tomto módu je každý znak zastoupen 1 bajtem v paměti a barva pozadí je určena paramtrem 'bg', podobně jako u mono textu. Namísto barvy popředí je zde parametr 'grad', což je ukazatel na gradient barev o délce rovnající se grafické délce řádku textu (např. pro 40 znaků má gradient 320 bajtů). Z tabulky gradientu je převzata barva popředí pro každý pixel znaku.
  • ScreenSegmDText(sSegm* segm, const void* data, const void* font, u8 fontheight, u8 bg, const void* grad, int wb) ... Text s dvojitým gradientem (GF_DTEXT). Funkce je totožná s předcházející funkcí s tím rozdílem, že každý pixel znaku se generuje jako 2 pixely obrazu. Tedy znak má dvojnásobnou šířku. Je to jediný textový mód umožňující zobrazení znaků s dvojnásobnou šířkou. Gradient barev zde funguje obdobně, avšaj 1 bajt gradientu představuje 1 pixel znaku (jako u předešlé funkce), ne 1 zobrazený pixel. Tedy řádek 40 znaků vyžaduje opět gradient 320 bajtů.
  • ScreenSegmTile(sSegm* segm, const void* data, const void* tiles, int w, int h, int wb) ... Dlaždice ve sloupci (GF_TILE). Dlaždice jsou obrazové segmenty o zadaném rozměru (šířka a výška dlaždice je 'w' a 'h'). Vzory dlaždic jsou uspořádané do jednoho obrazu. V tomto případě do sloupce o šířce 1 dlaždice. Parametr 'tiles' je ukazatel na obraz sloupce dlaždic. Parametr 'data' je ukazatel na pole bajtů, kde každý bajt představuje zobrazené číslo dlaždice. Dlaždic tedy může být maximálně 256. Parametr 'wb' se vztahuje k délce řádku pole indexů (ne k délce obrazu s dlaždicemi). Šířka dlaždice musí být násobek 4, nejméně 8. Dlaždice umožňují efektivní zobrazení obrazové informace, tím že se obraz může opakovat. Lze tak dosáhnout velkého rozlišení obrazu s malými nároky na paměť.
  • ScreenSegmTile2(sSegm* segm, const void* data, const void* tiles, int w, int h, int tilewb, int wb) ... Dlaždice v řádku (GF_TILE2). Funkce je alternativou k předešlé funkci s tím rozdílem, že vzory dlaždic jsou v obraze uspořádány do jednoho řádku. To může být pohodlnější při vytváření obrazu dlaždic, ovšem je nutné navíc zadat parametr 'tilewb' představující délku linky obrazu dlaždic. Obvykle tilewb = počet dlaždic * šířka dlaždice.
  • ScreenSegmLevel(sSegm* segm, const void* data, u8 bg, u8 fg, u8 zero) ... Segment zobrazení úrovně (GF_LEVEL). Segment slouží k zobrazení grafů. Vstupem je pole bajtů 'data' o délce odpovídající šířce pole v pixelech. Hodnota bajtu představuje výšku grafu na dané souřadnici X. Displej zobrazí barvu popředí nebo pozadí podle toho, zda zobrazený pixel leží nad hodnotou z pole dat nebo pod. Parametr 'zero' udává výšku referenční nuly. Nula neznamená negativní čísla v datech, čísla jsou stále udaná jako bezznaménková (s nulou na spodním okraji). Od referenční nuly se zamění barva pozadí a popředí. To má za následek, že graf vypadá vizuálně symetrický kolem referenční nuly. Vzhled segmentu můžete vidět v ukázkovém programu Oscilloscope (dolní křivka).
  • ScreenSegmLevelGrad(sSegm* segm, const void* data, const void* sample1, const void* sample2) ... Segment zobrazení úrovně s gradientem (GF_LEVELGRAD). Segment slouží k zobazení grafů, podobně jako předešlá funkce. Liší se tím, že barva se udává jako vertikální gradient o výšce odpovídající výšce segmentu. Leží-li pixel pod hodnotou dat, použije se barva z prvního gradientu. Jinak se použije druhý gradient. Příklad využití lze vidět v ukázkovém programu Level Meter, k zobrazení spektra.
  • ScreenSegmOscil(sSegm* segm, const void* data, u8 bg, u8 fg, int pixh) ... Segment zobrazení křivky osciloskopu (GF_OSCIL). Segment se funkcí podobá segmentu pro zobrazení úrovně. Liší se tím, že křivka se zobrazí jako čára o tlouštce 'pixh' pixelů. Tato funkce už je náročnější a nemusí být schopna stihnout obsloužit celou šířku obrazu.
  • ScreenSegmOscLine(sSegm* segm, const void* data, u8 bg, u8 fg) ... Segment spojité křivky osciloskopu (GF_OSCLINE). Křivka se zobrazí jako spojitá čára o tloušťce 1 pixel. Tento mód je již velmi náročný na vykreslení a je proto urychlen snížením horizontálního rozlišení na polovinu (vykresluje body široké 2 pixely).
  • ScreenSegmPlane2(sSegm* segm, const void* data, int plane, const void* trans, int wb) ... 2-bitová paletová grafika 4 barvy ve 2 rovinách (GF_PLANE2). Mód se funkcí podobá grafickému módu 2-bitových barev, avšak jednotlivé bity pixelů jsou uloženy do 2 samostatných barevných rovin. Tento režim se podobá CGA grafickému módu počítačů PC. Jednotlivé roviny odpovídají dvěma samostatným monochromatickým grafickým módům. Každý bajt roviny obsahuje 8 pixelů (první pixel v nejvyšším bitu). Parametr 'plane' je relativní offset druhé roviny od první roviny, udané parametrem 'data'. Funkce vyžaduje překladovou tabulku palet, která se vygeneruje následující funkcí:
  • GenPal4Plane(u32* trans, const u8* pal) ... Vygenerování překladové tabulky palet pro funkci ScreenSegmPlane2. Překladová tabulka je 256 položek o rozměru 32 bitů, v paměti tedy zabere 1024 bajtů. Tabulka je použita během zobrazení k interním účelům, musí být zarovnána na 4 bajty a musí být k dispozici po celou dobu zobrazování segmentu. Vstupem funkce je tabulka palet, což jsou 4 položky barev o rozměru 1 bajt.

V utilitách knihovny PicoVGA není sice k dispozici program, který připraví obrázek v módu 2 rovin, ale k dispozici je interní funkce Plane2Conv, která zkonvertuje obrázek v 4 barvách na mód se 2 rovinami. Tedy obrázek se k programu připojí jako 4-barevný, a k přípravě kopie v RAM se použije konverzní funkce.

ScreenSegmAttrib8(sSegm* segm, const void* data, const void* attr, const u8* pal, int wb) ... Grafický mód s atributy (GF_ATTRIB8). Tento mód je známý z počítačů ZX Spectrum. Parametr 'data' je ukazatel na data pixelů. Odpovídá to monochromatickému módu zobrazení, kdy každý bit rozliší, zda se použije barva popředí nebo pozadí. Parametr 'attr' je ukazatel na pole atributů barev. Atribut barvy je bajt, kde nižší 4 bity představují barvu popředí a horní 4 bity barvu pozadí. Atribut se zkonvertuje na barevný pixel pomocí tabulky palet 'pal', což je pole 16 bajtů barev. Každý atribut určuje barvy popředí a pozadí pro skupinku 8 x 8 pixelů. Na každých 8 bajtů pixelů tedy připadá 1 bajt atributů barev. Parametr 'wb' zde udává šířku linky v bajtech jak pro pole pixelů, tak pro pole atributů. Rozdíl je v tom, že adresa v poli atributů se neinkrementuje po každé lince, ale po 8 linkách.

V utilitách knihovny PicoVGA není sice k dispozici program, který připraví obrázek v módu atributů, ale k dispozici je interní funkce Attr8Conv, která zkonvertuje obrázek v 16 barvách na mód s atributy. Tedy obrázek se k programu připojí jako 16-barevný, a k přípravě kopie v RAM se použije konverzní funkce.

  • ScreenSegmProgress(sSegm* segm, const void* data, const void* sample1, const void* sample2) ... Progress indikátor (GF_PROGRESS). Progress indikátor je horizontální ukazatel. Parametr 'data' je pole bajtů o délce odpovídající výšce segmentu. Hodnota bajtu udává délku linky v násobcích 4 pixelů. Tedy hodnota 0 až 255 představuje délku indikátoru 0 až 1020 pixelů. V první části indikátoru (< data) se zobrazí barevný gradient 'sample1', pro druhou část (>= data) se zobrazí 'sample2'.
  • ScreenSegmGraph8Mat(sSegm* segm, const void* data, const int* mat, u16 xbits, u16 ybits) ... 8-bitová grafika s 2D maticovou transformací. Tento segment zobrazí 8-bitový obraz s transformacemi - otočení, změna měřítka, zešikmení a posun. Obraz musí mít šířku a výšku jako mocnina 2. Šířka a výška obrazu se zadává pomocí parametrů xbits a ybits jako počet bitů rozměru. Např. pro obraz 512 x 256 pixelů je xbits = 9, ybits = 8. Parametr 'mat' je ukazatel na pole 6 integer parametrů transformační matice - viz sekce Transformační matice. Segment nepodporuje parametry pro posun a wrapování obrazu, musí se ponechat na implicitních hodnotách.
  • ScreenSegmGraph8Persp(sSegm* segm, const void* data, const int* mat, u16 xbits, u16 ybits, u16 horiz) ... 8-bitová grafika s 3D perspektivou. Segment je podobný předešlému segmentu, jen navíc na obraz uplatní perspektivní deformaci. Je vhodný na zobrazení terénu (SNES mód 7). Parametr 'horiz' udává posun horizontu nad hranici segmentu, tedy stupeň zešikmení perspektivy.
  • ScreenSegmTilePersp(sSegm* segm, const u8* map, const u8* tiles, const int* mat, u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon) ... Dlaždicová grafika s 3D perspektivou. Slouží podobně jako předešlá funkce k zobrazení terénu s 3D projekcí. Namísto 8-bitové grafiky používá definici dlaždic. To umožňuje zobrazení velmi rozsáhlých terénů. Parametr 'map' je ukazatel na mapu dlaždic - indexy dlaždic 0 až 255. Šířka a výška mapy musí být mocnina 2 a zadávají se jako počet bitů mapwbits a maphbits. Dlaždice musí mít čtvercový rozměr, který musí být také jako mocnina 2. Rozměr dlaždic se udává parametrem tilebits jako počet bitů rozměru. Parametr 'tiles' je ukazatel na obraz se vzorem dlaždic, uspořádaných do 1 sloupce dlaždic. Parametr 'horizon' udává posun horizontu nad hranici segmentu / 4. Kladné číslo představuje posun horizontu, při záporném čísle se perspektiva otočí (lze použít k zobrazení oblohy). Nulová hodnota perspektivu vypne - v tom případě se funkce podobá funkci pro zobrazení obrazu s transformační maticí (s polem dlaždic lze rotovat, zešikmit atd).
  • ScreenSegmTilePersp15(sSegm* segm, const u8* map, const u8* tiles, const int* mat, u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon) ... Podobná funkce, ale pixely se vykreslují o šířce 1.5 pixelu. Funkci lze využít pokud předešlá funkce nestíhá renderování.
  • ScreenSegmTilePersp2(sSegm* segm, const u8* map, const u8* tiles, const int* mat, u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon) ... Podobná funkce, ale pixely se vykreslují o šířce 2 pixelů. Funkci lze využít pokud předešlá funkce nestíhá renderování.
  • ScreenSegmTilePersp3(sSegm* segm, const u8* map, const u8* tiles, const int* mat, u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon) ... Podobná funkce, ale pixely se vykreslují o šířce 3 pixelů. Funkci lze využít pokud předešlá funkce nestíhá renderování.
  • ScreenSegmTilePersp4(sSegm* segm, const u8* map, const u8* tiles, const int* mat, u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon) ... Podobná funkce, ale pixely se vykreslují o šířce 4 pixelů. Funkci lze využít pokud předešlá funkce nestíhá renderování.

Překryvné vrstvy

Zobrazení obrazu knihovnou PicoVGA se provádí pomocí řadiče PIO procesoru. Používá se PIO0. Druhý řadič, PIO1, je nepoužitý a lze využít k jiným účelům. PIO0 obsahuje 4 state machine, SM0 až SM3. Všechny state machine PIO0 používají společný program o velikosti 32 instrukcí. Každý state machine obsluhuje 1 překryvnou vrstvu. SM0 obsluhuje základní vrstvu 0, spolu s obsluhou synchronizačního signálu. Program pro obsluhu základní vrstvy tvoří 15 instrukcí, počínaje offsetem 17. Tato část programu je neměnná a používá se vždy. Ostatní 3 vrstvy, 1 až 3, SM1 až SM3, používají druhou část programové paměti, 17 instrukcí od adresy 0. Tato část se může měnit, podle módu překryvných vrstev. Všechny 3 překryvné vrstvy používají společný program a musí proto pracovat ve stejném módu zobrazení. Některé módy překryvných vrstev používají stejný program a mohou být sdíleny - blíže v tabulce níže.

Poznámka: Pouze základní vrstva 0 může obsahovat segmenty v různém formátu. Překryvné vrstvy 1 až 3 jsou na formátu základní vrstvy nezávislé, sdílejí s ní jen celkovou plochu displeje, ale používají svůj vlastní formát obrazu, u kterého se udává pouze souřadnice a rozměr.

Překryvné vrstvy mohou použít jeden z následujících programů:

  • LAYERPROG_BASE ... je označení programu základní vrstvy 0. Nelze použít pro překryvné vrstvy. Použití parametru u překryvné vrstvy znamená, že vrstva je neaktivní (nepoužívá program).
  • LAYERPROG_KEY ... vrstva s klíčovou barvou. Zadaná barva je nahrazena průhledností.
  • LAYERPROG_BLACK ... průhlednost s černou barvou. Černá barva je nahrazena průhledností. Oproti předešlému módu je výhoda menší náročnosti na rychlost procesoru.
  • LAYERPROG_WHITE ... průhlednost s bílou barvou. Je rychlejší podobně jako předešlá funkce a je vhodné použít tam, kde je potřeba zachovat černou barvu, ale může se oželet bílá barva. Při přípravě obrazu se obraz nekopíruje z Flash do RAM funkcí memcpy, ale použije se funkce CopyWhiteImg. Funkce zajistí, že pixely kopírovaného obrázku se inkrementují o 1. Tím se změní bílá barva (s hodnotou 255) na černou barvu (s hodnotou 0). Od této chvíle se s obrázkem pracuje jako by měl průhlednost s černou barvou - např. se udává černá barva pro funkci vykreslení sprajtů. Teprve až se obrázek dostane do programu v PIO0, program pixel zprůhlední stejně jako v případě černé barvy, ale současně hodnotu pixelu dekrementuje. Tím se barvy vrátí zpět k původní hodnotě, černá barva se stane černou a bílá barva byla použita jako průhlednost.
  • LAYERPROG_MONO ... Tento program v sobě zahrnuje 2 podprogramy. Prvním je zobrazení monochromatického obrazu. Pro každý bit obrazových dat se buď zobrazí zvolená barva obrazu nebo příslušný pixel bude průhledný. Tento mód je použit v příkladu Oscilloscope k zobrazení mřížky přes obrazovku osciloskopu. Druhým podprogramem je zobrazení barevného obrazu bez průhlednosti. Pixely barev se zobrazují tak jak jsou, bez možnosti průhlednosti, ale lze definovat rozměry obdélníku obrazu a jeho souřadnici na displeji. Tedy jakási obdoba jednoho obdélníkového sprajtu bez průhlednosti.
  • LAYERPROG_RLE ... Mód RLE komprese. RLE komprese není nějaký obecně platný formát. Znamená, že data obsahují informace o délce segmentu. V tomto případě knihovny PicoVGA obsahují obrazová data přímo instrukce pro PIO program. Přesněji - data obrazu jsou prokládána adresami skoků uvnitř programu. Obraz je připraven pomocí programu RaspPicoRle a je silně vázaný na použitý program vrstvy. Pokud by se např. posunuly instrukce v programu, formát RLE komprese by přestal fungovat. To je také důvod, proč program pro základní vrstvu 0 je umístěn na konci programové paměti a programy překryvných vrstvev na začátku - aby se snížila šance, že při změnách v programu se změní umístění programu v paměti, kdy by RLE komprese přestala fungovat. Po úpravě RLE programu v PIO je nutné aktualizovat i konverzní program.

V definici videomódu pomocí funkce VgaCfg se zadává požadovaný mód každé překryvné vrstvy. Z módu vrstvy se odvozuje použitý program a funkce pro obsluhu vykreslení vrstvy. Více módů vrstvy může sdílet shodný typ programu. Módy vrstev mají různé požadavky na časování state machine. Konfigurační funkce to zohlední a přizpůsobí tomu frekvenci procesoru.

Módy překryvných vrstev

Módy *WHITE, používající bílou průhlednou barvu, vyžadují přípravu obrazu pomocí funkce CopyWhiteImg, jak je uvedeno u programu LAYERPROG_WHITE.

  • LAYERMODE_BASE ... Označuje mód základní vrstvy 0. Pro překryvnou vrstvu nelze použít, ale používá se k označení neaktivní vypnuté překryvné vrstvy.
  • LAYERMODE_KEY ... Vrstva se zadanou klíčovou barvou.
  • LAYERMODE_BLACK ... Vrstva s černou klíčovou barvou.
  • LAYERMODE_WHITE ... Vrstva s bílou klíčovou barvou.
  • LAYERMODE_MONO ... Monochormatický obraz.
  • LAYERMODE_COLOR ... Barevný obraz (bez průhlednosti).
  • LAYERMODE_RLE ... Obraz s RLE kompresí.
  • LAYERMODE_SPRITEKEY ... Sprajty se zadanou klíčovou barvou.
  • LAYERMODE_SPRITEBLACK ... Sprajty s černou klíčovou barvou.
  • LAYERMODE_SPRITEWHITE ... Sprajty s bílou klíčovou barvou.
  • LAYERMODE_FASTSPRITEKEY ... Rychlé sprajty se zadanou klíčovou barvou.
  • LAYERMODE_FASTSPRITEBLACK ... Rychlé sprajty s černou klíčovou barvou.
  • LAYERMODE_FASTSPRITEWHITE ... Rychlé sprajty s bílou klíčovou barvou.
  • LAYERMODE_PERSPKEY ... Obraz s transformační maticí se zadanou klíčovou barvou.
  • LAYERMODE_PERSPBLACK ... Obraz s transformační maticí s černou klíčovou barvou.
  • LAYERMODE_PERSPWHITE ... Obraz s transformační maticí s bílou klíčovou barvou.
  • LAYERMODE_PERSP2KEY ... Obraz s transformační maticí se zadanou klíčovou barvou a zdvojenou šířkou.
  • LAYERMODE_PERSP2BLACK ... Obraz s transformační maticí s černou klíčovou barvou a zdvojenou šířkou.
  • LAYERMODE_PERSP2WHITE ... Obraz s transformační maticí s bílou barvou a zdvojenou šířkou.

Sdílené módy překryvných vrstev

Módy vrstev lze spolu kombinovat jen pokud používají stejný program. CPP je minimální požadovaný počet taktů SMx na pixel.

  PROG_BASE PROG_KEY PROG_BLACK PROG_WHITE PROG_MONO PROG_RLE CPP
LAYERMODE_BASE x           2
LAYERMODE_KEY   x         6
LAYERMODE_BLACK     x       4
LAYERMODE_WHITE       x     4
LAYERMODE_MONO         x   4
LAYERMODE_COLOR         x   2
LAYERMODE_RLE           x 3
LAYERMODE_SPRITEKEY   x         6
LAYERMODE_SPRITEBLACK     x       4
LAYERMODE_SPRITEWHITE       x     4
LAYERMODE_FASTSPRITEKEY   x         6
LAYERMODE_FASTSPRITEBLACK     x       4
LAYERMODE_FASTSPRITEWHITE       x     4
LAYERMODE_PERSPKEY   x         6
LAYERMODE_PERSPBLACK     x       4
LAYERMODE_PERSPWHITE       x     4
LAYERMODE_PERSP2KEY   x         6
LAYERMODE_PERSP2BLACK     x       4
LAYERMODE_PERSP2WHITE       x     4

 

Volba zápisových rovin

Standardně probíhá výstup obrazu z vrstev do všech výstupních pinů. To lze změnit předefinováním polí LayerFirstPin a LayerNumPin (ve vga_layer.cpp). Lze určit pro každou vrstvu zvlášť, do kterých výstupních pinů se bude zapisovat. Tím lze vytvořit jakousi pseudo-průhlednost. Např. jedna vrstva bude vykreslovat křivky červenou barvou, jiná vrstva zelenou barvou, a barvy se budou nezávisle na sobě prolínat. Při předefinování pinů je však nutné počítat s tím, že se posune i offset mapování pinů. Výstup bude probíhat vždy od nejnižších bitů pixelu.

Konfigurace překryvných vrstev

Prvním krokem pro nastavení překryvné vrstvy je zadání módu vrstvy pro inicializační funkci VgaCfg. Funkce detekuje potřebný program a potřebné časování. Nekontroluje se, zda jsou spolu kombinovány správné módy vrstev.

Jako druhý krok je inicializace popisovače vrstvy - struktura sLayer v poli LayerScreen. Je vhodné k tomu použít inicializační funkci:

LayerSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 col = 0, const void* par = NULL) ... Parametr 'inx' obsahuje číslo vrstvy 1..3, 'img' je ukazatel na obrazová data, 'vmode' je ukazatel na připravenou strukturu Vmode, 'w' je šířka obrazu, 'h' je výška obrazu, 'col' je klíčová barva. V případě módů *BLACK i *WHITE zadejte barvu COL_BLACK (resp. 0). 'par' je doplňkový parametr. Funkce nastaví rozměry obrázku a jeho adresu. Souřadnice vynuluje. Pozici obrazu na obrazovce lze nastavit funkcemi LayetSetX a LayerSetY. Souřadnice nezávisí na grafických módech základní vrstvy a vztahují se k levému hornímu rohu aktivní plochy obrazovky.

Po inicializaci zůstává vrstva vypnutá. Viditelnost vrstvy je nutné zapnout voláním funkce LayerOn. V případě módu s transformační maticí (LAYERMODE_PERSP*) se namísto uvedené funkce použije tato funkce:

LayerPerspSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 xbits, u8 ybits, s8 horiz, const int* mat, u8 col = 0) ... Na rozdíl od předešlé funkce se zadává navíc rozměr zdrojového obrázku v počtu bitů (rozměry obrázku musí být mocnina 2), výška horizontu/4 (pro zápornou hodnotu se podlaha změní na strop, pro nulu se neuplatňuje perspektivní transformace) a ukazatel na transformační matici v celočíselném tvaru.

V případě módu se sprajty se použije tato funkce:

LayerSpriteSetup(u8 inx, sSprite** sprite, u16 spritenum, const sVmode* vmode, s16 x, s16 y, u16 w, u16 h, u8 col = 0) ... Od předešlých funkcí se liší zadáním souřadnice plochy se sprajty, ukazatele na pole adres sprajtů a počtem sprajtů.

Sprajty

Sprajty lze používat v překryvných rovinách s programy KEY, BLACK a WHITE. Jsou dvě možnosti použití sprajtů:

  1. Pomalé sprajty, módy LAYERMODE_SPRITE*. Sprajty jsou generované softwarově. Renderovací funkce linky nejdříve vymaže buffer linky průhlednou barvou a pak postupně prochází pole sprajtů. Hledá, které sprajty danou adresu Y překrývají a v tom případě linku vykreslí do bufferu. Sprajty v tomto módu mají výhodu, že se mohou libovolně překrývat (pořadí překrývání vychází z pořadí umístění v poli adres) a mohou se posouvat jemně po pixelech. Hlavní nevýhodou je velká náročnost na vykreslování. I malé množství sprajtů může způsobit přetečení renderovacího času linky a tím výpadek obrazu. Je však nutno si uvědomit, že se jedná o množství sprajtů (a jejich rozměry) na stejné videolince. Sprajty na vzdálených souřadnicích Y se neovlivňují. Chcete-li ověřit, zda renderovací funkce bude daný počet sprajtů zvládat, umístěte sprajty horizontálně vedle sebe. A naopak, chcete-li zajistit nízké vykreslovací nároky, zajistěte, aby se sprajty nedostaly do stejných vertikálních souřadnic Y. Nebo zmenšete šířku sprajtů.
  2. Rychlé sprajty, módy LAYERMODE_FASTSPRITE*. Sprajty se nevykreslují softwarově do renderovacího bufferu, ale posílají se přímo do PIO pomocí DMA přenosu. Díky tomu je renderování sprajtů velmi rychlé a je možné zobrazit více sprajtů vedle sebe. Samozřejmě to přináší na druhou stranu nevýhody. Souřadnice X sprajtů i jejich šířka musí být násobkem 4, sprajty nelze po obrazovce posouvat jemně (nevztahuje se na souřadnici Y). Ale především, sprajty se nemohou přímo překrývat. Jeden sprajt může pokračovat ve vykreslování tam, kde předešlý sprajt skončil. Tedy předešlý sprajt může utnout začátek následujícího sprajtu. Je zde určité ošetření, které může situaci mírně zlepšit. Pro zlepšení překryvů (a zrychlení renderování) je součástí sprajtů i tabulka která udává, kolik pixelů od okraje začíná neprůhledná linka sprajtu a jak je dlouhá. K vygenerování tabulky lze použít funkci SpritePrepLines. U rychlých sprajtů musí být tato informace násobkem 4. Tedy zajistíme-li, že začátky a konce linek obrazu budou začínat a končit na násobcích 4, sprajty se budou překrývat téměř správně (pokud nebudou mít vnitřní průhlednosti). Jinak v místě překryvu mohou vznikat průhledné díry. Jedním z požadavků na rychlé sprajty je i to, že seznam sprajtů musí být setříděný podle souřadnice X. K tomu slouží podpůrná funkce SortSprite.

Při použití sprajtů bude prvním krokem zadání módu vrstvy LAYERMODE_*SPRITE* pro inicializační funkci VgaCfg.

Druhým krokem bude sestavení pole začátků a délek linek vzorů obrazů sprajtů pomocí funkce SpritePrepLines. Funkci se předá ukazatel na obrázek každého sprajtu (jsou podporovány pouze sprajty s 8-bitovou barvou), rozměry obrázku, ukazatele na pole začátků a délek linek (rozměry polí odpovídají výšce sprajtu) a klíčová barva průhlednosti. Funkce vyhledá začátky a konce linek a zapíše je do polí. Parametr 'fast' udává, zda se tabulky generují pro rychlé sprajty - v tom případě se začátky a délky linek vydělí 4. Pro pomalé sprajty je nutné počítat s omezením šířky sprajtu na 255 pixelů.

  • SpritePrepLines(const u8* img, u8* x0, u8* w0, u16 w, u16 h, u16 wb, u8 col, Bool fast)

Třetím krokem bude sestavení seznamu sprajtů a inicializace sprajtů - především ukazatel na obrázek, rozměry a souřadnice sprajtu. Seznam sprajtů je pole ukazatelů na sprajty. Každý sprajt může být v seznamu jen jednou, ale více sprajtů může sdílet stejný obraz sprajtu a stejné pole začátků a délek linek. Pomalé sprajty mohou mít souřadnice i mimo povolený rozsah (oříznou se), ale u rychlých sprajtů doporučuji nepřekračovat horizontální limity obrazovky, oříznutí obrazu není ještě správně doladěné a program by se mohl zhroutit.

Sprajty nemají sice parametr pro vypínání při nečinnosti, ale jejich vypnutí lze zajistit nastavením souřadnice Y mimo obrazovku. Při renderování se vyhledávají viditelné sprajty podle souřadnice Y, neplatná souřadnice Y zajistí bezpečné znefunkčnění sprajtu.

Rychlé sprajty vyžadují setřídění seznamu podle souřadnice X. K tomu slouží funkce SortSprite, které se předá ukazatel na seznam sprajtů a počet sprajtů v seznamu. Tato funkce by se měla zavolat vždy, když změníte souřadnice X sprajtů. Přechodné stavy (např. chvilkové chybné překrytí sprajtů) nevadí, jde jen o krátkodobé optické chyby, program to neohrozí. Funkce třídí bublinkovou metodou, tedy celkem pomalu, ale zatím se nezdálo že by to něčemu škodilo (sprajtů nebývá mnoho).

  • SortSprite(sSprite** list, int num)

Posledním krokem je inicialitzace vrstvy se sprajty. Funkce byla popsána v předešlé kapitole.

  • LayerSpriteSetup(u8 inx, sSprite** sprite, u16 spritenum, const sVmode* vmode, s16 x, s16 y, u16 w, u16 h, u8 col = 0)

Následuje už jen zapnutí viditelnosti vrstvy funkcí LayerOn a řízení sprajtů změnou jejich souřadnic X a Y a změnou jejich obrázků img.

Canvas

Canvas je kreslicí plátno. Je to podpůrná knihovna pro práci s grafickou plochou a obrázky (blíže soubor canvas.h ve složce _picovga\util). Struktura sCanvas je soubor parametrů, které popisují grafickou plochu, pro použití v kreslicích funkcích. Grafickou plochou může být jak grafický frame buffer, tak i obrázek, a to i ve Flash.

Chcete-li kreslit do grafické plochy, připojte k ní nejdříve canvas jako definici popisující strukturu plochy. A stejně tak, chcete-li vykreslit do plochy obrázek, nejdříve pro obrázek vytvořte jeho canvas s parametry. Jako parametry se do struktury zadá ukazatel na data obrázku, rozměry obrázku a formát. Jako kreslicí plocha může být grafická plocha s hloubkou 1, 2, 4, 8 bitů nebo s atributy. V případě kreslení obrázku do plochy musí mít zdrojový a cílový canvas stejný formát. V případě transformačních matic lze kreslit pouze do 8-bitového grafického formátu.

Poznámka: V PicoVGA je k dispozici implicitní canvas Canvas. Je na něj automaticky připojen grafický frame buffer při inicializaci pomocí funkce Video. Jinak je možné ho používat v programu libovolně.

  • DrawRect(sCanvas* canvas, int x, int y, int w, int h, u8 col) ... vykreslení obdélníku.
  • DrawFrame(sCanvas* canvas, int x, int y, int w, int h, u8 col) ... vykreslení rámu o tloušťce 1 pixel.
  • DrawClear(sCanvas* canvas) ... vyplnění canvasu černou barvou.
  • DrawPoint(sCanvas* canvas, int x, int y, u8 col) ... vykreslení pixelu.
  • DrawLine(sCanvas* canvas, int x1, int y1, int x2, int y2, u8 col) ... vykreslení čáry.
  • DrawFillCircle(sCanvas* canvas, int x0, int y0, int r, u8 col, u8 mask=0xff) ... vykreslení vyplněného kruhu. x0 a y0 jsou souřadnice středu, r je poloměr. Maska 'mask' udává pomocí bitů 0 až 7, které osminy kruhu se vykreslí.
  • DrawCircle(sCanvas* canvas, int x0, int y0, int r, u8 col, u8 mask=0xff) ... vykreslení kružnice, parametry jako u předešlé funkce.
  • DrawText(sCanvas* canvas, const char* text, int x, int y, u8 col, const void* font, int fontheight=8, int scalex=1, int scaley=1) ... výpis textu s průhledným pozadím. scalex a scaley je měřítko zvětšení ve směrech X a Y.
  • DrawTextBg(sCanvas* canvas, const char* text, int x, int y, u8 col, u8 bgcol, const void* font, int fontheight=8, int scalex=1, int scaley=1) ... výpis textu se zadanou barvou pozadí
  • DrawImg(sCanvas* canvas, sCanvas* src, int xd, int yd, int xs, int ys, int w, int h) ... vykreslení obrázku (bez průhlednosti).
  • DrawBlit(sCanvas* canvas, sCanvas* src, int xd, int yd, int xs, int ys, int w, int h, u8 col) ... vykreslení obrázku, průhlednost zadaná klíčovou barvou.
  • DrawImgMat(sCanvas* canvas, const sCanvas* src, int x, int y, int w, int h, const class cMat2Df* m, u8 mode, u8 color) ... vykreslení obrázku s transformací pomocí transformační matice (otáčení atd.). Bližší info v canvas.h.
  • DrawTileMap(sCanvas* canvas, const sCanvas* src, const u8* map, int mapwbits, int maphbits, int tilebits, int x, int y, int w, int h, const cMat2Df* mat, u8 horizon) ... vykreslení mapy dlaždic s perspektivou.
  • DrawImgLine(sCanvas* canvas, sCanvas* src, int xd, int yd, int xs, int ys, int wd, int ws) ... vykreslení linky obrazu s interpolací.

Transformační matice

Některé vykreslovací funkce používají k zobrazení transformační matici cMat2Df, která definuje transformaci obrazu (blíže soubor mat2d.h ve složce _picovga\util). Matice má 6 číselných prvků typu float. Transformace se připraví nastavením výchozího stavu funkcí Unit a poté postupným zadáváním transformací. Použitím matice se provede s obrazem operace, jako by se jednotlivé operace zadávaly postupně.

  • GetX ... provedení transformace pro souřadnici X
  • GetY ... provedení transformace pro souřadnici Y
  • Unit ... inicializace matice na jednotkový výchozí stav
  • Copy ... kopie matice
  • TransX ... posun ve směru X
  • TransY ... posun ve směru Y
  • ScaleX ... změna měřítka ve směru X
  • ScaleY ... změna měřítka ve směru Y
  • RotSC ... rotace se zadáním výsledků funkce sin(a) a cos(a)
  • Rot ... rotace se zadáním úhlu
  • Rot90 ... rotace o 90°
  • Rot180 ... rotace o 180°
  • Rot270 ... rotace o 270°
  • ShearX ... zkosení ve směru X
  • ShearY ... zkosení ve směru Y
  • FlipY ... vertikální překlopení
  • FlipX ... horizontální překlopení
  • PrepDrawImg(int ws, int hs, int x0, int y0, int wd, int hd, float shearx, float sheary, float r, float tx, float ty) ... Příprava matice pro vykreslovací funkci. Pořadí operací je zvoleno tak, jako by se obraz nejdříve posunul do bodu tx a ty, provedla se změna měřítka, zešikmení, pak rotace a nakonec posun do cílových souřadnic.
  • ExportInt(int* mat) ... Export matice do celočíselného pole (6 prvků int). Po transformaci obsahuje 12 spodních bitů čísla desetinnou část čísla, horních 20 bitů obsahuje celočíselnou část čísla. Vykreslovací funkce vyžadují tento celočíselný tvar transformační matice.

Přetaktování procesoru

Některé zobrazující funkce mohou být náročné na rychlost procesoru a mohou vyžadovat přetaktování na vyšší rychlost. Je nutno počítat s tím, že přetaktováním se procesor dostává do oblastí s nezaručenou správnou funkcí. Knihovna PicoVGA umožňuje řídit přetaktování procesoru, podle požadovaného videomódu. Ve funkci VgaCfg lze zadat minimální a maximální frekvenci procesoru. Implicitně knihovna povoluje rozsah 120 až 270 MHz. Může se však stát, že při vyšších frekvencích bude procesor pracovat chybně a může být nutné horní hranici snížit.

Vyhledanou frekvenci procesoru lze nastavit funkcí set_sys_clock_pll.

  • bool vcocalc(u32 reqkhz, u32 input, u32 vcomin, u32 vcomax, bool lowvco, u32* outkhz, u32* outvco, u16* outfbdiv, u8* outpd1, u8* outpd2) ... Funkce pro vyhledání optimálního nastavení PLL generátoru systémových hodin. Funkci se zadá požadovaná výstupní frekvence, vstupní frekvence krystalu (v Raspberry Pico 12 MHz), minimální a maximální frekvence oscilátoru VCO. Výstupem jsou parametry pro nastavení PLL oscilátoru. Funkce navrací True, pokud se jí podařilo nalézt nastavení pro přesnou hodnotu požadované frekvence. Jinak vyhledá nastavení pro nejbližší frekvenci a vrátí False. Blíže soubor overclock.h ve složce _picovga\util.
  • bool FindSysClock(u32 reqkhz, u32* outkhz, u32* outvco, u16* outfbdiv, u8* outpd1, u8* outpd2) ... Vyhledání nastavení PLL generátoru s implicitními parametry.
  • void __not_in_flash_func(FlashSpeedSetup)(int baud) ... Nastavení rychlosti interface pro externí flash.

Tisk textu

Funkce pro tisk textu se používají k výstupu textu do textového frame bufferu (blíže soubor print.h ve složce _picovga\util). V současnosti jsou podporované formáty bufferů GF_ATEXT (text s barevným atributem) a GF_MTEXT (mono text).

  • PrintSetup(u8* buf, int bufw, int bufh, int bufwb) ... Inicializace obsluhy tisku textu. Funkci se předá ukazatel na textový frame buffer a jeho rozměry. Je-li délka řádku v bajtech nižší než dvojnásobek šířky, zvolí se formát mono textu GF_MTEXT, jinak se použije formát s atributy GF_ATEXT. Tato funkce je automaticky volána při inicializaci videomódu pomocí funkce Video.
  • int PrintX, PrintY ... Aktuální tisková pozice.
  • u8 PrintCol ... Aktuální tisková barva (neuplatní se u mono textu).
  • PrintClear() ... Vymazání textového bufferu aktuálně zvolenou barvou.
  • PrintHome() ... Přesun ukazatele na začátek prvního řádku.
  • PrintSetPos(int x, int y) ... Nastavení tiskového ukazatele (sloupec a řádek).
  • PrintAddPos(int x, int y) ... Relativní posun tiskového ukazatele.
  • PrintSetCol(u8 col) ... Nastavení tiskové barvy. Použijte makro PC_COLOR k sestavení barevného atributu.
  • PrintChar0(char ch) ... Vytištění znaku do tiskového bufferu, bez zohlednění řídicích znaků.
  • PrintChar(char ch) ... Vytištění znaku do tiskového bufferu, s obsluhou řídicích znaků CR, LF a TAB
  • PrintSpc() ... Vytištění mezery.
  • PrintSpcTo(int pos) ... Vytištění mezer až po zadanou pozici.
  • PrintCharRep(char ch, int num) ... Opakovaný tisk znaku.
  • PrintSpcRep(int num) ... Opakovaný tisk mezery.
  • PrintText(const char* text) ... Tisk textu.
  • PrintHLine(int x, int y, int w) ... Vykreslení horizontální linky. Ke kreslení se používají znaky pro kreslení čar s kódem 17 až 31, tak jak jsou nadfinovány ve fontech knihovny PicoVGA. Při kreslení se čára kombinuje se znaky které jsou již v tiskovém bufferu tak, aby se čáry správně spojovaly a překrývaly. Funkce neošetřuje přetečení mimo povolený rozsah displeje.
  • PrintVLine(int x, int y, int h) ... Vykreslení vertikální linky. Ke kreslení se používají znaky pro kreslení čar s kódem 17 až 31, tak jak jsou nadfinovány ve fontech knihovny PicoVGA. Při kreslení se čára kombinuje se znaky které jsou již v tiskovém bufferu tak, aby se čáry správně spojovaly a překrývaly. Funkce neošetřuje přetečení mimo povolený rozsah displeje.
  • PrintFrame(int x, int y, int w, int h) ... Vykreslení čárového rámu. Funkce používá předešlé 2 kreslicí funkce.

Zvukový výstup PWM

Knihovna PicoVGA obsahuje podporu pro výstup zvuku pomocí PWM modulace. Implicitně výstup zvuku probíhá na port GPIO19 - nadefinováno v souboru pwmsnd.h ve složce _picovga\util. Na port se lze napojit přímo (např.sluchátka) nebo lépe přes jednoduchý RC filtr s dolní propustí.

Výstup zvuku pomocí PWM modulace má výhodu v tom, že postačí 1 výstupní pin a výstupní obvody jsou velmi jednoduché. Nevýhodou je zašumění zvuku modulačním kmitočtem a nízká bitová hloubka zvuku (používá se hloubka 8 bitů). Vyšší hloubka není možná z důvodu omezené frevence procesoru. Tento výstup je postačující pro většinu běžných nenáročných aplikací (jako jsou retro hry). Pro vyšší kvalitu zvuku se musí použít jiný způsob.

Poznámka: Dojde-li ke změně systémových hodin, je nutné reinicializovat nastavení zvukového výstupu novým zavoláním inicializační funkce.

  • PWMSndInit() ... Inicializace knihovny pro výstup zvuku PWM.
  • PlaySound(const u8* snd, int len, Bool rep = False, float speed = 1.0f) ... Přehrátí zvuku. Zvuk musí být ve formátu nekomprimovaný PCM, mono, 8 bitů, frekvence 22050 Hz. V parametrech lze zadat, zda se zvuk bude opakovat a jaká bude relativní rychlost jeho přehrávání (zvuk lze paramtrem 'speed' zrychlit nebo zpomalit).
  • StopSound() ... Zastaví přehrávání zvuku. Výstup na výstupní pin bude probíhat i nadále (projeví se slabým šumem), ale použije se hodnota nuly 128.
  • SpeedSound(float speed) ... Nastavení rychlosti přehrávání. Používá se při opakovaném přehrávání zvuku ke změně výšky tónu (např. zvuk motoru auta). Hodnota 1.0 představuje standardní rychlost přehrávání.
  • Bool PlayingSound() ... Testuje, zda probíhá přehrávání zvuku.
  • SetNextSound(const u8* snd, int len) ... Nastavení dalšího zvuku k přehrátí. Používá se u opakovaných zvuků, aby se dokončilo přehrátí aktuálnáího zvuku a pokračovalo se dalším zvukem.

Generátor náhody

Knihovna cRandom (blíže viz soubor rand.h ve složce _picovga\util) nahrazuje a rozšiřuje standardní generátor náhodných čísel. Jako seed se používá 64-bitové číslo, což zajistí dostatečnou náhodnost čísla. Omezenou náhodnost standardního 32-bitového generátoru lze pozorovat např. při generování terénu - projeví se jako vlny v terénu. Lze použít buď globální proměnnou Rand a funkce k ní patřící, nebo si vytvořit další lokální generátor cRandom. Následující funkce se vztahují ke globálním generátoru Rand. Při startu programu se doporučuje použít funkci RandInitSeed, která zajistí neopakující se náhodnost generátoru.

  • u64 RandSeed() ... Navrátí aktuální stav seed generátoru náhody. Lze použít k uchování stavu generátoru a jeho pozdější obnově, za účelem reprodukovatelné sekvence náhody.
  • RandSetSeed(u64 seed) ... Nastavení seed generátoru náhody. Bez nastavení seed začíná generátor náhody s implicitní hodnotou 0, která vznikne nulováním paměti při startu programu.
  • RandInitSeed() ... Inicializace generátoru náhody náhorným číslem. Funkce používá výstup z ROSC čítače. Přestože jeho výstup nezajistí velkou pestrost náhodnosti, bude tím zajištěno, že při opakovaném startu programu se nebude začínat se stejnou posloupností náhodnosti. Tato funkce by měla být volána vždy na začátku po spuštění programu.
  • u8 RandU8() ... Generování čísla u8 (0..255)
  • u16 RandU16() ... Generování čísla u16 (0..65535)
  • u32 RandU32() ... Generování čísla u32 (0..0xFFFFFFFF)
  • u64 RandU64() ... Generování čísla u64 (0..0xFFFFFFFFFFFFFFFF)
  • s8 RandS8() ... Generování čísla s8 (-128..+127)
  • s16 RandS16() ... Generování čísla s16 (-32 768..+-32 767)
  • s32 RandS32() ... Generování čísla s32 (-0x80000000..+0x7FFFFFFF)
  • s64 RandS64() ... Generování čísla s64 (-0x8000000000000000..+0x7FFFFFFFFFFFFFFF)
  • float RandFloat() ... Generování desetinného čísla float v rozsahu 0 (včetně nuly) až 1 (vyjma 1).
  • double RandDouble() ... Generování desetinného čísla double v rozsahu 0 (včetně nuly) až 1 (vyjma 1).

Generování čísel od 0 po zadané maximum (včetně maxima):

  • u8 RandU8Max(u8 max)
  • u16 RandU16Max(u16 max)
  • u32 RandU32Max(u32 max)
  • u64 RandU64Max(u64 max)
  • s8 RandS8Max(s8 max)
  • s16 RandS16Max(s16 max)
  • s32 RandS32Max(s32 max)
  • s64 RandS64Max(s64 max)
  • float RandFloatMax(float max) ... Generování čísla float od 0 (včetně nuly) po zadané maximum (vyjma maxima)
  • double RandDoubleMax(double max) ... Generování čísla double od 0 (včetně nuly) po zadané maximum (vyjma maxima)

Generování čísel v zadaném rozsahu, včetně hraničních hodnot (je-li min > max, vygeneruje se číslo vně intervalu):

  • u8 RandU8MinMax(u8 min, u8 max)
  • u16 RandU16MinMax(u16 min, u16 max)
  • u32 RandU32MinMax(u32 min, u32 max)
  • u64 RandU64MinMax(u64 min, u64 max)
  • s8 RandS8MinMax(s8 min, s8 max)
  • s16 RandS16MinMax(s16 min, s16 max)
  • s32 RandS32MinMax(s32 min, s32 max)
  • s64 RandS64MinMax(s64 min, s64 max)
  • float RandFloatMinMax(float min, float max) ... Generování čísla float v rozsahu min (včetně minima) až max (vyjma maxima)
  • double RandDoubleMinMax(double min, double max) ... Generování čísla double v rozsahu min (včetně minima) až max (vyjma maxima)
  • float RandGaussF(float mean = 0, float sigma = 1) ... Generování Gaussova náhodného čísla float, se středem 'mean' a šířkou intervalu 'width'.
  • double RandGaussD(double mean = 0, double sigma = 1) ... Generování Gaussova náhodného čísla double, se středem 'mean' a šířkou intervalu 'width'.

Následující funkce slouží ke generování terénů, pomocí skládání vln závislých na souřadnici. Výstupem je číslo v rozsahu -1 až +1.

  • float Noise1D(int x, int seed) ... Generátor náhody s 1 souřadnicí.
  • float Noise2D(int x, int y, int seed) ... Generátor náhody se 2 souřadnicemi.
  • float Noise3D(int x, int y, int z, int seed) ... Generátor náhody se 3 souřadnicemi.
  • float SmoothNoise1D(float x, int scale, int seed) ... Interpolovaný generátor náhody s 1 rozměrem.
  • float SmoothNoise2D(float x, float y, int scale, int seed) ... Interpolovaný generátor náhody se 2 rozměry.

Fonty

Ve složce _picovga\font naleznete fonty připravené pro využití v programech. Fonty v PicoVGA mají formát monochromatického obrázku (tj. 1 pixel je 1 bit) s 256 znaky na řádku a s šířkou znaků 8 pixelů. Celková šířka obrázku tak je 2048 pixelů (256 bajtů). Výška fontu může být libovolná, ale standardně jsou v knihovně fonty s výškou 8, 14 a 16 linek. Fonty jsou exportované utilitou RaspPicoImg do formátu zdrojového textu *.cpp, přidají se k programu jako bajtové pole.

Příklad fontu font_bold_8x8:

Import obrázků a zvuků

Ve složce _picovga\_exe naleznete podpůrné programy (utility) sloužící ke konverzi obrázků a zvuků do interního tvaru použitého knihovnou PicoVGA. Soubory se k programu přidávají ve formě zdrojového kódu, jako pole. Programy jsou připraveny ve Visual Studio 2005. Jsou to konzolové programy a tak by neměla být náročná jejich úprava i pod Linux.

Ve složce _picovga\_exe naleznete soubory s paletami *.act. Soubory použijete ve Photoshopu nebo Gimpu při konverzi obrázků do palet PicoVGA. Nejdůležitější je soubor palet pal332.act. Je vygenerovaný programem pal332.exe (ve složce pal332) a definuje základní 8-bitové barvy PicoVGA. Ve složce pal332 naleznete též soubor pal332.csv, který obsahuje podrobné informace o barvách - pořadové číslo barvy, RGB hodnotu barvy a hodnoty jednotlivých složek. Soubor můžete zobrazit v Excelu nebo Open Office, ale také jakýmkoliv textovým editorem. Může být užitečný např. v případě, když si ve Photoshopu přečtete RGB HEX hodnotu barvy a chcete vědět, indexu které barvy to odpovídá v PicoVGA. V tom případě HEX kód vyhledáte v souboru (funkcí Najít) a na začátku řádku si přečtete příslušný kód barvy.

Při importu obrázku do barev PicoVGA zkonvertujete obrázek do indexových barev, jako palety zvolíte "Custom" (vlastní palety) a ze souborů palet načtete příslušnou paletu. V některých případech (fotografie) může být užitečné zapnout volbu ditheringu (obvykle metoda Diffusion s 75%), jindy je lepší bez ditheringu.

Uložený obrázek importujete do PicoVGA programem RaspPicoImg (ve složce _picovga\_exe\img). Obrázek ukládejte vždy do souboru formátu Windows BMP, vypnutá komprese a zapnuté obrácené pořadí linek. V případě 8-bitové grafiky použijte k importu soubor palet pal332.act a obrázek uložte jako 8-bitový paletový soubor BMP. Při exportu do 4-bitové grafiky použijte 4-bitové palety, obvykle pal4_PC.act (palety CGA) nebo pal4_ZX.act (palety ZX Spectrum) a obrázek uložte jako 4-bitový paletový obrázek. Při exportu do 2-bitové grafiky použijte některou ze 2-bitových palet palcga*.act (palety CGA v módu 1 až 6). Obrázek BMP nepodporuje 2-bitový formát, ale můžete ho uložit jako 4-bitový, program RaspPicoImg rozpozná z palet že se jedná o 2-bitový obrázek a provede příslušnou konverzi. Při exportu do 1-bitové grafiky (mono) použijte soubor palet pal1.act a obrázek uložte jako 1-bitový paletový soubor.

Při konverzi obrázku do RLE komprimovaného formátu použijte program RaspPcoRle ve složce _picovga\_exe\rle. Vstupem programu je obrázek BMP zkonvertovaný do 8-bitových palet PicoVGA (soubor palet pal332.act), uložený bez komprese, se zapnutým obráceným pořadím linek. Čtvrtý parametrem programu je číslo barvy, která se použije jako průhlednost. Číslo barvy najdete z HEX kódu (zjištěný ve Photoshopu kapátkem) v souboru pal332.act. Nemá-li obrázek mít průhlednost, zadejte namísto barvy průhlednosti -1.

Program RaspPicoRle je silně závislý na PIO programu RLE. Do kódu ukládá instrukce s offsety potřebnými k funkci programu. Musíte proto použít vždy program ze stejné verze, jako je PicoVGA knihovna, protože někdy v budoucnu může dojít ke změně formátu použitého RLE kódu.

Ve složce snd naleznete program RaspPicoSnd, kterým lze importovat zvuky do PicoVGA. Importovaný zvuk musí být ve formátu WAV, bez komprese (komprese PCM), 8 bitů, mono, rate 22050 Hz. K úpravám zvuku můžete použít editor Cool Edit, nebo free program Audacity. Audacity disponuje mnoha zvukovými efekty, umožňuje dobrou manipulaci se zvukovými stopami a byl jím i připraven zvuk pro video s ukázkami programů knihovny PicoVGA.

Ukázkové programy

Programy jsou připraveny pro ovládání klávesnicí přes konzoli v PC (doporučeno begPutty) a virtuální sériový USB port. Podrobnější návod k připojení konzole naleznete v článku o RaspPicoSDK. Některé hry používají zvuk - generování PWM zvuku přes pin GP19. Hry s PWM zvukem jsou označeny poznámkou "(zvuk)".

Ants - karetní hra (zvuk). Dvě mraveniště spolu soupeří o nadvládu. Cílem je postavit vyšší hrad. Ovládání: J vlevo, L vpravo, mezerník vybrat kartu, D odložit, H pomoc, Q konec. Lze hrát proti jinému hráči i proti počítači.
Balloons - demonstrace použití sprajtů, poletující balonky (celkem 43 sprajtů).  
Draw - demonstrace kreslení grafických prvků. Pro ukázku se střídá pomalé vykreslování a kreslení maximální rychlostí.  
Earth - rotující zeměkoule. Softwarová sférická transformace obrázku.  
Eggs - logická hra (zvuk). Vychází ze hry Reversi. Cílem je získat co nejvíce vlastních kamenů. Jeden hráč mění kameny ve směru slepice-kuře-vejce, druhý hráč opačným směrem. Ovládání: L vpravo, I nahoru, J vlevo, K dolů, H pomoc, Q konec, P 2 hráči, D demo, mezerník položení kamene, Enter ok. Lze hrát proti jinému hráči i proti počítači.
Fifteen - logická hra (zvuk). Cílem je seřadit kameny v pořadí 1 až 15. Ovládání: L vpravo, I nahoru, J vlevo, K dolů, Q nová hra.  
Flag - vlající vlajka.  
Ghost Racing - závody aut (zvuk). Po projetí prvního kola (je nutný průjezd checkpointy) se objeví soupeř - "duch", který kopíruje vaši předchozí cestu. Soupeříte tak sami se sebou. Ve hře jsou celkem 2 soupeři duchové (druhý se má objevit po projetí druhého kola). Hra je nedodělaná - nepodařilo se mi vypočítat správnou transformaci obrazu soupeřů do kamery a je teď jen velmi přibližná. Je to spíš jen polotovar pro inspiraci a demonstraci 3D projekce terénu (plochy z dlaždic). Ovládání: I přeřadit nahoru, K přeřadit dolů, J doleva, L doprava. Lze zařadit 5 rychlostních stupňů. Původně byla možná i zpátečka, ale ta spíš překážela.  
Gingerbread House - pohádková knížka o perníkové chaloupce. Program slouží jako ukázka práce s obrázky s RLE kompresí. Ovládání: J předchozí stránka, L další stránka.
Hello World - nejjednodušší ukázkový příklad použití knihovny PicoVGA.  
Hypno - hypnotizující rotující obrazec. Ukázka maticové transformace obrázku.  
Level Meter - simulace indikátoru spektra hudby (zvuk). Program používá mód zobrazení úrovní grafu s gradientem. Vstupem pro displej je pole hodnot. Není potřeba obraz indikátorů generovat programově a tak lze dosáhnout velmi rychlé odezvy na změnu. V demo ukázce se používají náhodné vzorky.  
Life - simulátor života buněk (celulární automat). Buňky se v každém kroku mění podle počtu sousedních buněk: pro 1 a méně buňka zaniká na osamocení, pro 4 a více buňka zaniká na přemnožení, pro 3 vznikne nová buňka, pro 2 není změna. Ve hře se lze přepínat mezi 10 obrazovkami (sloty) a přenášet obraz mezi nimi pomocí schránky. V každém slotu je předpřipravena definice populárních kombinací. Ovládání: L vpravo, I nahoru, J vlevo, K dolů, C kopie do chránky, V vložení ze schránky, D vymazání plochy, mezerník změna buňky, Enter start/stop automatu, 0-9 výběr slotu.  
Lines - generátor čárových relaxačních obrazců.  
Mandelbrot - generátor fraktálových obrazců Mandelbrotovy množiny. Ke generování je použita integer matematika a díky tomu je překreslení obrazce rychlé. Je však nutno počítat s tím, že při zvětšování měřítka zobrazení je potřebná rostoucí přesnost počtu číslic. Použitá integer a float matematika vystačí do měřítka zvětšení 10^5, double matematika do měřítka 10^10. Při dalším zvětšování se namísto obrazce zobrazí už jen barevné čáry. Ovládání: E nahoru, S vlevo, D vpravo, X dolů, Q zvětšení měřítka, A zmenšení měřítka, L volba nízkého rozlišení 132x100, M volba středního rozlišení 264x200, H volba vysokého rozlišení 528x400, I přepnutí na celočíselnou matematiku (nejrychlejší, dosah do 10^-5), F přepnutí na float matematiku (pomalejší, dosah do 10^-5), B přepnutí na double matematiku (pomalá, dosah do 10^-10), O snížení počtu kroků iterací, P zvýšení počtu kroků iterací, U zvýšení systémových hodin, T snížení systémových hodin, mezera překreslení obrazovky.
Matrix Rain - simulace "matrixového kódového deště". Používá textový videomód.  
Maze - cílem je najít cestu z bludiště. Bludiště jsou generována náhodně programově. Ovládání: J vlevo, I nahoru, L vpravo, K dolů, H pomoc (ukázání dveří).  
Monoscope - test videomódů. Klávesami 0 až 9 a A až U lze přepínat rozlišení displeje, od 256x192 po 1280x960, pro VGA monitor i PAL/NTSC televizor. Pro televizor se pro vyšší rozlišení používá prokládaný obraz (jako je TV vysílání), pro nižší rozlišení se použije neprokládaný mód (jako jsou výstupy z 8-bitových počítačů). Lze využít k testování zobrazení na různá zařízení. Jednotlivé testovací obrazce jsou v programu uchovány jako připravené obrázky s RLE kompresí. Bylo by možné program upravit tak, aby používal jen 1 obrázek, který se bude přepočítávat podle potřeby, ale musel by se při generování komprimovat do RAM s RLE kompresí, protože v plné velikosti by se do RAM nevešel.
Oscilloscope - demonstrace zobrazení signálů osciloskopu. Program používá mód zobrazení grafů a křivek. Obraz průběhu signálu není nutné generovat softwarově, displeji se předá pouze pole hodnot, a to umožňuje velmi rychlou odezvu na změnu hodnot. V demo ukázce jsou vzorky generované programově. Slouží i jako ukázka skládání segmentů obrazu v různém módu. Základní obrázek osciloskopu je 8-bitová bitmapa (s ditheringem), skládající se ze 4 pruhů. V místě obrazovky jsou použity 2 prvky pro zobrazení grafů. Obrazovku překrývá překryvná průhledná vrstva s mřížkou.  
Pac-Man - populární akční hra (zvuk). Hra se snaží napodobit původní verzi hry z roku 1980, od společnosti Namco. Je dodržena logika chování duchů, počítání skore a levelů. Upozorňuji, že zvuky a vzhled jsou převzaty z původní hry, vztahuje se na ně copyright společnosti Namco a proto hra slouží jen jako inspirační ukázka. Ovládání: J vlevo, I nahoru, L vpravo, K dolů, A pauza.
Pi - výpočet čísla Pi na 4833 číslic. Po výpočtu je výsledek zkontrolován s očekávaným vzorkem.  
Pixels - náhodné generování barevných pixelů.  
Raytracing - generování 3D obrazce metodou ray tracing. Vzhledem k omezené barevné hloubce PicoVGA je při zobrazení použit rastrový dithering ("zrnitost" obrázku).  
Sokoban - logická hra (zvuk). Cílem je přesunout bedny na označená políčka. Hra obsahuje 3000 scén od různých autorů, spolu s jejich řešením. Ovládání: L vpravo, I nahoru, J vlevo, K dolů, H pomoc (ukázka řešení scény), R restart scény, Q předchozí scéna, W další scéna, P výpis info.
Spheres - náhodné generování koulí.  
Spots - náhodné generování skvrn.  
Tetris - populární hra, skládání kostek (zvuk). Ovládání: L vpravo, I otočení, J vlevo, K položení, A pauza.  
Train - logická hra na principu Hada (zvuk). Cílem je posbírat všechny předměty a projet branou. Hra má 50 scén, spolu s jejich řešením. Ovládání: L vpravo, I nahoru, J vlevo, K dolů, H pomoc (ukázka řešení scény), Enter zadání hesla, Esc zpět, BS smazání znaku.
Twister - zkroucení texturovaného kvádru. Slouží jako ukázka programové deformace obrázku, s využitím hardwarového interpolátoru.  
Water Surface - simulace vlnící se vodní hladiny (zvuk).  

 

Video ukázka

 

Na stažení

Download knihovny PicoVGA

Alternativní odkaz na uložto - klikn

Máte aj vy zaujímavú konštrukciu, alebo článok?

Máte aj vy zaujímavú konštrukciu , alebo článok a chceli by ste sa o to podeliť s viac ako 200.000 čitateľmi? Tak neváhajte a dajte nám vediet, radi ju uverejníme a to vrátane obrazových a video príloh. Rovnako uvítame aj autorov teoretických článkov, či autorov zaujímavých videí z oblasti elektroniky / elektrotechniky.

Kontaktujte nás!


Páčil sa Vám článok? Pridajte k nemu hodnotenie, alebo podporte jeho autora.
 

       

Komentáre k článku

Zatiaľ nebol pridaný žiadny komentár k článku. Pridáte prvý? Berte prosím na vedomie, že za obsah komentára je zodpovedný užívateľ, nie prevádzkovateľ týchto stránok.
Pre komentovanie sa musíte prihlásiť.

Vaša reklama na tomto mieste

Vyhľadajte niečo na našom blogu

PCBWay Promo

ourpcb Promo

PCBWay Promo

ourpcb Promo

PCBWay Promo

ourpcb Promo


Webwiki Button