43. Pribalené súbory: --embed, --patch, --file

Na čo to je

Hra nie je len program. Patrí k nej znaková sada, obrázok, mapa, hudba, kus strojového kódu. V interpreteri sa to všetko nahrávalo z diskety – zvlášť, po častiach, často zavádzačom, ktorý dnes nikto nemá. Prekladač vie také súbory pribaliť do výsledného .xex: nahrajú sa spolu s programom a program ich nájde tam, kde ich čaká.

Ako sa to píše

VoľbaČo robí
--embed súbor@adresanahrá súbor do pamäte na danú adresu; program sa tomu miestu vyhne
--embed súbor.xexnahrá časti iného .xex tam, kam samy patria (strojový kód, ktorý program volá cez USR)
--patch adresa=bajt,bajtzmení bajty v tom, čo --embed nahral
--file MENO=súborpribalí súbor, ktorý program otvára menom (OPEN #1,4,0,"D:MENO")

Voľby sa dajú opakovať. Patria do hlavičky REM @COMPILE (kapitola 40) – súbory sú súčasťou programu.

Celý program: dáta na adrese

Súbor examples/level.dat má 40 bajtov – mapu miestnosti, päť riadkov po osem znakov:

########
#..$...#
#.##.#.#
#....*.#
########

(V súbore sú za sebou bez koncov riadkov.) Súbor examples/embed.abas ho má pribalený na adrese $9000, desiatkovo 36864:

Atari BASIC
0 REM @COMPILE --embed level.dat@$9000
10 REM A file carried in the program: a map at address $9000
20 A=36864
30 FOR R=0 TO 4
40   FOR C=0 TO 7
50     PRINT CHR$(PEEK(A+R*8+C));
60   NEXT C
70   PRINT
80 NEXT R

Preklad a spustenie

Basic26 embed.abas --sim

Čo uvidíš

########
#..$...#
#.##.#.#
#....*.#
########

Ako to funguje

Znaková sada

Najčastejšie použitie. Znaková sada Atari má 1 024 bajtov (128 znakov po 8 bajtoch) a musí začínať na adrese deliteľnej 1024:

Turbo Basic XL
0 REM @COMPILE --embed myfont.fnt@$9800
10 POKE 756,152:REM 152 = $98, the page the font begins on
20 PRINT "Text in my own letters"

Adresa 756 hovorí Atari, na ktorej stránke pamäte (adresa delená 256) znaková sada leží. Jeden POKE – a celá obrazovka má iné písmo. Tak sú urobené české a slovenské textové hry: písmená s diakritikou sú nakreslené v sade na miestach menej používaných znakov.

Písmená s diakritikou: --charmap

Atari písmená ako č alebo š nemá. Keď ich napíšeš do textu programu, prekladač nevie, na ktorom mieste ich tvoja znaková sada má – urobí z nich otáznik a upozorní na to:

warning B26210: a character ATASCII does not have is a '?' in the program (--charmap says where the program's character set keeps it)

Povedz mu to súborom s mapou znakov. Je to obyčajný text (UTF-8), na každom riadku znak, medzera a jeho kód v sade – desiatkovo, alebo so znakom $ šestnástkovo. Riadok, ktorý sa začína bodkočiarkou, je poznámka. Súbor examples/letters.map:

; letters.map - where the character set keeps the Czech letters
á $01
č $03
ě $05
š $13
ž $1A

Program examples/letters.abas si ho pýta voľbou --charmap:

Atari BASIC
0 REM @COMPILE --charmap letters.map
10 REM Czech letters go where the program's character set keeps them
20 DIM A$(10)
30 A$="čaj"
40 FOR I=1 TO LEN(A$)
50   PRINT ASC(A$(I,I))
60 NEXT I
3
97
106

Písmeno č je v programe jeden bajt s kódom 3 – so znakovou sadou, ktorá má na tom mieste nakreslené č, ho PRINT ukáže správne. Mapa platí pre texty v úvodzovkách aj pre DATA. Smú v nej byť len znaky, ktoré Atari nemá; obyčajné písmená a číslice ostávajú, čím sú.

Text rovno do pamäte obrazovky: --screen-codes

Pamäť obrazovky nedrží znaky v tých istých kódoch ako PRINT (kapitola D): medzera je tam 0 a A 33. Program, ktorý píše na obrazovku sám – cez POKE alebo MOVE –, musí každý znak prepočítať, a to je v BASICu pomalé.

S voľbou --screen-codes uloží prekladač každý text v úvodzovkách už prepočítaný. Celé slovo alebo riadok potom zapíše jeden príkaz:

Turbo Basic XL
T$="Ahoj"
MOVE ADR(T$),DPEEK(88)+40,LEN(T$)

Platí to pre všetky texty v programe naraz. Čo ide cez PRINT alebo ako meno súboru do OPEN, vyjde zle – voľba je pre program, ktorý nič z toho nerobí. DATA ostávajú, ako boli.

Strojový kód z iného súboru

Turbo Basic XL
0 REM @COMPILE --embed engine.xex

Súbor .xex nesie v sebe adresy, kam jeho časti patria, preto sa adresa nepíše. Prekladač z neho vezme všetky časti okrem pokynu „spusti sa“ – spustiť sa má tvoj program, nie pribalený. Tak sa k preloženej hre pripája pôvodný strojový kód (rutiny na zvuk, kreslenie, hudbu), ktorý hra volá cez USR.

Keď má pribalený kód bajt, ktorý v preloženom programe prekáža – napríklad zapína BASIC, ktorý už netreba –, opraví ho --patch:

Turbo Basic XL
0 REM @COMPILE --embed engine.xex --patch $9168=$FF

Súbor, ktorý program otvára

Niektoré programy svoje dáta nečítajú z pamäte, ale zo súboru: OPEN #1,4,0,"D:LEVEL.DAT". Aby si k takému programu nemusel robiť disketu, dá sa súbor pribaliť aj tak. Súbor examples/carried.abas:

Atari BASIC
0 REM @COMPILE --file D:LEVEL.DAT=level.dat
10 REM A file the program opens by name, carried inside it
20 OPEN #1,4,0,"D:LEVEL.DAT"
30 TRAP 90
40 FOR C=1 TO 8
50   GET #1,K:PRINT CHR$(K);
60 NEXT C
70 PRINT
80 GOTO 40
90 CLOSE #1
100 PRINT "That was the whole file"
Basic26 carried.abas --run

Program vypíše tú istú mapu a pod ňu That was the whole file – bez diskety a bez DOS-u. OPEN mena D:LEVEL.DAT číta z pamäte programu; čítanie za koncom je chyba 136 ako pri skutočnom súbore. Pribalený súbor sa dá len čítať; zápis doň je chyba 135. Iné mená idú ďalej na skutočnú disketu, ak nejaká je.

Tento program skúšaj v emulátore: simulátor má vlastné zaobchádzanie so súbormi a pribalený súbor nevidí.

--embed alebo --file?

--embed súbor@adresa--file MENO=súbor
program dátačíta z pamäte (PEEK, USR, POKE 756)otvára menom (OPEN)
kde ležiana adrese, ktorú určíšv programe, miesto vyberie prekladač
typické použitieznaková sada, strojový kód, obrázokdobový program, ktorý si dáta nahráva sám

Súbory sa dajú pribaliť aj do pamäte, ktorú program bežne nevidí – pod operačný systém a do rozšírenej pamäte (--embed súbor@$C000, --embed súbor@1:$4000). O tom je kapitola 44.

Časté chyby

Čo sa staloČo sa stane
súbor nie je v priečinku programuerror B26201: súbor sa nenašiel
znaková sada na adrese, ktorá nie je násobkom 1024písmená sú rozsypané
písmeno s diakritikou v texte a žiadna mapawarning B26210, v programe je namiesto neho ?
v mape je obyčajné písmeno (a $01)error B26200: mapa je len pre znaky, ktoré Atari nemá
--screen-codes a PRINT "TEXT"na obrazovke sú iné znaky – text je v kódoch pamäte obrazovky
adresa zasahuje do kódu programuchyba prekladu ako pri --reserve (kapitola 42)
adresa zasahuje do obrazovky ($BC40 a vyššie)súbor sa prepíše pri prvom výpise
program s --file v simulátoreERROR- 170 – skúšaj v emulátore
--embed hra.xex vrátane pokynu na spustenienetreba sa báť: adresu spustenia prekladač vynechá

Vyskúšaj si

  1. Zmeň v level.dat mapu (v ľubovoľnom editore, 40 znakov bez koncov riadkov) a prelož embed.abas znova.
  2. Prelož embed.abas s voľbou --patch '$9000=65,66' a pozri, čo sa zmenilo v prvom riadku mapy.
  3. Uprav embed.abas, aby v mape našiel znak $ a vypísal jeho riadok a stĺpec.

Zhrnutie

Späť: 42. Miesto v pamäti · Ďalej: 44. Skrytá pamäť