sobota 27. listopadu 2004

AnimAce - díl čtvrtý: Na hranicích animace

autor: George K.


4.1 Maskovaný Joe

Pamatujete se, jak jsem v prvním dílu (1.2.3) říkal, abyste si schovali obrazovku? Teď přišla ta pravá chvíle opět ji vytáhnout a trošku poupravit. K dvěma starým pozicím Joa přidámě několik nových, aby chůze byla plynulejší... takže začneme pěkně od levého okraje kreslit to, co vidíte tady vedle - pozor na dvě věci: 1) výška Joa vzrostla z 16 bodů na 17 (nad kloboukem přibyl prázdný řádek); 2) pozice kreslete těsně pod sebe (mezi hlavou a nohama zůstane 1 volný řádek, masky budou přiléhat k sobě). Malé čárky po stranách obrazu jsou čistě jen kůli orientaci (po osmi bodech); kreslení si poněkud zpříjemníme nastavením Attrs/Trasparent a Misc/Bright grid 1 (v ART studiu samozřejmě).
Postavičky představují fáze Joa v chůzi (všimněte si, že ruka se houpe na obě strany - dopředu i dozadu, ne jako např. u Manic Minera, kde jsou pouhé tři fáze a pak to při pohybu vypadá, že chodí neustále pravou (nevylučuji ani levou) nohou dopředu..., pozice za sebou následují v tomto pořadí: 1, 2, 3, 4, 1, 5, 6, 7 a tak pořád dokola. (Pro ty, kteří minule nedávali pozor připomímám, že ten černý flek vpravo je maska a že jí musí obkreslit se stejnou chutí jako Joa.)
Aby nám grafika vůbec k něčemu mohla posloužit, musíme ji v nějaké rozumné formě uložit do paměti, takže až skončíte s kreslením, nahrajte nějaký assembler (nejraději Prométhea protože na něm byl následující program odladěn a vy si tak ušetříte spoustu problémů při zjišťování, proč to jinde přesně takhle nefunguje) a opisujte...
Program CONVERT převádí postavičky z obrazovky do paměti. Použijeme ho následovně: program pouze přeložíme (ASSEMBLY) a vyskočíme do BASICu (BASIC). Nahrajeme obrazovku s panáčky (LOAD [*]"JménoObr"SCREEN$) a spustíme konvertor (PRINT USR 45e3). V levém horním rohu obrazovky by mělo být číslo 60476, z kterého můľete usoudit, že délka dat je právě 476 - pro jistotu si je uložíme SAVE [*]"Joe"CODE 6e4,476]. Co vlastě program udělal? Od adresy 60000 uložil po řádcích všechny masky, ale mezi každým bajtem nechal jednu mezeru (zdvojená instrukce - inc ix) - masky tedy leží na sudých adresách. Na liché adresy (počínaje 60001) byly uloženy pozice Joa (také po řádcích), takže jsme získali řádkově organizované sprajty a klidně se můžeme vrátit do assembleru (GO TO 1) a celý program spustit (RUN).
Ještě jednou upozorňuji, že program se spouští na adrese START (dáno pseudoinstrukcí - ent START) a ta není 4500, ale o něco víc! Kdo program dobře opsal, tomu se po obrazovce celkem plynule prošel Joe. A to je vše. Pozn.: Čísla označená ve výpisu xx lze v rozumné míře měnit, aniľ by to program nějak iritovalo, nebo to vedlo k jeho (nervovému) zhroucení.
org 45000  ;překládej od adr. 45000
 ent START  ;preogram se spouští od adr. START

DATA equ 60000  ;kam ukládat grafiku
HI equ 17  ;výška sprajtu (v bodech)
WI equ 2  ;šířka sprajtu (ve znacích)
P equ DATA  ;první pozice leží na počátku dat
        
CONVERT ld hl,#4002 ;adresa první masky ve videoram
 ld ix,DATA  ;a odsuď se začnou ukládat
 ld bc,7*256*HI*WI ;b=7*hi (7 pozic pod sebou), c=WI (šířka)
 push bc  ;schovej pro příště
 call C01  ;ulož všechny masky
 pop bc  ;obnov rozměry
 ld hl,#4000 ;adresa první figurky ve videoram
 ld ix,DATA+1 ;a odsuď se začnou ukládat

C01 push bc  ;uschovej výšku
 push hl  ;a adresu ve VRAM
 ld b,c  ;do b dej šířku sprajtu
C02 ld a,(hl)  ;přečti byte z VRAM
 ld (ix+0),a ;a ulož ho do paměti
 inc hl  ;posuň se na následující byte
 inc ix  ;ale v paměti ukládej
 inc ix  ;"ob jedno"
 djnz C02  ;opakuj podle šířky (v našem případě 2x)
 pop hl  ;obnov adresu VRAM
 call NEXTHL  ;a jdi o jeden mikrořádek níž
 pop bc  ;obnov ukazatel výšky
 DJNZ C01  ;a pokud není 0 tak opakuj ukládání
 dec ix  ;ukazuj na 1. volný byte za grafikou (přiřaď bc=ix,
 ld b,hx  ;aby při volání z basicu (PRINT USR 45000) byla
 ld c,lx  ;tato hodnota vytištěna
 ret   ;vrať se

NEXTHL inc h  ;posuň se o jeden mikrořádek
 ld a,h  ;a pokud nedošlo k překročení
 and 7  ;osmi mikrořádek (tj. jednoho řádku),
 ret nz  ;tak se vrať
 ld a,l  ;jinak je nutno ošetřit
 add a,32  ;vstup na další řádek,
 ld l,a  ;a když to stačí,
 ret c  ;tak se vrať
 ld a,h  ;ale pokud byla překročena hranice mezi třetinami,
 sub 8  ;tak ještě správně dopočítej adresu a pak se vrať
 ld h,a  ;pozn.: znáte-li organizaci videoram, tak pro Vás
 ret   ;tento podprogram asi nebude takovou záhadou
 
;----------------------------
START ld iy,23610
 ld a,63
 ld i,a
 im 1
 ei

 ld hl,#4000
 ld de,#4001
 ld bc,#17ff
 ld (hl),-1
 ldir

 call INIT

 ld b,80
GOES push bc
 call WAIT
 call BACK

 ld de,DIRECT
POSIT ld hl,DIRECT
GOO ex de,hl
 ld a,(de)
 inc de
 or a
 jr z,GOO
 
 ld (POSIT+1),de
 ld b,a
 and 127
 ld hl,TABLE-2
 add a,a
 add a,l
 ld l,a
 ld a,h
 adc a,0
 ld h,a
 ld e,(hl)
 inc hl
 ld d,(hl)
 ld (GO2+1),de
 ld hl,(DR0+1)
 bit 7,b
 jr z,GO1
 inc hl
GO1 call HIDE
GO2 ld hl,0
 call DRAW
 pop bc
 djnz GOES
 ret

WAIT ld b,5
WAI halt
 djnz WAI
 ret
INIT ld hl,DIRECT
 ld (POSIT+1),hl
 ld hl,#4022
 call HIDE
 ld hl,P+0
DRAW ld bc,256*HI+WI
DR0 ld de,0
DR1 push bc
 push de
 ld b,c
DR2 ld a,(de)
 and (hl)
 inc hl
 or (hl)
 inc hl
 ld (de),a
 inc de
 djnz DR2
 ex de,hl
 pop hl
 call NEXTHL
 ex de,hl
 pop bc
 djnz DR1
 ret

HIDE ld bc,2*HI
 ld de,SPACE
 ld (DR0+1),hl
 jr HI1
HI0 dec hl
 dec hl
 call NEXTHL
HI1 ldi
 ldi
 jp pe,HI0
 ret

BACK ld bc,2*HI
 ld hl,SPACE
 ld de,(DR0+1)
 jr BA1
BA0 dec de
 dec de
 ex de,hl
 call NEXTHL
 ex de,hl
BA1 ldi
 ldi
 jp pe,BA0
 ret

DIRECT defb 2,3,4,128+1,5,6,7
 defw 128+1,0
TABLE defw P,P+68,P+136
 defw P+204,P+272,P+340
 defw P+408
SPACE defs 34
(pokračování příště)