BasicC/Zgodność
BasicC dla WWW przejmuje cechy i funkcje JavaScript, podczas gdy standardowa wersja oparta jest na C, wiąże się to z szeregiem niezgodności. Aby uzyskać maksymalną zgodność należy stosować się do określonych zasad. Przede wszystkim należy używać komend Basic, a unikać specyficznych funkcji JavaScript czy C.
Struktury i unie
[edytuj]Najlepiej nie korzystać z tych obiektów zastępując je zwykłymi zmiennymi. Wersja WWW nie posiada unii, posiada obiekty podobne do struktur, ale obsługiwane inaczej. Deklaruje się je tak jak zwykłe zmienne JS, ponieważ w JS nie ma ścisłego określania typu, np:
const point;
I już można używać point jak struktury, np:
point.x=0;point.y=0;
Można też zainicjować zmienną podczas deklaracji oddzielając pola przecinkiem:
const point={x:0,y:0};
Tablice
[edytuj]Tablice w JS deklaruje się inaczej niż w C. Zaleca się używanie specjalnych deklaracji BasicC z użyciem słów Dim, Arr lub ByteBuffer + ...Array z odpowiednim przedrostkiem typu.
Nie można bezpośrednio deklarować tablic wielowymiarowych. Najpierw deklarujemy tablicę jednowymiarową, następnie każdy jej element oddzielnie inicjujemy jako tablicę, otrzymując tablicę dwuwymiarową, i.t.d. Np:
int a Dim(10);
For(i,0,9)
a[i]=[];
Next
Otrzymujemy tablicę dwuwymiarowa, gdzie pierwszy wymiar wynosi 10, a drugi jest nieokreślony. Możemy się do jej elementów odnosić przy pomocy nawiasów, np. a[2][6]=5;
Funkcje matematyczne
[edytuj]Większość funkcji, np. cos, używamy bez przedrostka Math stosowanego w JS, czyli piszemy cos zamias Math.cos. Zapis Math.cos zostanie zamieniony przez preprocesor na Math.Math.cos, co spowoduje błąd. Ln oznacza logarytm naturalny. Funkcje te są zdefiniowane w BasicWWW.h
Funkcje Round, Ceil, Floor działają dokładnie tak samo jak round, ceil, floor.
Obsługa plików
[edytuj]Brak większości komend obsługi plików. Zaimplementowane są jedynie specjalistyczne funkcje ładowania obrazów, czy dźwięku oraz komendy:
BAppend(N,B)
[edytuj]Dopisuje B (zmienna lub napis) do pliku o nazwie N, jeśli plik nie istnieje - tworzy nowy.
BLoad(N,B)
[edytuj]Wczytuje plik o nazwie N do bufora B typu ByteBuffer.
BSave(N,B)
[edytuj]Zapisuje B (zmienna lub napis) w nowym pliku o nazwie N, jeśli już istnieje - jest kasowany.
Kill(N)
[edytuj]Usuwa plik o nazwie N.
LoadText(N,S)
[edytuj]Powoduje wczytanie pliku tekstowego o nazwie N i przypisanie do zmiennej S.
Komendy te mogą być używane tylko wewnątrz funkcji MAIN lub oznaczonych jako asynchroniczne za pomocą słowa async, ponieważ wymuszają synchroniczność, czyli program (podprogram) powinien zostać wstrzymany do czasu załadowania pliku.
Magazyn przeglądarki
[edytuj]Możemy w nim przechowywać dane podobnie jak w pliku. Każdy element jest parą ciągów tekstowych {klucz,wartość}.
Read(K)
[edytuj]Zwraca wartość zapisanego elementu o kluczu K.
Write(K,D)
[edytuj]Zapisuje wartość D jako element o kluczu K.
Remove(K)
[edytuj]Usuwa element o kluczu K z magazynu.
ClearStorage
[edytuj]Czyści całą zawartość magazynu.
Konsola / terminal
[edytuj]Poniżej "okna" graficznego wyświetlana jest konsola tekstowa pełniąca funkcję okna terminala. Można ją ukryć komendą CloseCon i przywrócić przez OpenCon. W zwykłym BasicC komendy te są ignorowane.
Komendy Input oraz Input$ nie działają w konsoli, lecz powodują wyświetlenie nowego okna dialogowego, mogą nie wstrzymywać programu na czas wprowadzania danych. Dostępne są dodatkowe komendy:
PrLog(...)
[edytuj]Wyświetla w konsoli przeglądarki (dostępnej w narzędziach dla programistów) podany ciąg tekstowy. Zamiennik console.log w JS, której nie zaleca się używać.
Prr(S)
[edytuj]Umożliwia wypisywanie w konsoli tekstu oraz liczb powodując dodatkowo wyczyszczenie wcześniejszej zawartości.
Napisy
[edytuj]Wersja WWW dziedziczy po JavaScripcie szereg komend obsługi napisów, nie ma też ograniczenia ich długości, jednak kompatybilność z wersją standardową zapewniają jedynie komendy Basic. Nie ma rozróżnienia na napisy typu $, czyli np. Add i Add$ dają ten sam efekt, a String$(S) nie robi nic. Komendy tekstowe nie wykorzystują zmiennej STRING$ i nie powodują zmiany jej zawartości. Litery UTF, które w pamięci zajmują więcej niż 1 bajt, traktowane są jak 1 znak, nie zaimplementowano funkcji LenChr oraz LenUTF. Nie zaimplementowano też komendy MemSet.
Wskaźniki
[edytuj]W JS nie ma jawnej deklaracji wskaźników. BasicPJS usuwa symbole wskaźnika *, pod warunkiem, że zostały umieszczone zaraz po określeniu typu zmiennej, beż żadnych spacji, np. SDL_Texture*.
Grafika
[edytuj]Do wyświetlania grafiki wykorzystywany jest obszar okna zwany płótnem (canvas). Jest podstawowe płótno, na którym wyświetlane są obrazy z wykorzystaniem WebGL, na co nakładane jest dodatkowe płótno (tzw canvas2d) z przeźroczystym tłem, na którym można wyświetlać grafikę tworzona standardowymi komendami JS, głównie napisy i prymitywne kształty jak punkt, linia, prostokąt, koło. Obrazy są wyświetlane nawet szybciej niż w wersji standardowej wykorzystującej SDL, która jest jedną z najszybszych bibliotek. Obszar okna przeglądarki traktowany jest jak ekran, a płótna jak okno.
W głównym sposobem wyświetlania obrazów jest wykorzystanie pętli MAINLOOP, zwykłe pętle powodują jakby zawieszenie przeglądarki, nie generuje wtedy obrazu i nie odczytuje zdarzeń. Wyświetlanie odbywa się z częstotliwością zależną od przeglądarki, parametr SYNC nie ma znaczenia. Zmienna Display.refresh_rate ma zawsze wartość 60, niezależnie od faktycznej częstotliwości, a Display.driverdata 0.
Dodatkowo można zdefiniować 4-wymiarową macierz przekształcania obrazu przypisaną do zmiennej TransMatrix, przez którą przemnożone zostaną dane obrazu. Zdefiniowana jest też funkcja MulMatrix4(a,b) zwracająca macierz będąca wynikiem mnożenia macierzy 4-wymiarowych a i b. Jest to wykorzystywane przez komendę SetScale, która ustawia i włącza skalowanie, oraz dodatkowa komendę SetPerspective. Brak komendy IntScaling, przekształcenia wyłączamy komendą TransformOff, która przypisuje zmiennej TransMatrix wartość NULL.
SetPerspective(P,TZ,RX,RY)
[edytuj]Ustawia macierz przekształceń dając efekt perspektywy wykorzystując 3. wymiar z oznaczający przesunięcie w głąb ekranu. Jest ona wykorzystywana np. w grze GPRO. P - współczynnik perspektywy, dobry efekt daje wartość 1. TZ - przesunięcie obrazu wzdłuż osi z, zwykle wartości ułamkowe z zakresu <-1,1>. RX, RY - obrót wokół osi x lub y o dany kąt w stopniach.
AddScaling(sx,sy,sz)
[edytuj]SetScale ustawia nową macierz przekształceń, natomiast AddScaling modyfikuje istniejącą macierz dodając do niej dane skalowanie włącznie ze skalowaniem wymiaru z. Stosujemy ją np. po wcześniejszym użyciu SetPerspective.
#define SCALEQUALITY NEAREST
[edytuj]Jest to domyślna definicja w BasicWWW.h sposobu obliczania kolorów przy skalowaniu obrazów przez WebGL. Zastąpienie NEAREST parametrem LINEAR spowoduje, że przejścia kolorów będą płynne. Taką definicję można wpisać w programie przed załączeniem BasicWWW.h. W zwykłym BasicC nie da to żadnego efektu.
SDLOpen(flag)
[edytuj]Komenda inicjacji grafiki, wartość flag ma wpływ tylko na wielkość obszaru graficznego:
0 - rozmiar WINDOWWxWINDOWH - domyślnie 640x400
>=1 - tryb pełnoekranowy, ale wirtualna rozdzielczość nadal wynosi WINDOWWxWINDOWH, to samo uzyskujemy komendą FullscreenWindow lub MaximizeWindow
Cls2 ClRect2(X,Y,W,H)
[edytuj]Cls i ClRect powodują wypełnienie danego obszaru płótna WebGL aktualnym kolorem, natomiast Cls2 i ClRect2 wypełniają płótno Canvas2d kolorem czarnym, przeźroczystym.
SetDrawBlendMode(Mode)
[edytuj]Jest duża różnica w działaniu komend mieszania w porównaniu ze standardowym BasicC, gdzie komenda ta ustawia sposób mieszania kolorów przy rysowaniu tzw. prymitywów, a inne komendy ustawiają mieszanie dla konkretnego obrazka.
W wersji WWW komenda ta nie ma wpływu na rysowanie prymitywów, lecz ustawia mieszanie dla wszystkich obrazków, włącznie z czcionką GPRINT. Dostępne tryby to:
SDL_BLENDMODE_NONE
SDL_BLENDMODE_BLEND
SDL_BLENDMODE_ADD
SDL_BLENDMODE_MOD
SDL_BLENDMODE_REV
SDL_BLENDMODE_SUB
Uwaga! KomendaInvertImgpowoduje zmianę trybu naSDL_BLENDMODE_REV
ImgColorModRGBA(r,g,b,a)
[edytuj]Jest zamiennikiem ImgColorModRGB oraz ImgColorMod, ale ustawia tryb mieszania we wszystkich kolejnych operacjach na obrazach polegający na modulacji kolorów, na raz ustawiamy modulację RGB oraz Alfa. Jednocześnie ustawiana jest przeźroczystość, jak w SDL_BLENDMODE_BLEND. Komenda SetDrawBlendMode powoduję wyłączenie modulacji.
ShowPage
[edytuj]Nie powoduje żadnego działania. Odświeżaniem ekranu steruje przeglądarka.
SDL_Texture
[edytuj]Obraz SDL_Texture jest obiektem strukturalnym posiadającym dodatkowe pola:
.tex - dane pikseli tekstury
.w - szerokość w pikselach
.h - wysokość
.fb - obiekt framebuffer, jeśli obraz jest w trybie target
ImgBitmap
[edytuj]W operacjach na bitmapach parametr pixels powinien być typu ByteBuffer
ImgFlip(f)
[edytuj]Dla f=true powoduje odwrócenie symetryczne obrazu w niektórych operacjach.
WebGL używa odwrotnej geometrii w porównaniu do tradycyjnie używanej w komputerach - oś Y jest skierowana w górę, dlatego obrazy wysyłane do projektora są obracane, co powoduje, że przy pobieraniu bitmapy ekranu otrzymujemy obraz odwrócony. Przy pobieraniu bitmapy z projektora należy używać tej odwrotnej geometrii - punkt (0,0) to lewy-dolny róg obszaru.
GetImgC2d(X,Y,W,H,T)
[edytuj]Odpowiednik GetImg dla drugiego płótna (canvas2d). Tu geometria jest tradycyjna - punkt (0,0) to lewy-górny róg obszaru.
ColorKey(S,c), ColorKeyRGB(S,R,G,B)
[edytuj]Zerują składową Alfa danego koloru w obrazie S (ustawia przeźroczystość). Prawdopodobnie w przyszłości komenda ta również w zwykłym BasicC będzie dotyczyła obrazu SDL_Texture.
SaveBMP
[edytuj]Nie zaimplementowana w wersji WWW!
Lines, Points, Rects, PRects
[edytuj]Nie zaimplementowane. Rysowanie prymitywów odbywa się na drugim płótnie - canvas2d.
Zdarzenia systemowe
[edytuj]JS inaczej obsługuje zdarzenia niż SDL, ale z punktu widzenia programisty BasicC wygląda to podobnie. Główna różnica jest w działaniu zmiennej InKey, która w wersji WWW nie ma efektu samopowtarzania klawisza, ale pojawia się on, jeśli program działa wewnątrz MAINLOOP. Inne są kody klawiszy, kody w JS są napisami, ale można to ujednolicić definiując makra, np. #define SDL_SCANCODE_A "KeyA", co dla części klawiszy zostało zrobione w BasicWWW.h. Odpowiednikiem SDL_SCANCODE są w JS wartości code zdarzenia klawiatury, a SDLK wartości key, odpowiednie wartości można odczytać np. na stronie https://www.toptal.com/developers/keycode
Do prawidłowego odczytu stanu klawisza z pomocą InKey(code) konieczne może być uzupełnienie definicji zmiennej SDLKeyboardState zawartej w BasicWWW.h przypisującej kluczom code - klawiszy używanych w programie (np. grze) wartości 0, przykładowo:
const SDLKeyboardState={"ArrowDown":0,"ArrowUp":0,"ArrowRight":0};
Inaczej obsługuje się dotyk. Nie używa się komendy GetFinger, a przy odczycie palca podajemy jego numer, np. FingerX(0) podaje współrzędną X dotknięcia względem okna przeglądarki w pikselach.
Przed odczytem stanu joystick'ów należy wywołać komendę GetJoys - aktualizuje ona stany wszystkich manipulatorów.
WaitInKey, WaitMouseU, WaitMouseD w WWW nie dają żadnego efektu. Nie działają też funkcje zdarzeń TextInput i okna. Nie działa SetMouse. GetEvents nie daje żadnego efektu, pobieraniem zdarzeń steruje przeglądarka.
Napisy graficzne
[edytuj]Napisy GPRint są obrazami tworzonymi na płótnie webgl.
Nie działają komendy: GPrintF, GPrintFAt
Wyłączenie trybu mieszania kolorów przywraca biały kolor czcionki.
Nie zaimplementowano funkcji biblioteki SDL_ttf, zamiast niej zdefiniowano funkcje pisania na płótnie canvas2d:
Font(F)
[edytuj]Wybieramy rodzaj, styl i wielkość czcionki, szczegóły w dokumentacji JavaScript. Parametr podajemy bez cudzysłowu.
FontStretch(s)
[edytuj]Ustawia rozciągnięcie czcionki. Parametr podajemy bez cudzysłowu.
StrokeText(X,Y,Txt)
[edytuj]Wyświetla text i Txt w pozycji X, Y bez wypełnienia.
StrokeTextMax(X,Y,Txt,M)
[edytuj]J.w. + parametr M określający maksymalna szerokość tekstu.
Text(X,Y,Txt), TextMax(X,Y,Txt,M)
[edytuj]Wyświetlają tekst wypełniony
TextAlign(a)
[edytuj]Określa sposób przesunięcia tekstu względem pozycji X. Parametr podajemy bez cudzysłowu.
TextBaseline(b)
[edytuj]Określa sposób przesunięcia tekstu względem pozycji X. Domyślnym parametrem jest alphabetic. Parametr podajemy bez cudzysłowu.
Dźwięk
[edytuj]Zaimplementowane są różne systemy dźwiękowe, o różnych możliwościach i poziomie zgodności z podstawową biblioteką BasicSND.
System podstawowy
[edytuj]Nie wymaga załączania dodatkowych plików, ale mogą występować opóźnienia odtwarzania. Nie ma kanałów dźwiękowych, nr kanału jest ignorowany, kolejne dźwięki są miksowane z aktualnie odtwarzanymi, można nimi manipulować bezpośrenio. Brak obsługi MIDI. Dźwięki są ładowane asynchronicznie, dlatego ładowanie najlepiej zainicjować na początku programu. Inaczej określa się głośność dźwięków. Inaczej działa parametr zapętlania (loops) dźwięku: 0 - powtarzanie w nieskończoność, NOT 0 - odtworzenie bez powtarzania. Komendy są dostępne niezależnie od bibliotek, które mogą jedynie modyfikować sposób ich działania:
DeleteSound(S)
[edytuj]Usunięcie dźwięku ze zmiennej S
LoadSound(s,f)
[edytuj]Asynchroniczne ładowanie dźwięków w różnych formatach.
LoadMusic(F)
[edytuj]Asynchroniczne ładowanie dzwięku do zmiennej SNDMusic
MusicRate(r,p)
[edytuj]Określa mnożnik r szybkości odtwarzania muzyki. Parametr p=true oznacza, że szybkość nie ma wpływu na wysokość dźwięków.
MusicSeek(t)
[edytuj]Określa bieżący czas utworu w sekundach.
MusicVolume(v)
[edytuj]Określa głośność muzyki w skali 0-1.
PauseMusic
[edytuj]Wstrzymuje odtwarzanie muzyki.
PlayMusic(l)
[edytuj]Odtwarzanie muzyki. Gdy l=0 odtwarza w pętli nieskończonej.
PlayingMusic
[edytuj]Zwraca true, gdy odtwarzana jest muzyka.
PauseSound(S)
[edytuj]Wstrzymuje odtwarzanie dźwięku S.
PlaySound(c,S,p,l)
[edytuj]Odtwarza dźwięk S z częstotliwością przemnorzoną przez p, gdy l=0 odtwarza w nieskończoność. c jest ignorowane.
PlayingSound(S)
[edytuj]Zwraca true, jeśli gra dźwięk S, false jeśli nie.
SoundRate(S,r)
[edytuj]Jeśli r wynosi true mnożnik pitch nie wpływa na wysokość dźwięku, a jedynie na szybkość odtwarzania.
SoundSeek(S,t)
[edytuj]Określa bieżący czas dźwięku S w sekundach.
SoundVolume(S,v)
[edytuj]Określa głośność dźwięku S w skali 0-1. Nie ma możliwości ustawienia głośności poszczególnych kanałów.
BJSSND.h
[edytuj]Mała biblioteka oparta na Web Audio w forme klasy. Wymaga załączenia pliku: #include <BJSSND.h> na początku programu, po załączeniu BasicWWW.h, instancja klasy przypisywana jest do zmiennej SND. Ilość kanałów jest nieograniczona. Brak obsługi MIDI i sekwencji. Komendy:
SND.play(ch, sample, pitch = 1, offset = 0, duration = 0, loop = 1)
[edytuj]Podstawowa procedura odtwarzania dźwięku, wykorzystywana przez komendy BasicC. Parametry:
ch: nr kanału
sample: nazwa zmiennej reprezentującej dźwięk, lub null dla dźwięków generowanych
pitch: mnożnik częstotliwości podstawowej
offset: czas w s po jakim ma się zacząć odtwarzanie
duration: czas odtwarzania pojedyńczego dźwięku, łączny czas = duration*loop
loop: ilość powtórzeń dźwięku, dla 0 - powtarzanie nieskończone
ChannelPanning(c,l,r)
[edytuj]Głośność kanałów lewego i prawego dla kanału c
PauseChannel(c)
[edytuj]Powoduje wstrzymanie odtwarzania dźwięków na wszystkich kanałach. Nr kanału jest ignorowany.
PlayingChannel(C)
[edytuj]Zwraca obiekt dźwiękowy (jego referancję) przypisany do kanału C lub null, gdy brak odtwarzania.
PlaySound(c,s,pitch,loop)
[edytuj]Odtwarza dźwięk s na kanale c. loop może być ułamkowe i oznacza dosłownie ilość odtworzeń, inaczej niż w BasicSND, ucinany może być tylko ostatni dźwięk.
ResumeChannel(c)
[edytuj]Wznawia odtwarzanie dźwięków na kanałach. Nr kanału jest ignorowany.
Sound(c,f,duration,loop)
[edytuj]Odtwarza dźwięk generowany na kanale c z częstotliwością f.
SoundVolume(S,vol)
[edytuj]Ustawia głośność dźwięku S w zakresie 0-1, nie wpływa na głośność już odtwarzanych dźwięków.
Wave(c,wave,attack,release)
[edytuj]Ustawia parametry odtwarzania dźwięków na kanale c. wave obsługuje tylko zdefiniowane ksztalty generowanych fal: WavNoise = WavTooth = "sawtooth", WavRound = WavSin = "sin", WavSqr = "square", WavTriang = "triangle", parametry attack i release nie dotyczą pojedyńczego dźwięku, lecz całej sekwencji (dla loop != 1).
SNDChanFree(c) HaltChannel(c)
[edytuj]Obie komendy robią to samo - zatrzymują odtwarzanie na kanale c i czyszczą kanał z danych dźwięku.
BajsicSND.h
[edytuj]Trochę większa biblioteka o dużej zgodności z BasicSND, poza obsługą MIDI, tak samo definiujemy ilość kanałów i częstotliwość. Wiele dźwięków może grać na tym samym kanale. Różnice w porównaniu z BJSSND i dodatkowe komendy:
SND.play(ch, sample, pitch, loop, offset = 0)
[edytuj]Podstawowa procedura odtwarzania. Parametry:
ch: nr kanału, jeśli poza zakresem kanałów - dźwięk jest generowany niezależnie od kanałów
sample: nazwa zmiennej reprezentującej dźwięk
pitch: mnożnik częstotliwości podstawowej
offset: czas w s po jakim ma się zacząć odtwarzanie
loop: ilość powtórzeń dźwięku, dla 0 - powtarzanie nieskończone
ChannelPanning(c,l,r)
[edytuj]Nie wpływa na już odtwarzane dźwięki.
PlayingChannel(C)
[edytuj]Zwraca true, gdy na kanale c trwa odtwarzanie, false, gdy nie.
PlaySeq(c,s,m,l)
[edytuj]Odtwarzanie sekwencji dźwięków s z tablicy m na kanale c l razy na kanale c. Akordy odtwarzane są na tym samym kanale.
SoundSeq(c,m,l)
[edytuj]Jak wyżej, dla dżwięków generowanych.
Wave(c,w,a,r)
[edytuj]Prócz zdefiniowanych nazw fal można podać dowolną funkcję generującą kształt. WavNoise - fala losowa (szum).
Czas i wyjście z programu
[edytuj]Czas SDLTime jest typu rzeczywistego i podaje wartości ułamkowe.
SDLQuit
[edytuj]Nie daje żadnego efektu. Przyjmuje się, że przeglądarka automatycznie "posprząta" po programie. Również zwalnianie/usuwanie zmiennych (np. SDL_Texture, co jest konieczne np. w Androidzie) może powodować błędy, gdyż pętla MAINLOOP działa niezależnie od reszty programu i zwalnianie może nastąpić przedwcześnie.