Krátký kurs editace pozic 3

Dostal jsem několik dopisů žádajících, abych výklad zpomalil a některé pojmy a metody vysvětlil důkladněji a na více příkladech. Pokusím se splnit nejdříve tyto žádosti a výklad komplikovanějších technik odložíme na později. Třetí díl bude tedy rekapitulací předchozích dvou dílů. Pokusy budeme tentokrát provádět na hře Wizardry Gold.
Dostal jsem několik dopisů žádajících, abych výklad zpomalil a některé pojmy a metody vysvětlil důkladněji a na více příkladech. Pokusím se splnit nejdříve tyto žádosti a výklad komplikovanějších technik odložíme na později. Třetí díl bude tedy rekapitulací předchozích dvou dílů. Pokusy budeme tentokrát provádět na hře Wizardry Gold.

Kupodivu mě nejvíce lidí žádalo, abych vysvětlil převody mezi číselnými soustavami, i když se tímto problémem zabývá řada knih o programování. Toto mě přesvědčilo, že tato problematika není zdaleka tak samozřejmá, jak by se na první pohled mohlo zdát. Základ číselné soustavy (V „počítačovém světě“ se nejčastěji používá základ 2 a 16, zřídkakdy i 8, běžně počítáme s čísly se základem 10.) vyjadřuje, kolik různých číslic využíváme k zápisu číslic (Ve dvojkové soustavě máme pouze číslice 0 a 1, v desítkové soustavě máme číslice 0 až 9. Všimněme si tedy, že v DVOJkové soustavě neexistuje číslice 2 stejně jako v desítkové k zápisu čísla deset potřebujeme dvou číslic. Tento jev může být někdy matoucí. Poznamenejme také, že pokud nám scházejí symboly pro zápis všech číslic, použijeme písmena latinské abecedy. Tedy v šestnáctkové soustavě zapíšeme číslici „deset“ jako A a číslici „patnáct“ jako F.). Současně to znamená i základ mocniny při přepočtu do a z soustavy. Uvědomme si, že

1589 (desítkově) = 9*10^0 + 8*10^1 + 5*10^2 + 1*10^3

tedy při přepočtu čísla z libovolné soustavy do desítkové soustavy můžeme postupovat právě tímto způsobem: číslo rozložíme na číslice, vytvoříme dílčí výsledky (číslice)*(základ soustavy)^(pořadí číslice zprava počínaje nulou) a tyto dílčí výsledky sečíst. V tabulce naleznete několik příkladů přepočtu do desítkové soustavy:

Číslo Základ zdrojová soustava Přepočet Výsledek (desítkově)
641 7 1*7^0 + 4*7^1 + 6*7^2 323
10110 2 0*2^0 + 1*2^1 + 1*2^2 + 0*2^3 + 1*2^4 22
1C5 16 5*16^0 + 12*16^1 + 1*16^2 453
M1P 30 23*30^0+1*30^1+ 26*30^2 23453
Při přepočtu z desítkové soustavy do jiné soustavy postupujeme následovně: číslo dělíme základem nové soustavy. Zbytek si zapíšeme (pomocí číslic v cílové soustavě) a výsledek opět dělíme tak dlouho, až bude roven nule. Zbytky zapíšeme v opačném pořadí a dostaneme výsledek.

Příklad: Přepočet 1260 do šestnáctkové soustavy:

Číslo Operace Výsledek Zbytek Zapíšeme si
1260 1260 / 16 78 12 C
78 78 / 16 4 14 E
4 4/16 0 4 4
Zpětným přepočtem zjistíme, že 4EC šestnáctkově je opravdu 1260 desítkově.

Příklad: Přepočet 300 do dvojkové soustavy:

Číslo Operace Výsledek Zbytek Zapíšeme si
300 300 / 2 150 0 0
150 150 / 2 75 0 0
75 75 / 2 37 1 1
37 37 / 2 18 1 1
18 18 / 2 9 0 0
9 9 / 2 4 1 1
4 4 / 2 2 0 0
2 2 / 2 1 0 0
1 1 / 2 0 1 1
Opět zjistíme, že 100101100 dvojkově se opravdu rovná 300 desítkově.

Nyní dokážeme provést přepočet z libovolné soustavy do desítkové soustavy a z desítkové soustavy do libovolné soustavy. Propojením těchto dvou přepočtů dokážeme převést číslo z libovolné do libovolné soustavy. Tento postup je sice univerzální, ale v některých případech lze použít i časově úspornější metodu. Při převodu z dvojkové do šestnáctkově soustavy postupujeme takto: rozdělíme číslo na skupinky po čtyřech číslicích (popřípadě doplníme zleva nulami), ty převedeme (můžeme se posloužit následující tabulkou) a pak číslo zpátky spojíme.

Dvojkově Šestnáctkově
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 A
1011 B
1100 C
1101 D
1110 E
1111 F
Příklad: číslo 1110100101011010101011 dvojkově převedeme do šestnáctkové soustavy. Rozdělíme na skupinky, doplníme nulami: 0011 1010 0101 0110 1010 1011, ty převedeme dle tabulky: 3A56AB.

Při převodu z šestnáctkové do dvojkové soustavy převedeme postupně jednotlivé číslice do dvojkové soustavy (dle předchozí tabulky) a ty pak spojíme.

Příklad: číslo FE2C šestnáctkově převedeme do dvojkové soustavy. Převedeme postupně jednotlivé číslice: 1111 1110 0010 1100 a spojíme dohromady: 1111111000101100.

Převod z a do osmičkové soustavy je stejný ale tvoříme skupinky po třech dvojkových číslicích.

Proč vlastně operujeme nejčastěji s čísly v dvojkové a šestnáctkové soustavě a ne v desítkové jak jsme zvyklí z běžného života? Je to dáno konstrukcí počítačů, pro které je dvojková soustava nativní. Celý počítač je založen na operacích v boolovské logice, které jsou realizovány pomocí hradel. Ta jsou zase konstruována na základě tranzistorů (ať už řízených proudem či polem/napětím) ve funkci spínače, které mají právě dva stavy- rozpojeno a sepnuto. A šestnáctkový systém je pouze zkrácenou formou zápisu dvojkového systému.

Dále je třeba upozornit, že tímto způsobem lze převádět i záporná čísla (třeba –10 desítkově by bylo –A šestnáctkově) ale tímto způsobem bychom získali číslo v přímém kódu, zatímco v počítačích se záporná čísla (respektive čísla, která můžou nabývat i záporných hodnot) reprezentují v doplňkovém kódu, což bylo popsáno v první části kurzu. Převádět lze snadno i čísla s plovoucí řádovou čárkou. Pokud si uvědomíme, že

0,257 = 2*10^(-1)+ 5*10^(-2)+ 7*10^(-3),

způsob převodu již snadno odvodíme. Musíme si při tom ale uvědomit, že číslo z konečným desetinným rozvojem (no dobře, správně by mělo být řečeno n-inným rozvojem, kde n je základem číselné soustavy) může mít v jiné soustavě rozvoj nekonečný. Třeba 0,1 desítkově je rovno 0,0001100110011… dvojkově. Tímto převodem se zde ale zabývat nebudeme, protože jej v praxi nepoužijeme – v počítačích se používá jiných způsobů zápisu čísel s plovoucí desetinnou čárkou (pomocí mantisy a exponentu).

Použití kalkulačky z Windows pro přepočty mezi soustavami je poněkud nepohodlné a zdlouhavé. Napsal jsem pro tento účel jednoduchý nástroj –programátorskou kalkulačku. Tentokrát se jedna o aplikaci pracující v prostředí Windows. Za cenu příjemného ovládaní je třeba zaplatit velikosti programu (160 kb) a nefunkčností v DOSu. Ke stažení zde.

Nyní si ještě zopakujeme čísla v doplňkovém kódu. Vše si můžeme představit jako mechanické počítadlo ve starých magnetofonech nebo počítadlo kilometrů na tachometru (pro naše účely předpokládejme, že naše počítadlo má šestnáct číslic 0 až F, a že je dvojmístné). Pokud přetáčíme naše počítadlo dopředu získáme normálně čísla tak, jak jsme na ně zvyklí (v přímém kódu). Pokud ale přetáčíme na opačnou stranu zjistíme, že po přetočení o jeden krok ze stavu počítadla 00 získáme FF. Pokud bychom měli čtyřmístné počítadlo, získali bychom FFFF. To je charakteristické pro doplňkový kód: minus jednička je reprezentována jako řada jedniček (která vyplní celou mřížku) v dvojkové soustavě nebo řada číslic F v šestnáctkové soustavě. Pokud dále přetáčíme naše počítadlo, bude na něm hodnota opravdu klesat. Jistě si uvědomíme, že někde musí být mez přetáčení, že na dvoumístném počítadle by 90 mohlo znamenat 144 nebo –112 podle toho, na kterou stranu jsme přetáčeli. Proto se dohodneme, že čísla z rozsahu 1 až 127 (tedy 00 až 7F na počítadle) budou kladná, čísla z rozsahu 128 až 255 (tedy 80 až FF na počítadle) budou záporná ( a budou znamenat –1 až -128 ) a nula zůstává nulou. Samozřejmě na čtyřmístným počítadle budou rozsahy 0000 až 7FFF resp. 8000 až FFFF. Díky tomu zjistíme, že číslo 90 na dvojmístném počítadle patří do oboru záporných čísel, a tedy jednoznačně znamená -112. Toto přirovnání snad dostatečně vysvětluje, proč výsledek odečtení jedničky od nuly je závislý na rozsahu (na počtu kroužků počítadla), na což bylo nejvíce dotazů.

Teď se už konečně můžeme vrhnout na editaci nějaké pozice. Zvolil jsem pozici ze hry Wizardry Gold. Tato výborná RPG hra má relativně přehlednou pozici a jistě bude velmi podobná jako pozice z původní hry Wizardy 7, která vyšla (plná verze) na SCORE CD. Pozice je ke stažení zde. Postavy mají jména 1111111 až 6666666 pro jejich snadnější identifikaci v souboru. Nejdříve rozdělíme pozici na bloky. Řetězec 11111111 nalezneme na adrese 2A44 a tam budeme hledat i ostatní hodnoty týkající se této postavy. Další postavy nalezneme na adresách 2C8C, 2ED4, 311C, 3364 a 35AC. Celý blok informací o postavě má tedy 584 (dec) bajtů a tuto délku má i poslední postava (37F3-35AC), což nasvědčuje tomu, že blok informací o postavě opravdu začíná jménem. Jako základ pro relativní adresy tedy zvolíme adresu prvního písmene postavy. Kdyby se poslední blok jevil jako kratší, tak by zřejmě některé informace o postavě byly zaznamenány i před jménem. Bázovou adresu bychom volili stejně, ale některé údaje by měly záporné relativní adresy. Pro editaci je ale dobré vědět, kde se blok začíná a kde konči, abychom neměnili hodnoty jiné postavy než té, kterou ve hře sledujeme. Nyní si opíšeme důležité hodnoty první postavy a pokusíme se je najít ve hře:

Význam Hodnota
STR 17
INT 6
PIE 11
VIT 14
DEX 9
SPD 8
PER 8
KAR 3
HP 11/11
EXP 62
Okamžitě vidíme maximální a aktuální hodnotu HP na adresách +18 a +20 (dvoubajtové hodnoty). STR, INT až KAR jsou trochu dále – na adresách +170 až +177. Wizardry je v zásadě hrou založenou na AD&D pravidlech, takže všechny tyto vlastnosti bychom měli měnit jen v rozsahu 1 až 18 (dec); jen zcela výjimečně můžou postavy dosáhnout až 21 (dec). Pokud do pozice zapíšeme příliš vysoké hodnoty, hra se odmítne načíst nebo se bude chovat nestabilně. Tohoto pravidla se držme vždy – používejme jen hodnot, které se ve hře můžou opravdu vyskytnout. Pokud budeme pozorně sledovat blok na adresách +178 až +193 (u dalších povolání i dále) a sledovat korelaci s hodnotami ve hře, zjistíme, že se zde nalézají hodnoty dovedností (mezi nimi jsou i „tajné“ dovednosti power strike, firearms, snake speed, mind control a reflextion). Opět budeme dbát na to, že se jedná o procentuální hodnoty a tady maximem je 100 (dec) neboli 64(hex). Zde nalezneme krásný příklad toho, že nic se nemá přehánět. Pokud dáme všude hodnotu 100 nebudeme mít po překročení úrovně kam přidělit body a zůstaneme viset v mrtvém bodě. Zkušenost najdeme na adrese +C (čtyřbajtová hodnota). Tímto jsme vyčerpali nejdůležitější hodnoty. Rád bych připomněl, že v této hře si můžete měnit povolání, takže si můžete vypěstovat opravdu kvalitní postavičky.

Ještě si trochu zopakujeme metodu změn a sledování výsledků ve hře. Zde máme, oproti Diablu, zjednodušenou situaci, protože máme šest postav, a tak můžeme sledovat buď šest veličin najednou nebo šest hodnot jedné veličiny. Všimneme si, že každá postava má na adrese +26 hodnotu 1. Postavu 1111111 necháme, postavě 222222 tuto hodnotu změníme na 2 atd. Ve hře pak zjistíme, že se jedna o hodnotu vyjadřující, kolikrát se postava už narodila (Nebo zemřela +1. Ve hře Wizardry se postavy oživují docela běžně.). Podobně můžeme postoupit s adresou +24 a zjistíme, že se jedná o úroveň.

Domácí úkol (pro majitele wizardry): Najděte kde je uložena mana pro jednotlivé kategorie, věk, zlato, rasa, povolání, kouzla a další hodnoty. Prostě pokuste se analyzovat význam každého bajtu v bloku informací o postavě.

To je prozatím vše. V této části jsme si zopakovali přepočty mezi soustavami, doplňkový kód a dvě metody editace hodnot – metodu přímého hledání a metodu hledání pomocí změn. V příští části se už snad konečně dostaneme ke kódovaným pozicím a ukážeme si, jak si poradit s dlouhými pozicemi, kde se mění příliš hodně hodnot než abychom mohli jednoduše pomoci FC vysledovat změny nebo najít nějakou konkrétní hodnotu (bude se v pozici opakovat víckrát). Ukážeme si také, že občas je užitečné kouknout se i do .exe souboru… Pokud ovšem vše nezmění vaše dotazy, jako se tomu stalo tentokrát. Jen o jedno vás žádám – vypisujte své dotazy sem do diskusního fóra, aby si mohlo odpovědi případně přečíst více čtenářů s podobnými otázkami.

Váš názor Další článek: Vyzývám vás na souboj, mravenci!

Témata článku: , , , ,