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@adresa | nahrá súbor do pamäte na danú adresu; program sa tomu miestu vyhne |
--embed súbor.xex | nahrá časti iného .xex tam, kam samy patria (strojový kód, ktorý program volá cez USR) |
--patch adresa=bajt,bajt | zmení bajty v tom, čo --embed nahral |
--file MENO=súbor | pribalí 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:
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 RPreklad a spustenie
Basic26 embed.abas --simČo uvidíš
########
#..$...#
#.##.#.#
#....*.#
########Ako to funguje
- Riadok 0: prekladač pri preklade prečíta
level.datz priečinka programu a vloží ho doembed.xex. Pri nahrávaní programu sa tých 40 bajtov uloží na adresy$9000–$9027. - Riadok 50: program ich číta obyčajným
PEEK. Nemusel nič otvárať ani nahrávať – dáta sú v pamäti skôr, než sa vykoná prvý riadok. - Prekladač vie, že na
$9000niečo leží, a vyhne sa tomu: voľná pamäť preDIMsa rozdelí tak, aby reťazce a polia súbor neprepísali.
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:
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
ž $1AProgram examples/letters.abas si ho pýta voľbou --charmap:
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 I3
97
106Pí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:
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
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:
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:
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 --runProgram 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žia | na adrese, ktorú určíš | v programe, miesto vyberie prekladač |
| typické použitie | znaková sada, strojový kód, obrázok | dobový 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 programu | error B26201: súbor sa nenašiel |
| znaková sada na adrese, ktorá nie je násobkom 1024 | písmená sú rozsypané |
| písmeno s diakritikou v texte a žiadna mapa | warning 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 programu | chyba 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átore | ERROR- 170 – skúšaj v emulátore |
--embed hra.xex vrátane pokynu na spustenie | netreba sa báť: adresu spustenia prekladač vynechá |
Vyskúšaj si
- Zmeň v
level.datmapu (v ľubovoľnom editore, 40 znakov bez koncov riadkov) a preložembed.abasznova. - Prelož
embed.abass voľbou--patch '$9000=65,66'a pozri, čo sa zmenilo v prvom riadku mapy. - Uprav
embed.abas, aby v mape našiel znak$a vypísal jeho riadok a stĺpec.
Zhrnutie
--embed súbor@adresanahrá súbor s programom na danú adresu; program ho číta cezPEEK.--embed súbor.xexpripojí strojový kód iného programu.--patchzmení v pribalenom jednotlivé bajty.--file MENO=súborpribalí súbor, ktorý program otvára cezOPEN.--charmap súborpovie, kde má znaková sada programu písmená s diakritikou;--screen-codesuloží texty tak, ako ich drží pamäť obrazovky.- Voľby patria do
REM @COMPILE, cesty sú od priečinka programu.
Späť: 42. Miesto v pamäti · Ďalej: 44. Skrytá pamäť