%=========================================================================
% (c) Jakub Jelen, 2012, 2013

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%                       Uvod                                %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Úvod}

Pro svoji bakalářskou práci jsem zvolil implementaci programu pro mobilní operační systém webOS. V~úvodu představím tento operační systém z~pohledu uživatelského, jeho vývoj a způsob tvorby aplikací pro tuto platformu. Dále následuje popis platformy Wherigo a souvisejících souborových formátů. 

V~další kapitole jsou zmíněny požadavky na aplikaci z~uživatelského hlediska, navrženo řešení propojení jazyků C++ a Lua, postup návrhu vlastních objektů Wherigo knihovny a analýza použitých typů souborů, které v~aplikaci používám. 

Další část již obsahuje detaily implementace pro systém webOS, strukturu aplikace s~rozdělením na logické a fyzické celky v~různých programovacích jazycích a použité algoritmy.

Poslední kapitola shrnuje metody testování a obsahuje příklady cartridgí, na~kterých byla moje aplikace otestována, jak v~reálné podobě, tak virtuálně, pomocí simulace GPS dat.

\section{Operační systém webOS}

\subsection{Historie a vývoj}
WebOS je operační systém pro mobilní telefony vyvinutý společností Palm, představený začátkem roku 2009 na veletrhu spotřební elektroniky CES\footnote{Consumer Electronics Show}. Již při představení přilákal mnoho pozornosti a první telefon s~tímto operačním systémem získal několik ocenění \cite{wikiPalmPre}. Přes počáteční úspěchy se firma potýkala s~mnohými problémy, a tak byla již začátkem roku 2010 i se systémem koupena firmou HP. Ta v~systém vkládala velké naděje a měla v~plánu používat jej v~různých vestavěných systémech. Ale již koncem roku 2011 bylo ohlášeno uvolnění systému jako opensource. Komunita se ujala otevřeného zdrojového kódu a dnes, v~roce 2012, existují funkční porty webOS na telefony jiných výrobců. Jméno se změnilo na Open webOS a oddělení se přejmenovalo na GRAM \cite{openWebOS}. Začátkem roku 2013 firma HP prodala webOS firmě LG, která má práva využít systém nebo jeho části ve svých chytrých televizích \cite{wikiWebOS}.


\subsection{Technická data}
Systém je postaven na linuxovém jádře stejně jako Android, ale uživatelské rozhraní a aplikace jsou tvořeny, jak už název napovídá, webovými technologiemi - javascriptem, HTML a CSS. Aplikace jsou spouštěny v~prostředí WebKit. Systém splňuje všechny předpoklady pro použití na chytrém telefonu včetně připojení k~WiFi, datovým sítím operátora, GPS přijímače, Bluetooth modulu a standardního 3.5~mm jack audio výstupu. Dalším důležitým předpokladem pro dobré využití chytrého telefonu je dostatek aplikaci, ale o~tom se zmíním až v~sekci č \ref{sec:applikace}.

Operační systém je primárně ovládán přes dotykový displej, jehož dotyková vrstva přesahuje zobrazovací plochu a umožňuje zadávat dotyková gesta (pohyby)\footnote{Z angličtiny Touch gestures -- gesta, Swipes -- pohyby, tahy} pro funkce \uv{zpět} či otevření launcheru. Až do druhé verze systému se počítalo s~druhou vstupní metodou, tedy s~přítomností hardwarové QWERTY klávesnice\footnote{Rozložení se liší podle cílového trhu}. Ta navazuje na precizní klávesnice původních přístrojů Treo od Palmu, průkopníků smartphonů, a i přes relativně malé rozměry se velmi dobře používá. Ve verzi webOS 3.0, která je určena pro tablety bez hardwarové klávesnice, je vstupem pouze dotykový displej se softwarovou klávesnicí.

I~přes neúspěchy na trhu obsahuje systém mnoho pokrokových funkcí, jako třeba nepřekonaný multitasking s~použitím karet reprezentujících aplikace nebo jednoduchý systém notifikací, na který někteří uživatelé nedají dopustit. Vývoj všech mobilních operačních systémů jde rychle dopředu a některé z~úspěšných funkcí postupně pronikají i do jiných operačních systémů.


\section{Aplikace} \label{sec:applikace}
Jak již bylo zmíněno výše, původní koncept byl postavit aplikace pouze na~webových technologiích, kterým rozumí skoro každý, a tak by bylo velmi jednoduché získat mnoho aplikací třetích stran. Ze začátku to vypadalo jako velmi dobrý tah, ale toto rozhodnutí s~sebou neslo několik, na první pohled trochu skrytých, úskalí:
\begin{itemize}
 \item Většina zdrojového kódu je v~nepříliš oblíbeném Javascriptu.
 \item Interpretace Javascriptu je pomalá, což bylo dost znát na prvních telefonech.
 \item Některé věci v~Javascriptu udělat nelze (programování blíže hardware -- i když Palm vytvořil rozhraní pro komunikaci javascriptu se službami operačního systému).
\end{itemize}

I~přesto vzniklo mnoho zajímavých aplikací pro tuto platformu. Ze začátku byly do~tohoto systému vkládány naděje k~záchraně oslabující společnosti Palm, ale firma v~té době neměla rychlé dodavatele a nezvládla distribuci do celého světa. Jelikož trh s~mobilními telefony jde velmi rychle dopředu, dnes (jaro 2013), po čtyřech letech, existuje jen malá komunita uživatelů, kteří tento systém používají a kteří pro~něj vyvíjejí aplikace. Celkový počet aplikací je v~řádech tisíců \cite{wikiWebOS}.

Dokumentace k~vývoji aplikací obsahuje podrobný popis životního cyklu aplikace, který pomáhá vývojáři zorientovat se v~mnoha možnostech spouštění aplikace a v~běhu na pozadí. Také přibližuje přístup ke službám systému. Dále obsahuje seznam bodů, které má dobrá aplikace splňovat, a to jak z~hlediska vzhledového, tak co se týče chování a práce s~pamětí \cite{appChecklist}.

\subsection{Frameworky}
Pro tvorbu aplikací přišel Palm s~Mojo frameworkem, který obsahuje widgety uživatelského rozhraní a základní strukturu aplikace. Widgety uživatelského rozhraní jsou ve formě HTML části pro umístění do DOM\footnote{Document Object Model} a javascriptové inicializace. Toto použití je docela rozvláčné a kvůli tomu s~příchodem nových verzí od HP vznikl nový framework Enyo, který tyto dvě části spojil a umístil do objektu v~Javascriptu. Ten určuje zanořením strukturu a zároveň zajišťuje generování DOM a inicializaci jednotlivých elementů.

Samotný Mojo Framework podporuje tvorbu aplikací podle architektonického vzoru MVC\footnote{Model - View - Controller}. Podle toho jsou také pojmenované výchozí adresáře ve struktuře aplikace.


\subsection{Nativní aplikace}
Jak jsem již výše naznačil, Javascript není všemocný. To si brzy uvědomili i inženýři z~Palmu. Dalším logickým krokem bylo umožnit vyvíjet nativní aplikace. Nativním částem se v~prostředí webOS říká \uv{plugin}. K~javascriptovému SDK bylo přidáno PDK\footnote{Plugin Development Kit}. Tyto aplikace lze psát v~C/C++, využívat SDL\footnote{Simple DirectMedia Layer} pro grafické aplikace a pomocí dalších rozhraní komunikovat se zbytkem systému. Díky tomu bylo na webOS portováno několik her, včetně celosvětově oblíbených Angry Birds \cite{angry_birds}.

\subsection{Hybridní aplikace}
Tyto dva přístupy lze do jisté míry kombinovat a těžit z~výhod obou. Jedná se o~uživatelské rozhraní napsané v~jednom z~výše zmíněných frameworků, tudíž vzhledově nevybočuje z~řady výchozích aplikací a podporuje koncepty dobré aplikace \cite{appChecklist}. Druhou částí aplikace je potom plugin, což je spustitelný soubor napsaný v~C/C++, zkompilovaný pro~architekturu ARM, se kterým může aplikace obousměrně komunikovat. Tento plugin může provádět výpočetně náročnější úkoly nebo obsahovat části již napsané v~tomto jazyce pro~jiné platformy.

%Právě tento koncept jsem vybral pro tvorbu své aplikace. 

\section{Wherigo} \label{sec:platforms}
Wherigo je hra pro zařízení s~GPS, která přenáší virtuální dobrodružství do reálného světa. V~přístroji se odehrává virtuální svět, který je ovládán pomocí GPS a často interaguje s~reálným okolím. V~základu se jedná o~rozšíření Geocachingu, ale lze vytvořit i nezávislé turistické průvodce nebo modifikace různých her (Whack a mole, Battleship, Snakes and ladders).

\subsection{Historie}
Systém byl vyvinut společností Groundspeak v~roce 2008, primárně pro GPS přístroje značky Garmin a pro kapesní počítače s~operačním systémem Pocket PC (Microsoft) \cite{wherigo}. Brzy si získal mnoho uživatelů a začaly vznikat zajímavé hry. Samotný Groundspeak od~vydání prvních verzí mnoho nového neudělal, ale komunita brzy začala tvořit vlastní přehrávače\footnote{častěji používané anglicky \uv{player}} a editory\footnote{z anglického \uv{builder} lze těžko přeložit}. Ze~editorů bych zmínil pouze české URWIGO \cite{urwigo}, ale existujícím přehrávačům se budu věnovat o~trochu více, protože to bude náplní mé práce.

\subsection{Přehrávače}
Přehrávač Wherigo cartridge má za úkol provést hráče fyzickými místy a dodat mu prvky virtuální reality na displeji zařízení. Může uživateli prezentovat virtuální objekty, stopovat čas a požadovat po uživateli interakci formou dialogů a dotazů.

Hlavní obrazovka se skládá ze čtyř částí:

\begin{description}
	\item[Locations] - Místa, kam se může hráč vydat
	\item[You See] - Věci, které hráč vidí v~okolí
	\item[Inventory] - Věci, které má hráč virtuálně u~sebe
	\item[Tasks] - Úkoly, které má hráč splnit, nebo je již splnil
\end{description}

\begin{figure}[ht]
	\centering
	\includegraphics[scale=0.5]{img/emulator}
	\caption{Screenshot oficiálního Wherigo Emulatoru pro Windows s~otevřenou catrdridge \uv{O~třech prasátkách}. Část popisů uživatelského rozhraní lze počeštit.}
	\label{fig:emulator}
\end{figure}

\paragraph{Oficiální přehrávače}
Groundspeak společně s~projektem Wherigo uvedl přehrávače pro~platformu Pocket PC a pro~turistické navigace společnosti Garmin. Tyto přehrávače jsou brány jako referenční, protože jsou stále nejvyužívanější.

\paragraph{openWIG}
Jako první neoficiální přehrávač vznikl projekt openWIG od autora Matejcik \cite{wig_matejcik} (Jan Matějek) z~pražské UK. Na přehrávači začal pracovat již v~roce 2008 a dokázal vytvořit kompatibilní program bez jakékoliv dokumentace a podpory Groundspeaku. Přehrávač je implementován v~Javě, primárně pro mobilní telefony (J2ME), ale knihovnu využil také pro vytvoření desktop verze.

\paragraph{WhereYouGo}
Projekt Wherigo přehrávače pro Android vznikl v~roce 2010 a autorem je Jiří Mlavec z~ČVUT \cite{wig_android}. Aplikace využívá Wherigo knihovnu z~openWIG. Tímto počinem se dostalo Wherigo na velmi rozšířenou platformu.

\paragraph{PiGo, později Wherigo}
Aplikace napsaná pro širokou základnu telefonů, pro přístroje Apple. Konkrétního autora se mi nepodařilo dohledat, ale tato aplikace je vytvořena s~podporou Groundspeaku. 

\paragraph{xmarksthespot}
Implementace Wherigo ve skriptovacím jazyce python pro snadnou přenositelnost a spustitelnost na různých platformách. Aplikace je stále ve vývoji, ale zdrojový kód \cite{pythonWig} mi byl v~mnoha místech inspirací. Autorem je Bas Wijnen z~Německa.









%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Analýza aplikace a návrh}

Úkol vytvořit přehrávač Wherigo cartridgí s~sebou nese mnoho úskalí, stejně jako přenos aplikace na tuto platformu. V~první části vás seznámím se samotnou hrou, se specifickými vlastnostmi platformy a problémy, které je potřeba řešit.

% ostatni implementace

\section{Wherigo cartridge}
Základním stavebním prvkem, který v~této aplikaci od uživatele dostanu, je právě Wherigo cartridge -- binární soubor, unikátní pro každého uživatele, který lze stáhnout z~portálu Wherigo.com a který obsahuje samotnou hru. Konkrétně tedy hlavičku s~metadaty cartridge, hlavní zkompilovaný bytekód jazyka Lua a nakonec další soubory (obrázky a zvuky) související se hrou. Formát cartridge není nikde oficiálně zveřejněn, ale byl zdokumentován tvůrci aplikací na jiné platformy. Pro přehlednost je zde také umístěn jako příloha \ref{app:gwc}.

Soubor je třeba číst s~ohledem na binární obsah a respektovat použité datové typy. Jednotlivé soubory je třeba extrahovat a umístit do adresáře, který bude přístupný z~uživatelského rozhraní, ale neměl by být pro uživatele viditelný z~ostatních aplikací (prohlížeč fotek, hudební přehrávač).

%Soubor cartridge je zpracováván objektem nad vstupním proudem. Objekt řeší základní datové typy dle přílohy, postupně prochází celý soubor, extrahuje soubory uložené v~cartridge. Obsah hlavičky je předáván do databáze uloženáých cartridges.

\section{Databáze her}
Pro rychlý přehled o~uložených cartridgích v~telefonu je dobré mít jednoduchou databázi s~hlavičkami extrahovanými z~cartridgí. Měl by v~ní být příznak o~rozbalení cartridge (extrakce souborů do datového adresáře aplikace), o~aktuálním stavu hry (uložení) a o~případném dokončení. Po odstranění cartridge z~databáze musí být odstraněny také extrahované soubory z~paměti telefonu, aby nedocházelo k~plnění souborového systému.

Uložené cartridge by mělo být možné filtrovat podle typu z~hlavičky (Geocache, TourGuide, Puzzle, Fiction) a podle stavu hry (příznak uložená, dokončená).

Cartridge by se měly automaticky řadit podle vzdálenosti od aktuální pozice. Speciálním případem jsou cartridge typu \uv{Play Anywhere}, které musí být umístěny ve speciálním seznamu, protože nemají zadanou výchozí pozici.

Databázi je potřeba aktualizovat na vyžádání uživatele  nebo jako reakci na událost smazání, uložení nebo dokončení cartridge. 

\section{Komunikace se serverem wherigo.com}\label{sec:wherigo_api}
Výhodou dnešních chytrých telefonů oproti jednoúčelovým navigacím je připojení k~internetu, které je dostupné již téměř všude. Aplikace by tedy měla mít možnost komunikovat se serverem, autorizovat uživatele, vyhledávat on-line nejbližší cartridge, prohlížet zápisy ostatních uživatelů, stahovat do paměti telefonu cartridge a po dokončení umožnit uživateli cartridge odemknout na webu a napsat zážitky z~hry.

Aktuálně (jaro 2013) však portál wherigo.com nemá žádné veřejné API, přes které by s~ním mohly aplikace komunikovat, a proto se ve své práci tomuto bodu věnovat nebudu. Tento bod je zde zařazen pouze pro budoucí možnost rozšíření aplikace.

\section{Uživatelské rozhraní}

Pro tvorbu uživatelského rozhraní mám několik možností. Je možné použít jeden z~dodávaných frameworků:
\begin{description}
	\item[Mojo] Starší, funguje na všech starších přístrojích, ale není již podporován systémem \mbox{openWebOS}, vývoj v~něm je poněkud neohrabaný, jak jsem si vyzkoušel při tvorbě své první aplikace před několika lety.
	\item[Enyo] Nový framework,  kompatibilní s~novějšími přístroji, na starší jde jednoduše doinstalovat, tvorba aplikací v~něm je výrazně jednodušší, protože se učí z~chyb prvního frameworku.
\end{description}

Teoretickou třetí možností by bylo implementovat uživatelské rozhraní přímo v~C++ za~pomocí jiného frameworku, ale zde by byly jasné nevýhody v~uživatelské přívětivosti (jiný vzhled než ostatní aplikace) a jádro problému, který řeším, by se pravděpodobně přesunulo na implementaci uživatelského rozhraní.

Po zvážení těchto ohledů je nejvhodnější možnost použít moderní Enyo framework, který navíc nabízí spustitelnost na jiných platformách.


\section{Lua}
Ze souboru cartridge získáme zkompilovaný zdrojový kód Lua (Lua Bytekód), který stačí interpretovat. Jako interpret je nejjednodušší zvolit oficiální implementaci ze stránky lua.org, která je velice dobře dokumentovaná a otestovaná. Jedná se o~zdrojové kódy v~C, které lze zkompilovat pro cílovou architekturu mobilního telefonu a připojit k~samostatné aplikaci.

Pro spuštění bytekódu z~cartridge je potřeba použít verzi 5.1 namísto aktuální 5.2, protože bytekód není kompatibilní mezi verzemi.

\subsection{Knihovna Wherigo} \label{sec:knihovna}
V dalším kroku je třeba vyřešit tento problém: zdrojové kódy her vyžadují (direktiva \emph{require}) knihovnu Wherigo, ale tato knihovna není nikde veřejně publikovaná.

Pro přehled o~objektech, funkcích a konstantách jsem musel nastudovat soubory generované oficiální aplikací Wherigo Builder, které poskytují základní strukturu knihovny Wherigo. Některé cartridge využívají nestandardní konstrukce, které je potřeba vypozorovat a aplikaci pro ně odladit. Dalším dobrým zdrojem jsou ostatní opensource implementace Wherigo, které jsou zmíněny v~sekci \ref{sec:platforms}.

Tuto knihovnu je potřeba zpřístupnit z~prostředí Lua VM. To lze udělat dvěma způsoby, které se od sebe velmi liší:
\begin{itemize}
	\item Třídy definovat v~C++ a exportovat do prostředí, ve kterém budeme hry spouštět. Tento způsob by přinesl jednodušší přístup k~datům cartridge z~C++, ale mnoho práce s~těsným propojením těchto dvou jazyků.
	\item Třídy definovat v~Lua, z~C++ exportovat pouze funkce ovládající UI, systémové akce a další věci, které nelze v~Lua zpracovat. Takto je implementován emulátor a pravděpodobně také oficiální přehrávače. Toto řešení má také výhodu, že není kvůli každé změně v~knihovně potřeba znovu kompilovat celý projekt.
\end{itemize}

Objekty a funkce, které je třeba implementovat shrnuje příloha \ref{app:library}, podrobněji jsou popsány na přiloženém CD (generováno z~komentářů pomocí LuaDoc).

\subsection{Propojení s~C++}

Propojení jazyka Lua s~C++ lze řešit několika způsoby:
\begin{itemize}
	\item Provést export dat z~C++ (informace v~hlavičce cartridge, nativní funkce) ručně pomocí funkcí Lua C API a ručně také zpracovávat parametry funkcí a návratové hodnoty.
	\item Provést export dat pomocí nějaké knihovny k~tomu určené, což přinese jednodušší práci s~funkcemi, ale potenciálně nižší výkon.
\end{itemize}

Rozhodl jsem se se využít knihovnu LuaBridge \cite{LuaBridge}, která je distribuována pod licencí MIT a která by dokázala zpracovávat i objekty. Já ji používám pouze pro funkce a proměnné ve~jmenných prostorech Env a WIGInternal, které jsou cartridgemi vyžadovány.

\subsection{Události a synchronizace}

Aplikace je událostmi řízená. Mezi nejčastější události patří změna pozice, při které je potřeba přepočítat všechny aktivní zóny a vzdálenosti. Další důležité události jsou start, uložení, ukončení a obnovení cartridge ze souboru. Dále jsou to akce herních objektů zobrazených uživateli. Tyto události mohou ovlivňovat zobrazení v~uživatelském rozhraní.

Události hry (zobrazení zprávy) jsou neblokující a synchronní (zobrazí se ihned, uživatelské rozhraní běží v~nezávislém procesu). Události uživatelského rozhraní (klik na položku v~inventáři) jsou zachyceny funkcemi ve vlastních vláknech a je třeba zajistit jejich synchronní zpracování.

\subsection{Objekty v~Lua}
Programovací jazyk Lua nemá vestavěný koncept tříd. Objekty lze simulovat pomocí tabulek, jak je předvedeno v~článku na serveru Lua users.org \cite{lua_oop}, ze kterého při implementaci vycházím.

Vzhledem k~tomu, že nevytvářím vlastní knihovnu, ale napodobuji již existující pro~požadavky stávajících zdrojových kódů, je potřeba přizpůsobit například názvy konstruktorů, které nejsou standardizované.

Objekt je simulován typem tabulka, který má podobné vlastnosti -- může obsahovat proměnné a funkce. Konstruktor objektu je potřeba simulovat přiřazením metatabulky s~metametodou \verb|__call|, která umožní tabulku volat jako funkci a umožní vrátit nový \uv{objekt}, tedy vlastně opět tabulku. Destruktor v~jazyce Lua nemusíme řešit, protože Lua obsahuje Garbage collector a nepotřebné objekty odstraňuje samovolně. Třídy jsou vytvořeny na~základě techniky prototypů, podobně jako v~jazyce Javascript.

Součástí jazyka je zkrácená forma zápisu metod s~automatickým předáváním instance objektu. Ta nám umožňuje zapisovat \verb|obj:func(p)| na místo \verb|obj.func(obj,p)| při definici i volání objektových metod.

Tabulky objektu musí být nějak označeny, abychom později poznali, že se jedná o~objekt, a abychom dokázali určit, ke které třídě tato instance patří. Pro tento případ je dobré přidat do tabulky položku s~nekolizním názvem (například \verb|_classname|) a vytvořit třídám funkce \verb|made|, které ověří příslušnost objektu k~dané třídě.

\subsection{Metatabulky}

Některé objekty v~knihovně Wherigo se umějí chovat jako čísla (objekty \emph{Distance} a \emph{Bearing}) a lze je přímo porovnávat s~jinými čísly, nebo jinými objekty. K~tomuto účelu existují v~metatabulkách další klíče, které využívám, konkrétně \verb|__eq|, \verb|__lt|, \verb|__le| pro porovnávání a \verb|__add|, \verb|__sub|, \verb|__mul|, \verb|__div| pro použitelné aritmetické operace. Bohužel, nelze definovat funkci převodu na číselný datový typ (tak, jako je pro převod na řetězec použita funkce \verb|__tostring| z~metatabulky) a je třeba definovat všechny tyto možnosti pro korektní chování některých cartridgí, které této možnosti využívají.

Metatabulky dále využívám pro sledování hodnot některých vlastností, které je třeba zaznamenávat, nebo které mohou vyvolat událost, například \verb|OnSetActive|. Používám klíče \verb|__index| a \verb|__newindex|, které jsou volány, pokud je požadován neexistující index pro čtení nebo zápis.

\section{Uložené hry}
Možnost uložení hry je součástí originálního systému. Neoficiální přehrávače řeší tento problém různě, a proto zde mám několik možností:
\begin{itemize}
	\item Následovat standard a ukládat hru do souboru kompatibilního s~oficiálními přehrávači, což vyžaduje zdokumentování struktury souboru, ale umožní odemykání hry tímto souborem na webu wherigo.com.
	\item Provést export celého běhového prostředí virtuálního stroje Lua\footnote{Lua Virtual Machine}, což by bylo datově velmi objemné. Na druhou stranu by byla jistota úspěšného a kompletního obnovení všech, i nestandardních konstrukcí.
	\item Během hry sledovat změny v~objektech globálního prostředí a zaznamenávat pouze tyto změny. Toto řešení by vyžadovalo speciální metatabulky sledující změny vlastností za běhu a ve výsledku bych stejně musel ukládat do nějakého formátu podobného první možnosti. Současně by celý proces hraní byl výpočetně více náročný, i kdyby uživatel hru nakonec neukládal.
\end{itemize}

\subsection{Formát uložených her}
Formát používaný emulátorem a oficiálními přehrávači není nikde popsaný, ale lze jej odhadnout analýzou souboru generovaného emulátorem. Mnoho částí jsou řetězcové úseky (jména vlastností, objektů, řetězcové konstanty), které jsou přímo čitelné, u~dalších částí definujících strukturu lze odvodit jejich význam podle kontextu.

I~přesto, že vycházím z~původní implementace Wherigo, nevyužívám některé vlastnosti využívané oficiálními přehrávači. Pro export je potřeba tyto vlastnosti vygenerovat a pro~načítání je zpracovávat do struktury, kterou používám.

\subsection{Časování ukládání hry}
Problém může nastat, když vyžadujeme uložení hry inicializované funkcí cartridge. V~tuto chvíli by bylo třeba ukládat ještě zásobník volání a hodnoty. Tomuto se lze docela jednoduše vyhnout způsobem, který je naznačen pojmenováním metody objektu cartridge: \verb|RequestSync| neznamená okamžitou synchronizaci (=uložení), ale požadavek na uložení, jakmile skončí aktuální strom volání funkcí.

Takového chování lze jednoduše docílit vložením uživatelské SDL události\footnote{SDL user event} do zásobníku událostí ve chvíli požadavku. Po dokončení předchozího požadavku se již provede uložení z~hlavní programové smyčky, protože lua je volána v~jediném procesu a nevytváří žádná vlákna (v~terminologii Lua: \emph{coroutine}).



% a pro korektní fungování je potřeba předat toto volání jako SDL událost

% toto se mi zda nesmyslne ...
%\section{Chování aplikace}
%Aplikace po spuštění volá funkci \verb|cartridge.OnStart()|.

%Zprávy uživateli jsou řešeny funkcemi pro zprávy: \verb|MessageBox()|, \verb|Dialog()| knihovny \verb|Wherigo|, která volá řetěz funkcí C++ a posílá událost uživatelskému rozhraní.

%Pravidelně je třeba získávat pozici GPS a aktualizovat pozici objektu hráče ve hře. Změna pozice GPS může vést ke vstupu do zóny, nebo jejímu opuštění -- to může ovlivnit předměty zobrazené uživateli a vyvolat události zón, například \verb|OnEnter()|, \verb|OnProximity()|, \verb|OnDistant()|, \verb|OnExit()|.

%Pravidelně je třeba předávat aktuální čas pro aktualizaci časovačů, a pokud některý časovač v vyprší, je třeba provést události časovače \verb|OnTick|.

%Aplikace reaguje na události uživatelského rozhraní a to většinou akce předmětů (pole \verb|Commands|), nebo reakci na klik \verb|OnClick()|.










%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Implementace a spuštění na cílové platformě}

\section{Instalace software pro vývoj}
Prerekvizitou instalace je oficiální vydání Oracle Java Runtime Environment (JRE). Ze~stránek pro vývojáře HP/Palm je třeba dále stáhnout SDK/PDK instalátor. Pro tvorbu spustitelných souborů na ARM architektuře je vyžadován CodeSourcery Toolchain. Tento balík je podporován pouze operačními systémy Windows a Mac OS. Pro instalaci emulátoru je potřeba mít nainstalovaný Virtualbox \cite{palmInstal}.

\section{Příprava zařízení pro vývoj}

\subsection{Aktivace vývojářského módu}
Vývojářský mód lze, na rozdíl od ostatních platforem, odemknout velmi jednoduše. Do univerzálního vyhledávacího pole stačí zadat text \mbox{\texttt{webos20090606}}  nebo Konami kód \mbox{\texttt{upupdowndownleftrightleftrightbastart}} a ve~zobrazené aplikaci \uv{Developer Mode Enabler} přepněte přepínač do polohy On.

Po restartu je přístroj spuštěn v~režimu, který umožňuje instalovat aplikace z~počítače a přistupovat k~chybovým a ladícím výpisům aplikací.

\subsection{Příkazová řádka v~přístroji}
Pro přístup k~příkazové řádce v~přístroji je třeba nainstalovat do telefonu SSH démona, který bude komunikovat přes USB. To lze provést připojením zařízení k~počítači a spuštěním utility z~nainstalovaného vývojového kitu:

\begin{verbatim}
$ pdk-device-install install
\end{verbatim}%$ %

Po restartu získáme přístup přes \verb|putty| (Windows) nebo \verb|novaterm| (Linux, součástí instalace SDK) k~příkazové řádce, kde můžeme spouštět a ladit aplikace přímo na zařízení, například pomocí \verb|gdb| \cite{deviceShell}.

\subsection{Enyo framework pro starší přístroje}
WebOS verze 1.x a 2.x obsahuje aplikace používající framework Mojo. Pro spuštění aplikace využívající Enyo framerowk je potřeba ho doinstalovat, a to buď společně s~aplikací \uv{Maps} z~oficiálního katalogu, nebo jako samostatný balík \uv{Enyo 1} z~Preware.
%Aplikace pro starší přístroje (Pre, Pixi, systém verze 1.x) jsou napsány ve Frameworku Mojo a systém v~základním stavu neobsahuje Enyo framework, který moje aplikace vyžaduje. Ten lze doinstalovat společně s~aplikací \uv{Maps} z~oficiálního katalogu, nebo samostatně jako balík \uv{Enyo 1} z~Preware.

\subsection{Hybridní aplikace pro starší přístroje} \label{sec:compatibility_register}
Starší přístroje obsahují chybu, a proto aplikace napsaná podle tutoriálů nekomunikuje s~pluginem. Jediná zmínka o~řešení je ve zdrojových kódech Enyo\footnote{\url{https://github.com/enyojs/enyo-1.0/blob/master/framework/source/palm/controls/Hybrid.js\#L49}}: Kromě popsaných postupů stačí odeslat událost \verb|__PDL_PluginStatusChange__| s~parametrem \uv{ready} po~dokončení registrace ostatních metod\footnote{Viz. zdroj Engine.cpp, řádky 595 - 602}.



\section{Podpůrné nástroje}

HP podporuje pro vývoj PDK pouze operační systém Windows a Mac, a proto překlad probíhal právě ve virtualizovných Windows, které jsou pro mě dostupnější.

\subsection{Makefile}
Pro sestavení převzatých zdrojových kódů interpretu Lua a vlastního C++ kódu je GNU Makefile nejjednodušší řešení. V~OS Windows je třeba nastavit proměnnou PATH pro~aplikace GNU. V~dodaném Makefile sestavujícím knihovny Lua už stačí nahradit původní nástroje za nástroje z~Code Sourcery a provést křížový překlad\footnote{Z anglického výrazu \uv{Cross compile}}.

Makefile obsahuje cíle pro překlad, zabalení aplikace do *.ipk balíčku, nebo okamžité spuštění na připojeném zařízení. Dále obsahuje přepínač pro překlad a spuštění na lokálním systému pro ladění chyb, úniků paměti a další testování. Dalším přepínačem je odstranění ladících symbolů pro publikaci v~oficiálním katalogu.

Vycházel jsem ze~vzorové implementace na oficiálním vývojářském webu \cite{pdkTutorial3}, tudíž je možné zvolit přepínače překladu specifické pro~různá zařízení, nebo zvolit univerzální pro~všechny platformy s~webOS.

%\subsection{Nástroje palm-*}

%Instalace vývojového SDK kitu přináší několik aplikací pro příkazovou řádku, které jsou využity také v Makefile.

%\begin{description}
%	\item[palm-package directory] Obsah adresáře zabalí do *.ipk balíčku.
%	\item[palm-install package] Provede instalaci *.ipk balíčku na připojené zařízení
%	\item[palm-launch app\_id] Spustí aplikaci podle zadaného app\_id
%	\item[palm-log -f app\_id] Otevře systémový log (/var/log/messages) a v reálném čase vypisuje aktuální logy (alternativa příkazu tail -f /var/log/messages | grep app\_id přímo na zařízení)
%	\item[palm-run directory] Provede všechny výše zmíněné akce
%\end{description}

\subsection{Funkčnost uživatelského rozhraní}

Uživatelské rozhraní aplikace je psáno v~javascriptu, za pomocí frameworku Enyo, a tudíž je možné jeho funkčnost ověřit nezávisle na platformě. Stačí k~tomu webový prohlížeč s~jádrem WebKit. Já využívám otevřený prohlížeč Chromium. Prohlížeč je potřeba spustit s~parametry, které umožní spouštět lokálně uložené skripty a ukládat cookie do počítače uživatele \cite{chrome}:

\begin{verbatim}
chromium-browser --disable-web-security --enable-file-cookies
\end{verbatim}

V~prohlížeči je poté spuštěno celé uživatelské rozhraní, algoritmy lze ladit pomocí vestavěných ladicích nástrojů a kontrolovat chyby. Hledání chyb v~javascriptu je tak mnohem rychlejší a jednodušší než aplikaci pokaždé instalovat na zařízení, spouštět a v~systémovém logu hledat chyby.

Lze simulovat také události specifické pro zařízení, podobně jako v~Emulátoru. \uv{Pohyb zpět}\footnote{z anglického \uv{Back swipe}} lze simulovat klávesou Escape, otevření nabídky aplikace pomocí kombinace kláves \verb|Ctrl + `|. 

Pomocí speciálních funkcí (\verb|enyo.nextTick()| pro simulaci asynchronních odpovědí) a proměnných (\verb|window.PalmSystem| pro detekci spuštění v~zařízení) lze simulovat odpovědi hybridní části aplikace pro ověření funkčnosti částí závislých na nativní části.

\subsection{Analýza souborů s~uloženou hrou}

Pro jednodušší analýzu a porovnání souborů s~uloženými hrami jsem vytvořil jednoduchou aplikaci převádějící soubor GWS (binární formát) do formátu XML, který je lépe čitelný a hlavně porovnatelný pomocí nástrojů příkazové řádky.

Program je pojmenován \verb|gws2xml| a lze sestavit na Linuxu cílem \verb|gws2xml| programu make. Očekává pouze jeden parametr -- jméno GWS souboru. Výsledné XML je posíláno na standardní výstup, který lze jednoduše přesměrovat do souboru. Porovnání lze provést standardními nástroji \verb|diff|. Pro případ hledání rozdílných polí v~uloženém souboru je užitečné soubory řádky seřadit nástrojem \verb|sort|, například takto:

\begin{verbatim}
$ vimdiff <(gws2xml cart.gws.webos | sort) <(gws2xml cart.gws.emu | sort)
\end{verbatim} %$

Pro zajímavost takto generovaný XML soubor je menší, než binární formát GWS.

\subsection{luadec}

Při spouštění bytekódu v~prostředí Lua nelze získat dostatečně podrobné chybové výpisy. Přestože jsem se snažil pracovat s~opensource cartridgemi, občas jsem narazil na~problém u~cartridge, ke které jsem neměl k~dispozici zdrojový kód. Pro odhalení speciálních konstrukcí používaných tvůrci cartridgí naštěstí existuje projekt \verb|luadec| \cite{luadec}, který převádí bytekód opět na zdrojový kód Lua. Transformace není dokonalá, výsledný kód často nejde znovu spustit, ale pro nalezení nestandardních konstrukcí je to dostatečné.

Přeložení a použití je jednoduché, jak je popsáno na výše citované stránce. Pro vstup je potřeba použít soubory *.luac z~pracovního adresáře aplikace v~telefonu nebo v~počítači. Aplikace vyžaduje lua knihovnu a spuštění na kompatibilní platformě vůči cartridge (32bitový operační systém).

\begin{verbatim}
$ luadec cartridge.luac > cartridge.lua
\end{verbatim} %$



\section{Struktura aplikace}

Na obrázku č. \ref{fig:schema} jsou naznačeny datové toky mezi jednotlivými částmi aplikace. V~následujícím textu se pokusím popsat jednotlivé logické celky.

\begin{figure}[ht]
	\centering
	\includegraphics[scale=0.7]{img/schema}
	\caption{Schéma aplikace a datových toků mezi jednotlivými částmi.}
	\label{fig:schema}
\end{figure}


\subsection{Uživatelské rozhraní -- Enyo framework}

Uživatelské rozhraní je postaveno na hlavním objektu \verb|WIGApp|, který obsahuje selektor obrazovek\footnote{v terminologii Enyo: Pane - umožňuje zobrazení různých typů obsahu a přechody mezi nimi} hlavní nabídky -- umožňuje zobrazení seznamu cartridgí, detailu cartridge, nastavení aplikace a zobrazení samotné hry. Soubory s~objekty pro jednotlivé obrazovky jsou umístěny ve složce \verb|enyo|.

Obrazovka samotné hry obsahuje, pro kontrolu opuštění hry, další výběr obrazovek zobrazitelných ve hře -- celkový přehled, detail kategorie a obrazovku s~detailem položky.

Speciálním objektem je \verb|Plugin|, který zajišťuje komunikaci s~nativní částí aplikace.
Dal\-ší objekty řeší zobrazení různých vyskakovacích oken a požadavků na vstup uživatele a výpočet vzdáleností GPS souřadnic pro zobrazení seznamu nejbližších cartridgí.

%\paragraph{Kompas} ???
\paragraph{Navigace v~aplikaci}

Uživatel se v~aplikaci pohybuje pomocí stisku tlačítek, nebo výběrem různých položek v~seznamu. Tímto způsobem je řešeno zanořování do různých selektorů obrazovek\footnote{V názvosloví frameworku Enyo se jim říká \uv{Pane}}. Postupné vynořování je řešeno pomocí události \uv{Back}, která je vyvolána tahem vlevo v~ploše pro gesta\footnote{A anglického \uv{Gesture area}}. WebOS verze 3.x a Open webOS již nezaručuje přítomnost plochy pro~gesta, a proto je na každé obrazovce také tlačítko umožňující vrátit se zpět. Celkový pohled na strukturu obrazovek popisuje obrázek č. \ref{fig:screens}.

\begin{figure}[ht]
	\centering
	\includegraphics[scale=0.6]{img/screens}
	\caption{Schéma obrazovek v~uživatelském rozhraní. 
Tučně jsou zobrazeny výchozí obrazovky selektorů a šipky znázorňují možnost zanořování. Speciální obrazovkou je obrazovka \uv{Preferences}, která je přístupná z~jakékoliv jiné obrazovky přes aplikační menu.}	\label{fig:screens}
\end{figure}


\subsection{Plugin -- C++ aplikace}

Jedná se o~jakési jádro celého projektu, i když může vypadat pouze jako most spojující jednotlivé části. Pro přehlednost je zdrojový kód rozdělen na logické celky do jmenných prostorů, které se starají o~různé úkoly.

Jmenný prostor \verb|Engine| obstarává komunikaci s~uživatelským rozhraním, systémem a předávání jeho událostí do jmenného prostoru \verb|WherigoLib|. Ten se stará o~zpracovávání všech událostí a správu běhového prostředí Lua pro hru. Součástí je jmenný prostor \verb|WherigoLib::Save|, který řeší ukládání hry do souboru a její obnovu. 

Další významnou částí je objekt \verb|Wherigo|, který zpracovává samotný GWC soubor, načítá do svých vlastností parametry hlavičky a zpřístupňuje samostatnou hru mezi jmennými prostory.

Mezi pomocné objekty lze zařadit objekty \verb|FileReader| a \verb|FileWriter|, což jsou objekty nad vstupním nebo výstupním proudem a zpřístupňují metody pro čtení různě dlouhých úseků a jejich korektní převod na datové typy využité v~C++, viz tabulky použitých datových typů v~přílohách \ref{app:gwc} a \ref{app:gws}.


\subsection{Knihovna Wherigo -- Lua}

Knihovna byla vytvořena na základě originální knihovny používané v~emulátoru a některé algoritmy jsou inspirované verzí pro Python \cite{pythonWig}. Jedná se o~samostatný zdrojový soubor \verb|wherigo.lua|. Kromě vyžadovaných objektů, funkcí a konstant (viz sekce \ref{sec:knihovna} a příloha \ref{app:library}) obsahuje také funkce provádějící výpočty, které by bylo složité dělat přes C API knihovny Lua. Především zpracování požadavků a odpovědí uživatelského rozhraní.




\section{Komunikace mezi částmi aplikace}


\subsection{Komunikační kanály mezi Enyo frameworkem a C++}
První rozhraní, které aplikace obsahuje, je mezi uživatelským rozhraním v~Javascripitu a pluginem v~jazyce C++.

WebOS má pro tento problém vlastní knihovnu a funkce, které tuto komunikaci umožňují a zjednodušují jak na straně javascriptu třídou \verb|enyo.Hybrid|, tak na straně C++ hlavičkovým souborem \verb|PDL.h|. Ten mimo jiné definuje způsob komunikace, potřebné metody a konstanty. Požadavky pro hybridní aplikaci lze shrnout do těchto bodů: 

\begin{itemize}
	\item V~javascriptu (Enyo framework):
	\begin{itemize}
		\item Vytvořit novou třídu (kind) \verb|enyo.Hybrid| a určit spustitelný soubor, se kterým se bude komunikovat.
		\item Určit metody, které lze z~pluginu volat.
		\item Implementovat zpracování těchto volání.
	\end{itemize}
	\item V~C++ pluginu:
	\begin{itemize}
		\item Provést inicializaci PDL: \verb|PDL_Init(0);|
		\item Provést inicializaci SDL: \verb|SDL_Init(SDL_INIT_VIDEO);|
		\item Registrovat obslužné funkce pro přijímání volání z~Enyo frameworku.
		\item Oznámit frameworku dokončení inicializace (viz poznámka o~starších zařízeních v~sekci \ref{sec:compatibility_register}).
		\item Přijetí parametrů funkcí z~Javascriptu a alokace paměti. Toto je prováděno ve~vlastním vlákně, a proto je potřeba předat parametry SDL událostí.
		\item Zpracování události v~hlavním vlákně a uvolnění paměti.
		\item Zakódování návratové hodnoty do JSON, pokud je třeba.
	\end{itemize}
	\item V~appinfo.json zveřejnit položku \verb|"plug-ins": true|.
	\item Do výsledného *.ipk balíčku přidat:
	\begin{itemize}
		\item spustitelný soubor plugin (zkompilovaný pro architekturu ARM).
		\item soubor package.properties obsahující nastavení atributů spustitelnosti souboru plugin (\verb|filemode.755=plugin|).
		\item soubor APP\_NAME\_plugin\_appinfo.json (kde APP\_NAME je jméno aplikace z~appinfo.json) obsahující informace o~spustitelné aplikaci (nepovinné).
	\end{itemize}
\end{itemize}

\paragraph{Vybrané komunikační kanály v~mé aplikaci}

\begin{description}
	\item[getCartridges(refresh)] Požadavek UI a odpověď obsahující seznam cartridgí v~datovém adresáři. Odpověď může vzniknout bez závislosti na požadavku.
	\item[openCartridge(filename)] Požadavek UI na otevření cartridge \verb|filename| a asynchronní potvrzující odpověď.
	\item[save] Požadavek UI na uložení hry.
	\item[ClosePrompt] Požadavek cartridge na uzavření hry.
	\item[closeCartridge(save)] Požadavek UI na uzavření  právě otevřené cartridge, parametr \verb|save| značí, zda se má hra uložit, nebo ne.
	\item[deleteCartridge(filename)] Požadavek UI na odstranění souboru cartridge a všech ostatních dočasných souborů uložených v~souborovém systému telefonu.
	
	\item[MessageBox(message, media, button1, button2, callback)] Požadavek cartridge na zobrazení zprávy s~textem \verb|message|, obrázkem \verb|media|, tlačítky \verb|button1|, \verb|button2| a pokud vyžaduje odpověď, je nastavena hodnota \verb|callback| na true a je odeslána odpověď závislá na vybraném tlačítku.
	\item[playAudio(media)] Požadavek cartridge na spuštění přehrávání zvuku \verb|media|.
	\item[GetInput(type, text, choices, media)] Požadavek cartridge na vstup uživatele. Hodnota \verb|type| může nabývat hodnot Text, Number, MultipleChoice. Položka \verb|text| obsahuje otázku zobrazenou uživateli, \verb|choices| je pole možností pro typ MultipleChoice a \verb|media| je zobrazený obrázek. Po potvrzení uživatelem je odeslána asynchronní odpověď.
	
	\item[showScreen(screen, item)] Požadavek cartridge na zobrazení určité obrazovky. Pokud se jedná o~detail, \verb|item| určuje unikátní identifikátor objektu na dané obrazovce.
	\item[showMap(zone\_id)] Požadavek UI na zobrazení mapy okolí se všemi body zóny a asynchronní odpověď.
	\item[updateState(JSONdata)] Pravidelná aktualizace stavu otevřené cartridge do UI. Obsahuje všechna data, která jsou zobrazena uživateli.
	\item[CallbackFunction(event, ObjId)] Požadavek UI pro vykonání události (zvolený příkaz, nebo OnClick událost).
	 
	\item[switchGPS(newState)] Požadavek UI na zapnutí nebo vypnutí automatické aktualizace GPS pozice. Vyžadováno pro testování a může ušetřit baterii při delších přesunech bez vypnutí aplikace.
	\item[setPosition(lat, lon)] Požadavek UI na nastavení pozice. Pro ladicí a testovací účely umožňuje nastavit pozici uživatele a simulovat vstup GPS.
	\item[movePosition(delta\_lat, delta\_lon)] Požadavek UI na posun pozice uživatele pro ladicí účely.
	
\end{description}


\begin{comment}
Konkrétně existují v~mé aplikaci tyto komunikační kanály:

\paragraph{Ve směru k~Javascriptu}
\begin{description}
	\item[getCartridgesResult] Asynchronní odpověď obsahující JSON řetězec s~metadaty cartridgí načtených z~datového adresáře.
	\item[openCartridgeResult] Asynchronní odpověď potvrzující otevření dané cartridge
	\item[MessageBox(message, media, button1, button2, callback)] Požadavek na zobrazení zprávy s~textem \verb|message|, obrázkem \verb|media|, tlačítky \verb|button1|, \verb|button2| a pokud vyžaduje odpověď, je nastavena hodnota \verb|callback| na true
	\item[Dialog(message, media)] Požadavek na zobrazení série zpráv, podobné jako MessageBox
	\item[playAudio(media)] Požadavek na spuštění přehrávání zvuku
	\item[stopSound] Ukončení přehrávání právě hrajícího zvuku
	\item[Alert] Jednoduchý zvukový signál upozorňující na událost
	\item[GetInput(type, text, choices, media)] Požadavek na vstup uživatele. Hodnota \verb|type| může nabývat hodnot Text, Number, MultipleChoice. \verb|text| obsahuje otázku zobrazenou uživateli, \verb|choices| je pole možností pro typ MultipleChoice a \verb|media| je zobrazený obrázek
	\item[ShowStatusText(text)] Požadavek na zobrazení stavové zprávy (nevyužíváno)
	\item[showScreen(screen, item)] Požadavek na zobrazení určité obrazovky, pokud se jedná o~detail, \verb|item| určuje unikátní identifikátor objektu na dané obrazovce
	\item[ClosePrompt] Požadavek na uzavření cartridge
	\item[showMapResponse] Odpověď na požadavek zobrazení mapy okolí se všemi body zóny
	\item[updateState] Aktualizace stavu otevřené cartridge - JSON objekt obsahující všechna data, která jsou zobrazena uživateli
\end{description}

\paragraph{Ve směru k~C++ pluginu}
\begin{description}
	\item[getCartridges(refresh)] Požadavek na seznam cartridgí v~pracovním adresáři. Parametr určuje možnost obnovení seznamu se znovunačtením všech metadat
	\item[openCartridge(filename)] Požadavek na otevření cartridge do Lua prostředí, určené názvem souboru \verb|filename|
	\item[closeCartridge(save)] Požadavek na uzavření  právě otevřené cartridge, parametr \verb|save| značí zda se má hra uložit, nebo ne
	\item[deleteCartridge(filename)] Provede odstranění souboru cartridge a všech ostatních dočasných souborů uložených v~paměti přístroje
	\item[MessageBoxResponse(value)] Odpověď uživatelského rozhraní pro volání callback funkce s~hodnotou jména stisknutého tlačítka \verb|value|
	\item[GetInputResponse(value)] Odpověď uživatele na dotaz vyvolaný správou \verb|GetInput|
	\item[CallbackFunction(event, ObjId)] Volání události uživatelského rozhraní (zvolený příkaz, nebo OnClick událost)
	\item[setPosition(lat, lon)] Pro ladící a testovací účely umožňuje nastavit pozici uživatele a simulovat vstup GPS
	\item[movePosition(delta\_lat, delta\_lon)] Posun pozice uživatele pro ladící účely
	\item[switchGPS] Provede zapnutí, nebo vypnutí automatické aktualizace GPS pozice, což je vyžadováno pro testování, a může ušetřit baterii při přesunech bez vypnutí aplikace
	\item[showMap(zone\_id)] Požadavek na bližší informace o~zóně pro zobrazení v~mapě
	\item[save] Uložení hry inicializované uživatelským rozhraním
\end{description}

\end{comment}

\subsection{Komunikační kanály mezi C++ pluginem a knihovnou Lua}

Další rozhraní, které moje aplikace vyžaduje, je provázání pluginu v~C++ s~třídami v~Lua. Pro propojení funkcí jsem použil koncept podobný Wherigo emulátoru, a to implementaci knihovny v~jazyce Lua a export pouze funkcí, které vyžadují speciální zpracování, nebo požadavek pro uživatelské rozhraní. Tyto funkce jsou sdruženy do jmenného prostoru \verb|WIGInternal|, který používají také oficiální přehrávače.

Volání C++ funkcí ze strany Lua je řešeno pomocí knihovny LuaBridge.

Rozhraní je podobné výše zmiňovanému, ale jsou zde navíc funkce časovače. Funkce popsané výše jsou již vynechány.

\paragraph{Ve směru k~C++}
\begin{description}
	\item[escapeJsonString] Provede ošetření znaků, které nelze přímo serializovat do řetězce JSON. Pro vyšší výkon implementováno v~C++
	\item[RequestSync] Požadavek cartridge na uložení rozehrané hry - vytvoří SDL událost, která je vykonána po dokončení aktuálně prováděného zpracování v~programové smyčce. Tímto je ošetřen problém ukládání zásobníku volání.
	\item[Close] Požadavek na uzavření cartridge, vyžaduje potvrzení uživatele
	\item[addTimer(remaining, ObjId)] Vytvoří nový časovač na \verb|remaining| sekund. \verb|ObjId| je unikátní ID časovače v~cartridge.
	\item[removeTimer(ObjId)] Zruší běžící časovač, zadaný podle \verb|ObjId|
	\item[getTime] Vrací aktuální čas. Pro výpočet zbývajícího času pro opakující se události.
	\item[LogMessage(message)] Posílá zprávu do logu průběhu cartridge
\end{description}


\paragraph{Ve směru k~Lua}
Volání Lua funkcí ze strany C++ je řešeno přes zásobník Lua a funkce C API knihovny. Funkce, které jsou interní, jsou zařazeny také do jmenného prostoru Wherigo knihovny, ale začínají podtržítkem, aby se snížilo riziko kolize s~uživatelem definovanými funkcemi a proměnnými.

\begin{description}
	\item[ZTimer.\_Tick(ObjId)] Událost vypršení časovače
	\item[Wherigo.\_MessageBoxResponse(value)] Reakce uživatele na zobrazení zprávy (vybrané tlačítko)
	\item[Wherigo.\_GetInputResponse(value)] Odpověď uživatele na otázku
	\item[Wherigo.\_callback(event, ObjId)] Událost na objektu (Click, Command)
	\item[Wherigo.\_getUI] Žádost o~data pro zobrazení v~uživatelském rozhraní
	\item[ZCartridge.\_update(position, time, accuracy)] Aktualizace pozice GPS, času a přesnosti
\end{description}

Další přístupy C++ do prostředí Lua a do objektů vlastní hry jsou řešené přes Lua C API. Takto je řešeno získání statických dat hry, která jsou odesílána jako odpověď funkci \verb|openCartridge|, události OnStart a OnRestore, nebo získání dat pro zobrazení mapy. Stejným způsobem je řešen přístup do prostředí Lua při ukládání/obnovování hry ze souboru.



\section{Algoritmy}

\subsection{Sférická geometrie}
Pro práci s~GPS souřadnicemi je potřeba využít algoritmy sférické geometrie. Země sice není přesná koule, ale odchylky od ní jsou minimální a zanedbatelné. Je potřeba počítat s~extrémními případy kolem severního pólu a s~přechodem kolem datové hranice.

%Je velmi málo pravděpodobné, že takováto situace nastane a proto jsem zatím tyto speciální případy neřešil.

\paragraph{Je bod v~zóně?}

Mezi velmi často používané algoritmy patří ověření, zda je hráč uvnitř zóny. Jakýkoliv uzavřený rovinný útvar, jimž zóna definována alespoň třemi body je, dělí kulovou plochu na dvě části a pro korektní výpočet by bylo vyžadováno, aby bylo určeno, jaká část je uvnitř a jaká venku. Zdrojové soubory her obsahují vlastnost OriginalPoint -- jakýsi střed zóny. Ale tento bod není vždy uvnitř zóny (například pro nekonvexní tvary). Kromě toho Emulátory a ostatní přehrávače tento bod ignorují. V~rámci kompatibility s~existujícími hrami mi nezbývá, než se zachovat stejně.

Základním algoritmem, který pro tento úkol používám, je algoritmus Inpoly \cite{inpoly}, který využívá metodu \uv{počtu přechodů}\footnote{z anglického \uv{Crossing Count}}. Hlavní myšlenkou je ověřit, kolikrát se polopřímka vedená z~ověřovaného bodu na sever protne se všemi segmenty zóny. Pokud je tento počet lichý, jsme v~zóně, jinak jsme mimo ni. Algoritmus popsaný ve výše uvedeném článku používá několik optimalizací pro hraniční případy.

Algoritmus bez dalších optimalizací nelze použít pro výpočet zón, které obsahují severní nebo jižní pól, případně které protínají datovou hranici. Tento stav je velmi nepravděpodobný, a proto jsem jej zanedbal. Stejně tak v~tomto algoritmu považuji zemi za plochou, protože většina zón je relativně malá a v~tomto případě je odchylka zanedbatelná.

Dále jsem použil optimalizaci pomocí MBR\footnote{Minimal Bounding Rectangle, speciální případ Bounding box pro dva rozměry}, která ještě před~spuštěním výše uvedeného algoritmu ověří, zda jsme vůbec v~blízkosti této zóny.

\paragraph{Vzdálenost a azimut}
Výpočet nejkratší vzdálenosti a azimutu na kulové ploše není úplně zřejmý, a proto bych jej chtěl zde vysvětlit. Vycházel jsem z~článku \cite{latlong}, který čitelně popisuje problémy a poskytuje vhodné algoritmy.

Výpočet vzdálenosti mezi dvěma body lze řešit několika různými způsoby, ale studium každé metody, výběr nejvhodnější, popřípadě tvorba vlastní metody by zdaleka přesáhly rozsah této práce. Já jsem zvolil metodu \uv{Haversine formula} (nenalezl jsem český překlad), která je využita i ve výše uvedeném článku a je definována takto:

\begin{align}
R &= 6371 \text{ [km]}	\\
a &= \sin^2\left(\frac{\Delta\varphi}{2}\right) + \cos\left(\varphi_1\right) \cos\left(\varphi_2\right) \sin^2\left(\frac{\Delta\lambda}{2}\right)	\\
c &= 2 \text{atan2}\left(\sqrt{a}, \sqrt{1 - a}\right)	\\
d &= R c
\end{align}

Kde $R$ je poloměr Země, $\varphi$ je zeměpisná šířka a $\lambda$ je zeměpisná délka. Důležité je dosazovat úhly/souřadnice v~radiánech.

Algoritmus pro výpočet azimutu v~sobě skrývá také několik překvapení. Prvním je fakt, že azimut se po cestě z~jednoho bodu do druhého po nejkratší cestě mění. Pro naše potřeby stačí určit azimut ve výchozím bodě, protože ten nás povede po nejkratší cestě. Ten je definován takto:

\begin{equation}
\theta = \text{atan2}\left( \sin\left(\Delta\lambda\right) \cos\left(\varphi_2\right),
	\cos\left(\varphi_1\right) \sin\left(\varphi_2\right) - \sin\left(\varphi_1\right) \cos\left(\varphi_2\right) \cos\left(\Delta\lambda\right) \right)
\end{equation}

Vycházíme opět ze zeměpisné šířky a délky $\varphi$ a $\lambda$ v~radiánech. Výsledný azimut je opět v~radiánech.

Za zmínku možná ještě stojí funkce atan2, což je běžná trigonometrická funkce Arkus tangens se dvěma parametry pro určení správného kvadrantu na základě znamének předaných argumentů.

\paragraph{Posun bodu o~danou vzdálenost v~daném azimutu}
Další algoritmus, který je použitý v~knihovně a v~uživatelském rozhraní, je algoritmus offsetu bodu. Vycházel jsem z~výše zmíněného zdroje \cite{latlong}. Použité vztahy vypadají takto:

\begin{align}
\varphi_2 &= \text{asin}( \sin(\varphi_1) \cos(d/R) + \cos(\varphi_1) \sin(d/R) cos(\theta) )	\\
\lambda_2 &= \lambda_1 + \text{atan2}( \sin(\theta) \sin(d/R) \cos(\varphi_1), \cos(d/R) - \sin(\varphi_1) \sin(\varphi_2) )
\end{align}

Kde $R$ je opět poloměr Země, $\varphi$ je zeměpisná šířka, $\lambda$ je zeměpisná délka, $d$ je vzdálenost a $\theta$ je požadovaný azimut.


\subsection{Ukládání a obnova rozehraných her}

Originální Wherigo přehrávače podporují ukládání a obnovování her, což je součástí většiny rozsáhlých her. Pro ukládání souborů využívá Emulátor a Garmin formát GWS, jehož struktura je přiložena jako příloha \ref{app:gws}. Tuto strukturu jsem se rozhodl respektovat a vytvořil jsem kompatibilní soubor.

Z~objektů je potřeba odfiltrovat funkce knihovny Wherigo, které nemá smysl ukládat, a některé vlastnosti, které nejsou v~referenčním souboru potřeba. Naopak některé vlastnosti ve své knihovně nepoužívám, a proto je potřeba tyto vlastnosti pro ukládání vytvořit.

Data jsou zapisována ve formátu, v~jakém je získávám z~Lua C API. Předtím je potřeba přenést proměnné z~globálního jmenného prostoru do pole \verb|ZVariables|, aby byly společně se hrou uloženy. Opačně je potřeba postupovat při obnovování ze souboru.










%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Testování}\label{cha:test}

Testování částí aplikace probíhalo od začátku vývoje, a to v~několika rovinách. Automatizované testy byly použity pro ověření funkčnosti samostatné knihovny, ale nejdůležitější bylo testování v~terénu s~reálnými GPS daty a opravdovými cartridgemi.

\section{Automatizované testy}

Aplikace je rozsáhlá a různorodá, a proto se mi nepodařilo pokrýt touto metodou všechny části. Automatizované testy jsem vypracoval pouze pro část Wherigo knihovny. Testy ověřují možné konstrukce používané v~různých cartridgích a chování funkcí knihovny při určitých akcích. Soubor testů je uložen ve složce \verb|tests/| a lze spustit zadáním argumentu test, spustitelnému souboru:

\begin{verbatim}
$ ./wig test
\end{verbatim} %$

Alternativně lze spustit pouze některé testy zadáním jejich jména ve druhém parametru.


\section{Testy uživatelského rozhraní}

Uživatelské rozhraní nelze otestovat automaticky. Testování spočívalo v~prohlížeči Chromium a na dvou různých telefonech s~různou verzí webOS. Testoval jsem porovnání vůči emulátoru, zda lze provést všechny možné kombinace akcí, zda všechna tlačítka a nastavení reagují. Dále probíhala občasná kontrola vůči jiným aplikacím během terénního testování.

V~porovnání s~emulátorem jsem se dopustil několika významnějších změn, které vedou k~jednoduššímu a rychlejšímu používání, i když mohou někoho zmást.

\begin{itemize}
\item Možnost zobrazit detail položky jediným dotykem z~hlavní herní obrazovky
\item Zobrazení seznamu příkazů položky bez vyžadování stisku dalšího tlačítka
\end{itemize}

Původní systém byl vytvořen pro jiný druh ovládání a na menší displeje. V~dnešní době je na displeji místa dost a rolování obrazovky je velmi intuitivní a rychlé.

\section{Terénní testy}

Asi nejdůležitější částí testování hotové aplikace byly testy v~terénu a ověření chování aplikace v~prostředí, ve kterém má být využita. Během konečné části vývoje jsem se vypravil na většinu Wherigo cartridgí, které jsou v~Brně dostupné, abych ověřil, že je možné jejich bezproblémové dokončení. Dále jsem vyzkoušel několik cartridgí, které je možné hrát kdekoliv\footnote{Například tyto: 
O~třech prasátkách od Siky:\\\url{http://www.wherigo.com/cartridge/details.aspx?CGUID=c885657e-5eab-4958-a1b1-0058e1e48bfb},\\
Whack-A-Lackey od Ranger Fox:\\\url{http://www.wherigo.com/cartridge/details.aspx?CGUID=f6002f33-c68a-4966-82ca-3c392a85d892}\\
Battleship od Ranger Fox:\\\url{http://www.wherigo.com/cartridge/details.aspx?CGUID=9065c3cf-f837-4c50-b418-63a7d9f3b485}}.

\section{Simulace GPS}

Na všechny cartridge se nemohu dostat, a i kdybych mohl, není nejpohodlnější testovat vždy v~terénu. Největší problémy je nejlepší odchytit pomocí simulace u~počítače. Během spolupráce s~tvůrci Wherigo cartridgí jsem dostal doporučení na velmi rozsáhlou a komplikovanou cartridge, Feuersturm über Reutlingen\footnote{Feuersturm über Reutlingen od Charlenni: \\\url{http://www.wherigo.com/cartridge/details.aspx?CGUID=9573732b-2242-413d-a5d5-b33b8b5ba2b6}}, která využívá téměř všech vlastností Wherigo (jak standardních, tak velmi nestandardních), a proto pro mě byla cennou zkušeností.

\begin{figure}[ht]
	\centering
	\includegraphics[scale=.3]{img/simulaceGPS}
	\caption{Snímek obrazovky aplikace.}
	\label{fig:simulace}
\end{figure}

Změna GPS pozice je možná pouze z~obrazovky zóny, nebo objektu, který má definovanou pozici, a tudíž se v~detailu zobrazí kompas a vzdálenost k~cíli, jak je vidět na obrázku č. \ref{fig:simulace}.

Pozici lze ovládat tlačítkem \uv{Move To}, které okamžitě přesune hráče na pozici zóny nebo věci (velmi nepřirozený skokový pohyb, který může některé cartridge zmást), nebo pomocí kláves (v~textovém boxu vpravo dole) \verb|w|, \verb|s|, \verb|d|, \verb|a| pro pohyb po větších krocích a kláves \verb|i|, \verb|k|, \verb|l|, \verb|j| pro pohyb po menších krocích ve směru světových stran (S, J, V, Z), jak je zobrazeno na obrázku č. \ref{fig:klavesnice}\footnote{Zdroj: \url{http://www.productwiki.com/upload/images/hp_pre_3_1.jpg}}.

\begin{figure}[ht]
	\centering
	\includegraphics[scale=.3]{img/keyboard}
	\caption{Simulace GPS pomocí klávesnice}
	\label{fig:klavesnice}
\end{figure}

Simulace je v~publikované aplikaci skryta, protože není součástí hry a hráče by naváděla k~podvádění. Simulaci GPS lze zapnout pomocí konstanty \verb|DEBUG| v~souboru \verb|Wig.js|.










%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Závěr}

Výsledkem projektu je funkční aplikace, která je srovnatelná s~aplikacemi na jiných platformách a která byla otestována na okolních cartridgích. Plánuji pokračovat ve vývoji a rozšířit uživatelské rozhraní o~interakci s~webovým portálem \url{http://www.wherigo.com} (viz sekce \ref{sec:wherigo_api}), což přinese mnohem lepší uživatelskou přívětivost a dokáže plně využít potenciálu Wherigo her na mobilním zařízení. Aplikace je nyní dostupná v~oficiálním katalogu aplikací pod jménem WebWIG \cite{WebWIG}. Zdrojové kódy jsou dostupné v~repozitáři GitHub\footnote{\url{https://github.com/Jakuje/webwig}}.

Rozšířil jsem si znalosti o~programování aplikací pro mobilní zařízení, naučil jsem se pracovat se skriptovacím jazykem Lua, který lze využít pro jednoduché skripty, vkládat do~kompilovaných jazyků a těžit z~výhod jejich kombinace. Naučil jsem se objektově orientované programování v~Lua a při implementaci vkládání do C++ jsem nahlédl pod pokličku Lua VM. Současně jsem si osvěžil znalosti o~C++.

Hlavním problémem, který jsem musel řešit, byla neexistence oficiální dokumentace platformy Wherigo. Často jsem musel dělat pokusy s~emulátorem, porovnávávat binární soubory a sledovat chování aplikace v~různých mezních situacích. Výsledkem mého hledání jsou přílohy k~této práci, které shrnují detaily systému Wherigo, a samotné zdrojové soubory. Dále potom dokumentace samostatné knihovny, která je přiložena na CD. Zjištěné údaje o systému Wherigo mohou být použitelné pro autory přehrávačů na ostatních platformách k zlepšení jejich funkčnosti a kompatibilitiy.

%Závěrečná kapitola obsahuje zhodnocení dosažených výsledků se zvlášť vyznačeným vlastním přínosem studenta. Povinně se zde objeví i zhodnocení z~pohledu dalšího vývoje projektu, student uvede náměty vycházející ze zkušeností s~řešeným projektem a uvede rovněž návaznosti na právě dokončené projekty.



















%=========================================================================
