2008.05_Freebasic – Basic na miarę XXI wieku_[Programowanie].pdf

(1244 KB) Pobierz
439032579 UNPDF
Programowanie
Język programowania/FreeBasic
na miarę XXI wieku
Marek Sawerwain
Język programowania Basic stracił bardzo wiele na popularności w ciągu ostatnich lat. W latach 80.
był to bardzo popularny język programowania szczególnie na komputerach ośmiobitowych takich jak
ZX Spectrum, Atari XL oraz Commodore C64. Wbrew pozorom znacznie późniejszy AMOS, znany z
komputerów AMIGA był językiem bardzo podobnym do Basica. O jego popularności zadecydowała m. in.
duża liczba rozszerzeń, które ułatwiały tworzenie efektownej graiki oraz oprawy muzycznej i dźwiękowej.
programie OpenOfice. Jednakże, istnieją dwa
bardzo ciekawe projekty związane z Basiciem
dla systemu Linux. Pierwszym jest GAM-
BAS. Jest to próba przeniesienia języka Visual Basic do śro-
dowiska UNIXowego. I co warto podkreślić, całkiem udana.
Drugi projekt to FreeBasic, czyli bardzo nowoczesna odmia-
na języka Basic, ale zgodna w wielu aspektach z językiem
QuickBasic (był on dostępny w systemie MS-DOS). Oferu-
je dostęp do wielu współcześnie stosowanych bibliotek np.:
OpenGL, do funkcji systemu baz danych o nazwie SQLite,
czy też do funkcji z biblioteki SDL, o ile tylko wersja binarna
tej biblioteki jest dostępna w systemie. Jest to ogromną zale-
tą, ponieważ po instalacji standardowego pakietu uzyskuje-
my dostęp do wielu przydatnych funkcji.
sności a nawet istnieje możliwość przeciążania operatorów. Bez
kłopotów możemy korzystać z przestrzeni nazw, z preproceso-
ra zgodnego z ANSI C i z wielu innych nowoczesnych właści-
wości jak np.: wątki (ang. thread ).
Warto się przyjrzeć jak wyglądają wobec tego możliwo-
ści programowania obiektowego. Zdeiniujmy klasę o nazwie
Vektor2D, która będzie zawierać dwa pola x oraz y typu single
(liczba zmiennoprzecinkowa o pojedynczej precyzji) oraz ope-
rator konwersji na ciąg znaków. Odpowiednia deinicja przed-
stawia się w następujący sposób: (Listing 4.)
Zaletą FreeBasic względem języka C++ jest następujący
prosty fakt: operator konwersji został nazwany wprost słowem
Cast . Polepsza to znacząco czytelność kodu i trzeba przyznać,
iż w tym konkretnym przypadku autorzy FreeBasica lepiej roz-
wiązali ten aspekt niż np.: w C++. Operator ten jest traktowany
jako funkcja, dlatego o typie konwersji decyduje także typ war-
tości wynikowej. Deklaracja operatora przedstawia się w nastę-
pujący sposób:
Co może FreeBasic?
Współpraca FreeBasic'a z dostępnymi bibliotekami jest bar-
dzo ważna. Należy podkreślić, że FreeBasic oferuje łatwą
współpracę z innymi językami jak np.: C++ czy Java.
Jednak to nie wszystkie możliwości FreeBasica. Pozwa-
la on na tworzenie programów obiektowych, dostępne są wła-
operator Vector2D.cast () As String
return "(" + Str(x) + ", " + Str(y) + ")"
End Operator
60
maj 2008
Freebasic – Basic
D zisiaj Basic jest kojarzony z makrami np.: w
439032579.035.png 439032579.036.png 439032579.037.png 439032579.038.png
 
Programowanie
Język programowania/FreeBasic
Właściwą konwersję wartości pól x oraz y wy-
konuje funkcja Str . Jednakże, skoro mamy de-
inicję typu wektora dwuwymiarowego, to bez
większego trudu możemy przeciążyć operator
dodawania:
względem Javy, która w przypadku większych
programów mimo wszystko nie oferuje zbyt du-
żej wydajności, a na poziomie programowania
strukturalnego, jego możliwości są podobne do
języka C czy np.: ciągle popularnego Pascala.
cji graicznych, choć oferuje podstawowe możli-
wości, to oferuje bardzo proste API nie sprawia-
jące żadnych kłopotów. Naturalnie potrzebny jest
kompilator. Sposób jego instalacji został pokrót-
ce przedstawiony w ramce pt.: Instalacja kompi-
latora FreeBasic .
Nasz program będzie działał w ramach śro-
dowiska X-Windows choć wszystkie zawiłości z
obsługą okna są przed nami ukryte. Kod źródło-
wy jest w całości zawarty na Listingu 1. Pierwsze
declare operator + ( ByRef leftArg As
Vector2D, ByRef rightArg As Vector2D
) As Vector2D
Pierwszy program
Nasz pierwszy program, to nieskomplikowana
aplikacja, która uruchamia tryb graiczny o nu-
merze 17, czyli tryb 640x400. Biblioteka funk-
Gdzie argument leftArg odpowiada lewemu ar-
gumentowi, natomiast prawy o nazwie righ-
tArg zgodnie ze swoją nazwą prawemu argu-
mentowi operatora dodawania. Obydwa argu-
menty jak widać, są przekazywane przez refe-
rencję, co oznacza wysoką wydajność, ponie-
waż nie są wykonywane kopie argumentów.
Tym razem implementacja przedstawia się na-
stępująco: (Listing 5.)
Nowy wektor jest utworzony za pomocą
konstrukcji Type<Vector2D> , gdzie zgodnie z
kolejnością deklarowania argumentów podaje-
my wartości poszczególnych pól. W podobny
sposób możemy deklarować nowe wektory, ini-
cjalizując od razu pola obiektu:
Listing 1. Uruchomienie trybu graicznego oraz wyświetlenie palety dostępnych kolorów
DIM key AS STRING , driver AS STRING
DIM AS INTEGER i , j , w , h , d , rate
CONST depth = 32
SCREEN 17 , depth
SCREENINFO w , h , d ,,, rate , driver
LOCATE 2 , 2 : PRINT "Mode: " + STR ( w ) + "x" + STR ( h ) + "x" + STR ( d ) ;
IF ( rate > 0 ) THEN
PRINT " @ " + STR ( rate ) + " Hz" ;
END IF
PRINT " (" + driver + ")"
Dim a As Vector2D = Type<Vector2D>(
2.2, 3.3 )
FOR j = 0 TO w - 1
LINE ( 32 + j , 40 ) - ( 32 + j , 79 ) , j SHL 16
LINE ( 32 + j , 100 ) - ( 32 + j , 139 ) , j SHL 8
LINE ( 32 + j , 160 ) - ( 32 + j , 199 ) , j
NEXT j
Naturalnie w klasie - czy używając nomenklatu-
ry FreeBasica: typie - możemy korzystać z kon-
struktora oraz destruktora. Zaletą jest również
obecność własności. Własność do odczytu dekla-
rujemy w następujący sposób:
SLEEP
declare property prop_name as integer
Natomiast jeśli chcemy jeszcze utworzyć wła-
sność do zapisu to odpowiednia deklaracja przyj-
muje następującą postać:
declare property prop_name( new_value
as integer )
Jednakże istnieją także mankamenty. Przedsta-
wiana wersja języka o numerze 0.18c nie oferuje
na obecnym etapie np.: dziedziczenia oraz funk-
cji wirtualnych, co naturalnie stanowi ogrom-
ne ograniczenie modelu obiektowego. Jednakże
autorzy mają w planach wprowadzenie tej mimo
wszystko zasadniczej właściwości. Toteż po uzu-
pełnieniu własności obiektowych będzie można
powiedzieć, iż jest to język o możliwościach zbli-
żonych do C++ czy Java.
Mimo ograniczeń w modelu obiektowym w
odróżnieniu od swoich protoplastów sprzed wie-
lu lat FreeBasic to sprawny 32-bitowy kompila-
tor, który daje możliwość tworzenia wydajnych
aplikacji, co stanowi od razu o jego zalecie np.:
Rysunek 1. Uruchomiony przykład programu Stars oraz przykład z Listing 1, w tle fragmenty kodu źródłowe-
go programu
www.lpmagazine.org
61
439032579.001.png 439032579.002.png 439032579.003.png 439032579.004.png 439032579.005.png 439032579.006.png 439032579.007.png 439032579.008.png 439032579.009.png 439032579.010.png 439032579.011.png 439032579.012.png 439032579.013.png
 
Programowanie
Język programowania/FreeBasic
dwie linie na Listingu rozpoczynające się od sło-
wa DIM to deklaracje zmiennych. Następnie de-
iniujemy stałą, która będzie oznaczać liczbę bi-
tów przeznaczonych na kolor. Uruchomienie try-
bu graicznego sprowadza się do użycia polece-
nia SCREEN . W rzeczywistości jest to procedu-
ra, a dokładniej podprogram, jednakże dla odróż-
nienia od innych funkcji np.: z biblioteki FMOD ,
wszystkie nazwy związane bezpośrednio z Fre-
eBasiciem będą nazywane poleceniami.
Pierwszy argument polecenia SCREEN to
numer trybu (17 odpowiada rozdzielczości
640x400, a np.: 21 to rozdzielczość 1280x1024),
drugi argument to liczba bitów opisujących ko-
lor jednego piksela. Polecenie SCREEN, posiada
jednakże znacznie więcej parametrów np.: wy-
wołanie w postaci:
źródłowy naszego programu należy poddać kom-
pilacji, ponieważ w przeciwieństwie do starych
wersji Basica, FreeBasic to kompilator. Kompi-
lacja niestety wymaga skorzystania z konsoli, ale
jest bardzo łatwa. Jeśli nasz program z Listing 1,
zapiszemy w katalogu domowym pod nazwą np.:
example_0.bas , to kompilacja sprowadza się do
wydania polecenia:
dzieć się, jakie tryby graiczne, a dokładniej ja-
kie rozdzielczości, możemy włączyć. Wystar-
czy napisać prosty program o następującej po-
staci: (Listing 6.)
Kluczowym poleceniem jest SCREEN-
LIST, które jeśli uruchomimy z parametrem
oznaczającym ilość bitów przeznaczonych na
kolor zwróci liczbę całkowitą, gdzie starsze bi-
ty zawierają szerokość, natomiast młodsze bity
wysokość. Informacje o kolejnych trybach uzy-
skujemy wywołując polecenie SCREENLIST bez
dodatkowych parametrów. Na końcu SCREEN-
LIST zwraca wartość zero, oznaczającą koniec
fbc example_0.bas
Uzupełniając jeszcze informacje o trybie gra-
icznych trzeba dopowiedzieć, iż łatwo dowie-
SCREEN 18, 32, 4, 1
oznacza uruchomienie trybu 640x480 o 32-bi-
towym kolorze, gdzie mamy dostęp do czterech
ekranów, po których można rysować. Naturalnie
tylko jeden z nich jest widoczny w danej chwi-
li. Ostatni parametr -- jedynka – oznacza, iż tryb
graiczny zostanie uruchomiony w trybie pełne-
go ekranu. Do uruchomienia trybu graicznego
wygodnie będzie też użyć polecenia SCREENRES .
Dwa pierwsze argumenty, to odpowiednio szero-
kość i wysokość, więc możemy napisać:
SCREENRES 640, 480, 32, 4, 1
W naszym programie po uruchomieniu trybu
graicznego za pomocą SCREENINFO uzyskujemy
szereg informacji o parametrach obrazu. Warto
zwrócić uwagę na to, iż część parametrów została
pominięta - wystarczy tylko wstawić przecinek, a
ewentualną nazwę zmiennej pominąć.
Kolejna część programu za pomocą funkcji
LOCATE (ustawienie pozycji kursora) oraz PRINT
w lewym górnym rogu wyświetli podstawo-
we informacje o uruchomionym trybie graicz-
nym. Pętla FOR jest odpowiedzialna za narysowa-
nie trzech pasów w odcieniach czerwieni, zieleni
oraz koloru niebieskiego. Rysowanie jest realizo-
wane za pomocą funkcji LINE . Informacja o ko-
lorze jest zawarta w drugim argumencie, ponie-
waż pierwszy parametr to współrzędne początku
i końca zapisane w postaci dwóch par rozdzie-
lonych myślnikiem: (x1,y1) – (x2,y2) . Kod
Rysunek 2. Strona domowa projektu FreeBasic
Na płycie CD/DVD
Na płycie CD/DVD znajdują się wykorzy-
stywane biblioteki, kod źródłowy programu
oraz wszystkie listingi z artykułu.
Rysunek 3. Tworzenie interfejsu graicznego dla odtwarzacza modułów
62
maj 2008
439032579.014.png 439032579.015.png 439032579.016.png 439032579.017.png
 
Programowanie
Język programowania/FreeBasic
listy dostępnych rozdzielczości.
Jeśli tak się stało, uruchomienie odtwarza-
nia pliku nastąpi po wywołanie funkcji FMU-
SIC_PlaySong , natomiast zatrzymanie od-
twarzania za pomocą funkcji FMUSIC_Stop-
Song . Usunięcie modułu z pamięci następu-
je po wywołaniu funkcji FMUSIC_FreeSong .
Po rozpoczęciu odtwarzania muzyki FreeBa-
sic wykonuje swój program w sposób zupeł-
nie niezależny, więc nie musimy się martwić
o płynność odtwarzania muzyki. Bibliote-
ka FMOD jest pod tym względem niezależ-
na od naszego programu. Dlatego za pomo-
Mały odtwarzacz modułów
Na płycie DVD dołączonej do czasopisma
(oraz na stronie czasopisma Linux+) znajdują
się źródła omówionych przed chwilą przykładów
jak również kilka innych programów. Jednakże,
aby nie tracić miejsca na ich prezentację, zajmie-
my się tylko jednym z nich, a mianowicie pro-
gramem do odtwarzania modułów muzycznych.
Moduły muzyczne, czyli pliki o rozszerzeniu
min.: MOD, S3M oraz XM to bardzo popularne
formaty na tzw. demoscenie, ale nie tylko. Znana,
szczególnie miłośnikom gier, gra Unreal również
korzystała z modułów muzycznych.
Ponieważ FreeBasic oferuje dostęp do bi-
blioteki FMOD, która odtwarza tego typu pliki,
w ramach prostego ćwiczenia dość łatwo zbudo-
wać całkiem przydatny program. Listing 2 przed-
stawia kod źródłowy programu wykorzystujący
bibliotekę FMOD.
Nasz program zaczynamy od polecenia pre-
procesora #include. Podobnie jak jego odpowied-
nik w języku C, polecenie #include włącza plik
nagłówkowy. Dodatkowe słowo once zapewnia,
że plik zostanie włączony tylko raz.
Programy w Basicu nie mają wyróżnio-
nej funkcji, od której rozpoczyna się wykony-
wanie programu. Program rozpoczyna pracę od
pierwszej instrukcji w pliku źródłowym. W na-
szym programie jest to instrukcja warunkowa IF.
Wcześniej wprowadzamy deklarację funkcji er-
ror_sub przeznaczonej do obsługi błędów i kilka
stałych. Jedna z nich, music_ile , zawiera nazwę
pliku do odtwarzania. Nie jest to dobre rozwiąza-
nie, gdyż lepiej byłoby wyposażyć nasz program
w interfejs dla użytkownika i tak zrobimy w na-
stępnym punkcie.
Zadanie pierwszej instrukcji warunkowej,
to sprawdzenie wersji biblioteki FMOD. Upew-
niamy się, czy używana przez program wersja
FMOD nie jest niższa niż wersja FMOD zastoso-
wana podczas kompilacji naszego programu. Jest
tak się stanie, funkcja error_sub zakończy dzia-
łania naszej aplikacji.
Gdy numer wersji biblioteki jest odpo-
wiedni, należy dokonać inicjalizacji bibliote-
ki FMOD. To zadanie wykonuje kolejna in-
strukcja warunkowa wywołująca funkcję FSO-
UND_Init . Pierwszy parametr to częstotli-
wość dźwięku, czyli 44kHz, natomiast liczba
32 oznacza ilość dostępnych kanałów dźwię-
ku. Ostatni parametr pozwala na wprowadzenie
dodatkowych lag, my jednak nie wykorzystu-
jemy żadnych dodatkowych właściwości.
Po udanej inicjalizacji od razu może-
my spróbować wczytać moduł funkcją FMU-
SIC_LoadSong . Wartość różna od zera ozna-
cza, iż moduł został poprawnie wczytany.
W sieci
• Strona projektu FreeBasic - http://www.freebasic.net
• Top50, czyli 50 najlepszych stron o FreeBasic'u - http://www.fbtop50.com
• Spis gier opracowanych we FreeBasic'u - http://games.freebasic.net
• Wiele narzędzi do programowania, również dla FreeBasic'a - http://www.phatcode.net
• Najnowsze informacje zawiązane z kompilatorem FreeBasic - http://
report.freebasic.info
• Ciekawa strona zawierająca interesujące przykłady wraz z kodem źródłowym, natu-
ralnie we FreeBasic'u – http://aapproj.phatcode.net
Listing 2. Odtwarzanie modułu muzycznego
# include once "fmod.bi"
DECLARE SUB error_sub ( byval Message as string )
const TRUE = 1
const FALSE = 0
const music_ile = "aryx.s3m"
DIM song AS FMUSIC_MODULE ptr
IF ( FSOUND_GetVersion () < FMOD_VERSION ) THEN
error_sub ( "Do poprawnego działania programu naley zainstalowa co
najmniej wersj " & FMOD_VERSION )
END IF
IF ( FSOUND_Init ( 44100 , 32 , 0 ) = FALSE ) THEN
error_sub ( "Nie mona uruchomi systemu FMOD!" )
END IF
song = FMUSIC_LoadSong ( music_ile )
IF song = 0 THEN
error_sub ( "Nie mona wczyta pliku """ + music_ile + """" )
END IF
FMUSIC_PlaySong ( song )
PRINT "Nacinij klawisz spacji (lub dowolny inny) aby zakoczy działanie
tego programu."
SLEEP
FMUSIC_FreeSong ( song )
FSOUND_Close
END
SUB error_sub ( BYVAL message AS String )
print "Błd: " ; message
FSOUND_Close
END 1
END SUB
www.lpmagazine.org
63
439032579.018.png 439032579.019.png 439032579.020.png 439032579.021.png 439032579.022.png 439032579.023.png 439032579.024.png 439032579.025.png 439032579.026.png 439032579.027.png 439032579.028.png 439032579.029.png 439032579.030.png
 
Programowanie
Język programowania/FreeBasic
Listing 3. Fragmenty programu do odtwarzania plików muzycznych
cą polecenia PRINT wyświetlamy komunikat
i poleceniem SLEEP usypiamy nasz program,
ale muzyka nadal jest odtwarzana. Ta wła-
sność okaże się bardzo wygodna w następ-
nym przykładzie.
# include once "gtk/gtk.bi"
# include once "gtk/libglade/glade-xml.bi"
# include once "fmod.bi"
declare sub on_EndWorkBTN_clicked cdecl alias "on_EndWorkBTN_clicked" (
byval object as GtkObject ptr , byval user_data as gpointer )
' usuni te fragmenty
namespace global
Dim music_ilename As String
Dim song As FMUSIC_MODULE ptr
Dim paused As Byte
Dim FileNameENTRY As GtkWidget ptr
end namespace
Dim xml As GladeXML ptr
Dim MainWin As GtkWidget ptr
global . music_ilename = ""
gtk_init ( NULL , NULL )
' inicjalizacja FMOD
xml = glade_xml_new ( "mplaywin.glade" , NULL , NULL )
MainWin = glade_xml_get_widget ( xml , "MainWin" )
global . FileNameENTRY = glade_xml_get_widget ( xml , "FileNameENTRY" )
gtk_widget_show_all ( MainWin )
glade_xml_signal_autoconnect ( xml )
gtk_main ( )
g_object_unref ( xml )
FSOUND_Close
end 0
' usuni te fragmenty
sub on_PlayBTN_clicked cdecl ( byval object as GtkObject ptr , byval
user_data as gpointer ) export
global.song = FMUSIC_LoadSong( global.music_ilename)
if global . song = 0 then
error_sub ( "Nie mona wczyta pliku: " & global . music_ilename )
else
FMUSIC_PlaySong ( global . song )
end if
end sub
sub on_StopBTN_clicked cdecl ( byval object as GtkObject ptr , byval
user_data as gpointer ) export
FMUSIC_FreeSong( global.song )
end sub
sub on_PauseBTN_clicked cdecl ( byval object as GtkObject ptr , byval
user_data as gpointer ) export
Dim tmp As Byte
if global . paused = 0 then
tmp = FMUSIC_SetPaused ( global . song , 1 )
global . paused = 1
else
tmp = FMUSIC_SetPaused ( global . song , 0 )
global . paused = 0
end if
end sub
sub on_SelFileBTN_clicked cdecl ( byval object as GtkObject ptr , byval
user_data as gpointer ) export
' usuni te fragmenty
end sub
Duży odtwarzacz modułów
Poprzedni przykład, niestety, nie ma interfej-
su graicznego, toteż należy taki interfejs zbu-
dować. Załóżmy, że w naszym programie wy-
stąpi pięć przycisków. Trzy pierwsze związane
będą z odtwarzaniem muzyki: Play, Pause oraz
Stop. Przycisk O.K. kończy pracę naszej apli-
kacji. Ostatnim przyciskiem jest przycisk o na-
zwie „trzy kropki”. Za jego pomocą wybieramy
moduł do odtwarzania. Dodamy również pole
edycyjne, w którym wyświetlana będzie nazwa
pliku wraz z pełną ścieżką.
Do budowy tak prostego interfejsu, mi-
mo wszystko, najlepiej skorzystać z biblio-
teki GTK+, tym bardziej iż FreeBasic ofe-
ruje pełny dostęp do tej biblioteki. Wspiera-
ne są również pliki XML zawierające opis in-
terfejsu wygenerowanego za pomocą progra-
mu GLADE.
Niestety kod źródłowy naszej aplikacji jest
już zbyt duży, aby go zaprezentować w całości,
dlatego Listing 3 przedstawia tylko wybrane,
choć jak widać obszerne, fragmenty. Podobnie
jak w poprzednim programie rozpoczynamy od
dołączenia plików nagłówkowych. Oprócz bi-
blioteki FMOD dołączamy także pliki dotyczą-
ce biblioteki GTK+ oraz pakietu GLADE-XML.
Następnie deklarujemy nagłówki funkcji odpo-
wiadające na sygnały np.: na sygnał „clicked”,
czyli na tzw. kliknięcie na przycisk. Listing 3 za-
wiera tylko jeden przykład takiej deklaracji. Po-
dobieństwo do języka C jest jak widać oczywi-
ste, choć musimy użyć słowa kluczowego by-
val aby wskazać, iż wartości te są przekazy-
wane przez wartość (tzn. wykonywana jest ko-
pia wskaźników). Nim zaczniemy budować sam
interfejs, należy uruchomić bibliotekę FMOD
- ten fragment jest identyczny jak w poprzed-
nim punkcie, dlatego nie będzie on w tym miej-
scu omawiany.
Kolejny fragment to deinicja przestrzeni
nazw o nazwie global. W ten sposób, wszyst-
kie zmienne, które chcemy aby były widoczne
dla innych funkcji i procedur są zawarte w prze-
strzeni global, pełniącej rolę przestrzeni zmien-
nych globalnych. Ważną zmienną jest zmienna
o nazwie song reprezentująca wczytany moduł
muzyczny. Po deklaracji zmiennych należy za-
inicjalizować bibliotekę GTK. To zadanie jest
realizowane przez funkcję gtk_init. Kolejne li-
nie kodu są praktycznie takie same jak w wielu
aplikacjach GTK+ pisanych bezpośrednio w ję-
zyku C. Zastosowanie funkcji glade_xml_new
64
maj 2008
439032579.031.png 439032579.032.png 439032579.033.png 439032579.034.png
 
Zgłoś jeśli naruszono regulamin