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 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. 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:
BLoad(N,B)
[edytuj]Wczytuje plik o nazwie N do bufora B typu ByteBuffer.
LoadText(S,N)
[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 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, są one trudne w użyciu, gdyż nie wstrzymują działania programu na czas wprowadzania danych. Dostępna jest dodatkowa komenda:
PrintR
[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 zasadzie jedynym sposobem wyświetlania obrazów jest wykorzystanie pętli LOOP, zwykłe pętle powodują jakby zawieszenie przeglądarki, nie generuje wtedy obrazu i nie odczytuje zdarzeń. Wyświetlanie jest zawsze synchroniczne, parametr VSYNC nie ma znaczenia. Zmienna Display.refresh_rate ma zawsze wartość 60, 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 InitScaling, 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 wgłą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 - szerokość okna przeglądarki, 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! Komenda InvertImg powoduje zmiane trybu na SDL_BLENDMODE_REV
ImgColorModRGBA(r,g,b,a)
[edytuj]Jest zamiennikiem ImgColorModRGB oraz ImgColorMod, ale działa tak jak SetDrawBlendMode - ustawia tryb mieszania w 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 typu struktury 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 LOOP. 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 sa 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};
WaitInKey WaitMouseU WaitMouseD w WWW nie dają żadnego efektu. Nie działają też funkcje zdarzeń TextInput, okna, obsługi dotyku i joysticków. Funkcje NumFingers Stick Strig NumJoys przyjmują zawsze wartość 0. 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 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]Starano się uzyskać maksymalną zgodność z BasicSND, ale występują różnice. W wersji WWW nie ma kanałów dźwiękowych, nr kanału jest ignorowany, kolejne dźwięki są miksowane z aktualnie odtwarzanymi, czyli tak jak by nr kanału wynosił -1. Brak obsługi muzyki 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 loops
dźwięku: 0 - powtarzanie w nieskończoność, !=0 - odtworzenie bez powtarzania. Poniżej dodatkowe komendy dźwiękowe w wersji WWW:
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.
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.
PauseSound(S)
[edytuj]Wstrzymuje odtwarzanie dźwieku S.
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.
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 LOOP działa niezależnie od reszty programu i zwalnianie może nastąpić przedwcześnie.