home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #7
/
amigamamagazinepolishissue1998.iso
/
magazyn_amiga
/
1196
/
039_asembler
< prev
next >
Wrap
Text File
|
1998-03-26
|
6KB
|
335 lines
-------------Proszë zîoûyê dwuszpaltowo----------------------
GRAFIKA NA EKRANIE
<a>Bartek Pampuch
<txt>Zanim przejdziemy do naszej lekcji, kilka wyjaônieï:
*1* program z odcinka "Intuition cz. 1. Ekrany" nie zamykaî
otwartego przez siebie ekranu. Aby to robiî, naleûy dopisaê:
<l>
move.l OSA,a0
jsr _LVOCloseScreen(a6)
<txt>przed:
<l>
jsr _LVOWBenchToBack(a6)
NieMaEkranu:
<txt>
*2* Zapis:
<l>
MojImage: dc.w 0,0,640,256,3,0,0,2,0
<txt>jest bîëdny, poniewaû nie wszystkie pola struktury typu
Image sâ sîowami. Poprawny zapis wyglâda:
<l>
MojImage: dc.w 0,0,640,256,3
dc.l 0
dc.b 0,2
dc.l 0
<txt>
*3* UWAGA! BARDZO WAÛNE! Przypadkiem wkradî sië bîâd dotyczâcy
pobierania RastPortu ekranu. W zwracanej (przez _LVOOpenScreen)
strukturze typu Screen znajduje sië kopia RastPortu. Zatem pod
adresem OSA+$54 nie ma adresu RastPortu, ale sam RastPort.
Dlatego zamiast:
<l>
move.l OSA,a0
move.l $54(a0),RastPort
<txt>naleûy wpisywaê:
<l>
move.l OSA,a0
add.l #$54,a0
move.l a0,RastPort
<txt>Jeôli natomiast chodzi o RastPort okienka, poprawny jest
sposób podany na poprzedniej lekcji.
Skoro juû poprawione zostaîy bîëdy z poprzedniej lekcji, moûemy
powróciê do dzisiejszego tematu.
Na poczâtku -- kod úródîowy z wykorzystaniem DrawImage:
<l>
INCDIR DF0:
INCLUDE moj_dos.i
INCLUDE moj_intui_1.i
_LVOOpenLibrary = -552
_LVOCloseLibrary = -414
; kod otwierajâcy bibliotekë DOS
; i zapisujâcy jej adres pod DosBase
; otworzenie biblioteki INTUITION
; i zapisanie jej adresu pod IntBase
...
move.l IntBase,a6
lea MyScreen,a0
jsr _LVOOpenScreen(a6)
tst.l d0
beq.w NoScreen
move.l d0,OSA
jsr ClearScreen ; wywoîanie naszej procedury
move.l DosBase,a6 ; odczekanie
moveq #50,d1 ; jednej
jsr _LVODelay(a6) ; sekundy
move.l IntBase,a6
move.l OSA,a0 ; zamkniëcie
jsr _LVOCloseScreen ; ekranu
NoScreen:
; kod zamykajâcy bibliotekë intuition
...
rts
ClearScreen: ; nasza procedura
move.l OSA,a0
add.l #$54,a0 ; w A0 - RastPort ekranu
moveq #0,d0
moveq #0,d1
lea MyImage,a1
jsr _LVODrawImage(a6)
rts
Image:
dc.w 0,0,640,256,3
dc.l 0
dc.b 0,1
dc.l 0
DosName: dc.b 'dos.library',0
DosBase: ds.l 1
IntName: dc.b 'intuition.library',0
IntBase: ds.l 1
OSA: ds.l 1
MyScreen:
dc.w 0,0,640,256,4
dc.b 0,2
dc.w HIRES ; HIRES=$8000
dc.w CUSTOMSCREEN ; CUSTOMSCREEN = $F
dc.l 0
dc.l 0
dc.l 0
dc.l 0
<txt>W naszym programie uûyliômy nowego rozkazu: "moveq". Rozkaz
ten dziaîa podobnie do rozkazu "move.b #dana,REJESTR", tylko
wykonywany jest duûo szybciej (juû jego nazwa to sugeruje:
movequick).
MOVEQ ma jednak pewne ograniczenie. Przesyîaê tylko jeden bajt,
dlatego #danâ moûe byê liczba z przedziaîu od -128 do 127.
MOVEQ zmienia jednak zawartoôê caîego rejestru (najmîodszy bajt
jest ustawiany na wartoôê #danej, a pozostaîe sâ zerowane).
Jeûeli D0=$12345678, to po wykonaniu rozkazu:
<l>
moveq #$11,d0
<txt>
D0=$00000011.
Nasz program otwiera najpierw szesnastokolorowy ekran (2^4),
nastëpnie czyôci go pierwszym (a liczâc zerowy -- drugim) kolorem
palety, odczekuje jednâ sekundë i zamyka otwarty ekran.
Skoro znacie juû zasadë dziaîania rozkazu _LVODrawImage, moûemy
napisaê coô ciekawszego.
Oprócz procedury czyszczâcej ekran napiszemy procedurë wrysowujâcâ
jakiô drobny rysunek.
Na koïcu naszego kodu dopiszcie:
<l>
; procedurë wrysowujâcâ obrazek
DrawPic:
move.l OSA,a0
add.l #$54,a0
moveq #0,d0
moveq #0,d1
lea Image2,a1
jsr _LVODrawImage(a6)
rts
; strukturë Image
Image2:
dc.w 0,0,10,10,1
dc.l Image2Data
dc.b %0100,%0000
dc.l 0
; oraz dane do obrazka
SECTION DANE,DATA_C
Image2Data:
dc.w %1111111111000000
dc.w %1000000001000000
dc.w %1011001101000000
dc.w %1011001101000000
dc.w %1000000001000000
dc.w %1011001101000000
dc.w %1011001101000000
dc.w %1001111001000000
dc.w %1000000001000000
dc.w %1111111111000000
<txt>A bezpoôrednio za linijkâ:
<l>
jsr ClearScreen
<txt>dopisz:
<l>
jsr DrawPic
<txt>Teraz nasz program dodatkowo po wyczyszczeniu ekranu w
prawym górnym rogu ekranu narysujë uômiechniëtâ twarz w
kwadraciku.
Nie muszë chyba tîumaczyê samej procedury DrawPic, ale niektóre
rzeczy mogâ byê niezrozumiaîe:
* Nasz rysunek ma pozycjë 0,0 i wymiary 10 x 10 pikseli
* jest to rysunek jednobitplanowy
* rysunek wkopiowywany bëdzie w czwarty bitplane ekranu.
Ôwiadczy o tym pole PlanePick=%0100, czyli PlanePick=4.
(Przypominam, ûe znaczek procentu przed liczbâ oznacza, ûe jest
ona zapisana w systemie dwójkowym). Pozostaîe bitplane'y sâ
zerowane (oczywiôcie tylko w miejscu naszego rysunku).
* Dane naszego rysunku okreôlone sâ etykietâ Image2Data. Ale po
co przed nimi:
<l>
SECTION DANE,DATA_C
<txt>A po to, aby dane graficzne znajdowaîy sië w pamiëci typu
Chip (a to wîaônie powoduje powyûsza dyrektywa). Gdybyômy jâ
pominëli, nasz program dziaîaîby bez zarzutu na komputerach
wyposaûonych TYLKO w pamiëê Chip. Natomiast na wszystkich innych
byîoby raz dobrze, a raz úle:
-- jeûeli program wczytaîby sië do pamiëci Chip, dziaîaîby poprawnie
-- w innym wypadku -- bîëdnie.
Bîëdne dziaîanie programu nie oznacza zawieszenia komputera,
tylko zamiast naszego rysunku w docelowym miejscu pojawiîyby sië
punkciki przedstawiajâce jakieô inne miejsce pamiëci (tîum.:
pojawiîyby sië ômieci).
Dlatego omówiona dyrektywa jest niezbëdna.
* Jak zdâûyliôcie zauwaûyê, dane naszego rysunku skîadajâ sië
ze sîów(WORD), TAK MUSI BYÊ! Dlatego, mimo ûe nasz rysunek ma
szerokoôê 10 pikseli, musimy dopeîniê dane zerami do 16 (16 bitów
to jedno sîowo). Gdyby nasz rysunek miaî szerokoôê 20 pikseli,
to pierwsze dwa sîowa dotyczyîyby jednej linijki. Wyglâdaîoby to
mniej wiëcej tak:
<l>
dc.w %1111111111111111,%1111000000000000
<txt>No, fajnie! Nasz program wyôwietla juû prosty rysunek. Moûe
wiëc jakaô animacja? Ale to juû w nastëpnym odcinku.