home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga ACS 1997 #2
/
amigaacscoverdisc
/
amigascene
/
diskmagazines
/
izviestia
/
izviestia_10.lha
/
Izviestia_10
/
Texts
/
039
/
039
Wrap
Text File
|
1996-08-12
|
8KB
|
264 lines
BImages w C
[LeMUr/Fire & blabla]
I oto kolejny odcinek kursu "System Amigi w C". Tym razem o obrazach, a
ôciôlej mówiâc o images.
Co to takiego te images? Ano nic szczególnego! KAÛDY koder, który chociaû
raz bawiî sië w wyôwietlanie obrazków spotkaî sië z danymi w formacie RAW
(czyli same dane bitplane'ów). Podobnie jest z image'ami (brrr - co za
sîowo!). Jest jednak pewna róûnica. Image jest pewnâ strukturâ w systemie
Amigi, która opisuje nasz "obrazek". Zawiera ona dane dotyczâce wielkoôci,
iloôci biteplane'ów i kilku innych rzeczy [otrzebnych do peînego opisania
obrazka. Oto ona:
struct Image
{
WORD LeftEdge
WORD TopEdge
WORD Width
WORD Height
WORD Depth
UWORD *ImageData
UBYTE PlanePick
UBYTE PlaneOnOff
struct Image *NextImage
}
Czas na objaônienia, a jest ich trochë...
LeftEdge i TopEdge to przesuniëcie (z lewej i z góry) od "poczâtku"
obrazka. O co chodzi? Zaîóûmy, ûe chcemy "poîoûyê" nasz obrazek (funkcjâ
DrawImage(), ale o tym póúniej) tak, aby jego górny lewy róg byî w punkcie
(10;10), ale mamy tam gotowâ ramkë o szerokoôci 2 punktów. Aby zbytnio nie
kombinowaê moûemy ustawiê to dwupunktowe przesuniëcie wîaônie w tych polach.
Uûywajâc DrawImag() podamy wspóîrzëdne (10;10), ale dziëki polom LeftEdge i
TopEdge obrazek bëdzie w punktach (jego lewy-górny róg) np. (12;12).
Width i Height okreôlajâ wielkoôê obrazka w punktach. Natomaist Depth to
oczywiôcie iloôê uûytych plane'ów.
ImageData jest wskaúnikiem (adresem) na dane graficzne. Tutaj maîa uwaga -
jeôli zmieniacie IFFa na RAWa i chcecie tych danych uûyê w Image, to dane te
muszâ byê "wyrównane" do sîowa. Korzystajâc z Pic-Cona mamy to zapewnione
przez ustawienie "WORD-ALIGNED" w odpowiendniej opcji "Image format".
Oczywiôcie dane te muszâ byê w pamiëci CHIP!
PlanePick i PlaneOnOff to pola, które decydujâ o tym, które biteplane'y
majâ byê brane pod uwagë przy rysowaniu obrazka i które trzeba "zablokowaê".
Po wiëcej szczegóîów odsyîam do AutoDocs.
NextImage jest wskaúnikiem na nastëpnâ strukturë Image, wiëc moûemy za
pomocâ jednego wywoîania DrawImage() narysowaê kilka obrazków.
Czas na opis funkcji DrawImage() z intuition.library, która to pozwala na
narysowanie "obrazka".
void DrawImage(RastPort, Image, LeftOffset, TopOffset)
A0 A1 D0 D1
RastPort to wskaúnik (adres) na strukturë RastPort w której zostanie
narysowany nasz obrazek. Dobraê sië do niej najîatwiej przez "Okno->RPort",
przy czym "Okno" jest wskaúnikiem na nasze okno otrzymanym z OpenWindow().
Image to wskaúnik na opisanâ przed chwilâ strukturë Image.
LeftOffset i TopOffset to wartoôci, jakie zostanâ dodane do pól Left- i
TopEdge w srtukturze Image i otrzymana suma bëdzie wspóîrzëdnâ lewego-górnego
rogu naszego gotowego obrazka.
DrawImage() pobiera dane z pola NextImage i jeôli nie jest ono równe NULL
to rysowany jest kolejny obrazek.
Czas na przykîad, który wyjaônie jeszcze kilka spraw. Plik DrawImage.c z
katalogu "Bonus Stuff":
___cut_here___
/*
DrawImage.c
LeMUr/Fire & blabla
*/
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/powerpacker.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <libraries/ppbase.h>
#include <intuition/intuition.h>
#include <stdlib.h>
#inlcude <stdio.h>
struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;
struct PPBase *PPBase=NULL;
struct Screen *ekran=NULL;
struct Window *okno=NULL;
/* pamiëê i jej rozmiar */
UWORD *Bufor=NULL;
ULONG Size=NULL;
struct NewWindow nokno=
{
0, 0,
320, 256,
0, 0,
RAWKEY,
RMBTRAP | NOCAREREFRESH | ACTIVATE | BORDERLESS | BACKDROP,
NULL, NULL,
NULL, NULL,
NULL,
0, 0,
0, 0,
CUSTOMSCREEN
};
struct NewScreen nekran =
{
0, 0,
320, 256,
4,
0, 0,
NULL,
CUSTOMSCREEN,
NULL, NULL,
NULL, NULL,
};
struct Image myimage =
{
0, 0,
320, 256,
4,
NULL,
0x0F, 0,
NULL
};
void gout(int kod)
{
if(okno)
CloseWindow(okno);
if(ekran)
CloseScreen(ekran);
if(Bufor && Size)
FreeMem(Bufor, Size);
if(IntuitionBase)
CloseLibrary((struct Library *)IntuitionBase);
if(GfxBase)
CloseLibrary((struct Library *)GfxBase);
if(PPBase)
CloseLibrary((struct Library *)PPBase);
exit(kod);
}
void main(int argc, char *argv[])
{
int err;
if(!(PPBase=(struct PPBase *)OpenLibrary("powerpacker.library", 0L)))
gout(10);
if(!(IntuitionBase=(struct IntuitionBase *)
OpenLibrary("intuition.library", 34L)))
gout(10);
if(!(GfxBase=(struct GfxBase *)
OpenLibrary("graphics.library", 34L)))
gout(10);
if(err=ppLoadData(argv[1], DECR_NONE, MEMF_CHIP,
(UBYTE **)&Bufor, &Size, NULL))
{
printf("%s\n", ppErrorMessage(err));
gout(50);
}
if(!(ekran=OpenScreen(&nekran)))
gout(30);
LoadRGB4(&ekran->ViewPort, Bufor, 16);
nokno.Screen=ekran;
if(!(okno=OpenWindow(&nokno)))
gout(40);
ShowTitle(ekran, FALSE);
myimage.ImageData=Bufor+16;
DrawImage(okno->RPort, &myimage, 0L, 0L);
RemakeDisplay();
/* pëtla obsîugujâca komunikaty intuition */
for(;;)
{
struct IntuiMessage *imsg=NULL;
WaitPort(okno->UserPort);
if(imsg=(struct IntuiMessage *)GetMsg(okno->UserPort))
{
ULONG clas=imsg->Class;
UBYTE code=imsg->Code;
ReplyMsg((struct Message *)imsg);
/* naciôniëcie ESC */
if(clas==RAWKEY && code == 69)
gout(0);
}
}
}
___cut_here___
Czas na objaônienia. Na poczâtek standardowo full include'ów i definicji. W
NewWindow "kaûë" informoawê o naciôniëciu klawisza oraz ustawiam "olewanie"
RMB i informacje o odôwieûaniu ekranu. Dodatkowo okno ma beê otwarte bez ramek
i pod wszystkimi oknami na danym ekranie, co w tym wypadku nie jest konieczne.
Okno i ekran majâ rozmiary 320x256 i jest to w 16 kolorach. Takie obrazki
bëdziemy wuôwietlaê.
Dalej jest funkcja wychodzâca, która zwalnia i zamyka wszystko, co jest do
zwolnienia.
W gîównym programie otwieramy takûe bibliotekë powerpacker, bo program ma
moûliwoôê wczytywania danych spakowanych w tym formacie. Moûna to pominâê i
napisaê (lub uûyê gotowâ, np. z poprzedniego odcinka) innâ procedurë, ale
zaleûaîo mi na w miarë krótkim listingu. Po zaîadowaniu obrazka otwieramy
ekran, ustawiamy paletë (o tym jescze za chwileczkë) i otwieramy okno.
Nastëpnie rysujemy nasz obrazek i "przemyôlamy wyôwietlanie" ;-)
W pëtli sprawdzamy czy aby nie naciôniëto ESC, a jeôli tak to koïczymy
program.
Jeôli natomiast chodzi o plik, który zostanie wyôwietlony to musi on byê
odpowiednio przygotowany. Jak? Bardzo îatwo! Uruchamiamy Pic-Cona i wczytujemy
dowolny obrazek IFF w 320x256 i 16 kolorów. Teraz zapisujemy paletë (4 bit!),
a nastëpnie dane (word-aligned). Oczywiôcie do 2 róûnych plików. Uruchamiamy
nastëpnie Cygnusa (lub w inny sposób îâczymy pliki) i wczytujemy plik z
nagranâ paletâ. Skaczemy na koniec tekstu i doîâczamy ("Include file...") plik
z danymi RAW. Caîoôê zgrywamy na dysk jako jeszcze inny plik (w sumie z
jednego obrazka bëdziemy mieê 4 pliki - sam obrazek, paletë, dane w RAW i plik
dla powyûszego programu). Uruchamiamy DrawImage podajâc jako parametr nazwë
pliku zgranego z Cygnusa. Podziwiamy obrazek i naciskamy ESC gdy nam sië
znudzi. Ot, caîy trick!
Dla uîatwienia w katalogu "Bonus Stuff" powinien sië znaleúê jakiô
przykîadowy obrazek, o ile starczy miejsca.
Dodam tylko, ûe powyûszy program jest fragmentem slide-showu, nad którym
pracujemy (zmienione jest tylko kilka funkcji (na AGA-thowe :) i dodane
zmienianie wielkoôci ekranu), a takûe w tym numerze Izviestii do wyôwietlania
clip-artów. Mam nadziejë, ûe teraz pokazywanie obrazków i uûywanie ich w
waszych programach nie bëdzie kîopotliwe!
Czego sobie i Wam ûyczy
LeMUr/Fire & blabla
P.S.
Thanks must go to Spirol/Clan for idea of article!