Zmiany w AGE

Ostatnio miałem trochę czasu aby posiedzieć chwilę dłużej nad kodem z czego oczywiście skorzystałem.

Największą zmianą było wyrzucenie menedżera zasobów na rzecz wczytywania z wirtualnego systemu plików. Doszedłem do wniosku, że menedżer w tamtej postaci był nieprzydatny. W końcu nietrudno jest zrobić coś bezużytecznego i się przy tym napracować 😉

Kolejną zmianą było zastąpienie biblioteki SDL_image biblioteką DevIL, która jest po prostu wygodniejsza w użyciu. Miałem z nią pewne problemy ale jak się później okazało wynikały z tego, że kilka innych rzeczy też nie działały jak powinny. Dodałem także kilka wersji funkcji CreateTexture() która pozwala ładować tekstury z plików graficznych, z pamięci, z wirtualnego systemu plików oraz po prostu tworzyć pustą białą teksturę o podanych rozmiarach. Jeśli chodzi o ostatnią wersję to jest ona teraz najmniej użyteczna bo nie zrobiłem jeszcze możliwości edycji pikseli tekstury, ale wszystko przed nami 😉

Następną zmianą jaką postaram się wprowadzić będzie wspomniana właśnie edycja tekstury oraz możliwość definiowania, którą część tekstury chcemy wyświetlać na obrazku. Pozwoli to na stworzenie klasy obsługującej sprajty i korzystającej z jednej tekstury. W tej chwili obrazek wyświetla teksturę jako całość i przy takim jej traktowaniu rozdział na teksturę oraz obrazek zupełnie nie ma sensu.

Ostatnią z rzeczy, którą planuję jest zapis aktualnego ekranu do tekstury. Można powiedzieć, że to bedzie renderowanie do tekstury. Oczywiście z tym od razu kojarzy się robienie zrzutów ekranu oraz zapis tekstury do pliku więc i to trzeba będzie zrobić 🙂

Reklamy

AGE VFS

Ostatnio do AGE dodałem obsługę wirtualnego systemu plików. Zainspirował mnie artykuł Tomasza Dąbrowskiego: http://dabroz.scythe.pl/2008/07/17/wirtualny-system-plikow-vfs .

O ile funkcjonalność jaką oferuje ten „VFS” można podpiąć pod wirtualny system plików. Tak na prawdę chodziło raczej o wrzucenie danych plików do jednego wielkiego pliku. Ogromną zaletą rozwiązań przedstawionych w artykule jest szybkość działania. Potraktowanie nazw plików funkcją hashującą wpływa mocno na prędkość wyszukiwania i dodatkowo sprawia, że wpis w hash-table dla każdego pliku ma taki sam rozmiar. To z kolei pozwala łatwiej stworzyć takie pliki VFS bo nie trzeba zapisywać nazw plików zawartych wewnątrz.

Tutaj jednak pojawia się problem. Nie powoduje on wielkich problemów, ale jednak istnieje i może stać się uciążliwy – z takiego pliku z danymi nie da sie odczytać nazw plików (bo są tam tylko hashe), a to jest pewien problem, jeśli programista pracujący nad projektem zapomni co wrzucił do pliku.

Można ten problem rozwiązać na dwa sposoby:

  1. Dodać na końcu pliku tablicę nazw plików, a na początku informację, gdzie jest nazwa każdego pliku
  2. Utworzyć w programie generującym pliki VFS możliwość zapisu projektu

Rozwiązanie pierwsze pozwala na podgląd jakie pliki są zapisane w systemie, a to z kolei pozwala na ich łatwy eksport z pliku.

Drugie zaś pozostawia plik systemu plików „niedostępnym” oraz pozwala na modyfikowanie systemu plików po prostu przez stworzenie go od nowa z nowymi plikami.

Ja postanowiłem wybrać drugie rozwiązanie i napisałem program AGE-VFS. Narzędzie napisane jest z pomocą wxWidgets więc powinno kompilować się też pod Linuxem (co sprawdzę w pszyszłości 😉 ).

Ostatnią fażą dodawania do AGE wirtualnego systemu plików było oczywiście dodanie klas obsługujących wczytywanie i wyszukiwanie danych w pliku. To jednak okazało się być mało pracochłonne.

Ostatecznie postanowiłem sprawdzić jak działa VFS i wczytać jakiegoś WAVe’a. Szybko okazało się, że w moim programie do tworzenia VFS był mały błąd, który skutecznie psuł tworzone pliki 😉 Naprawiłem go jednak i w końcu mogę powiedzieć, że AGE potrafi obsługiwać bardzo prosty system plików (o ile można go tak nazwać…)

Konsola AGE

Konsola do AGE wreszcie skończona. Na początek zmagałem się z obsługą wyświetlania, dodawania linii i opcjami takimi jak „przewijanie” konsoli i czyszczenie ekranu konsoli. Następnym krokiem było wprowadzanie komend do konsoli. Tutaj na początku wydawało mi się to bardzo trudne ze względu na to że musiałbym sobie sam zakodować obsługę klawisza SHIFT. Tutaj jednak z pomocą przyszedł mi unikod. Można go w SDLu włączyć za pomocą wywołania:

SDL_EnableUNICODE(true);

Wtedy struktura eventu klawiatury otrzymywanego od SDL jest wypełniona dodatkowo o kod wciśniętej kombinacji klawiszy w unikodzie. To bardzo mi pomogło ponieważ po wciśnięciu SHIFT+0 od razu dostałem znak ‚)‚ zatem nie musiałem się już martwić o takie rzeczy.

Później dodałem jeszcze obsługę klawiszy:

  • PageUp, PageDown, Strzałki – dół, góra: przewijanie konsoli
  • Strzałki – prawo, lewo: przesuwanie karetki w prawo/lewo
  • CTRL + prawo/lewo: przesuwanie karetki o całe wyrazy
  • (CTRL +) Backspace/Delete: usuwanie znaków/wyrazów przed i za karetką
  • Home/End: przejście na początek/koniec linii

Możliwe, że w przyszłości dodam jeszcze uzupełnianie komendy za pomocą klawisza TAB.

Końcąwą fazą tworzenia konsoli był jej kluczowy element – dodanie obsługi wpisywanych komend. Rozwiązanie już mialem (z poprzedniej wersji AGE). Teraz wystarczyło prawie skopiować kod i troszkę go przystosować.

Planuję jeszcze dodać wbudowaną komendę help która pokazywałaby pomoc dla komendy podanej jako argument. Oczywiście użytkownik AGE mógłby stworzyć ją sam, ale wtedy miałby z tym więcej pracy. Co o tym sądzicie?

Czcionki w AGE

Dodanie obsługi czcionek TTF do AGE tak aby utrzymać wieloplatformowość małym kosztem wydawało się początkowo trudne. Jednak dzięki bibliotece FreeType2 i Google okazało się to znacznie prostsze niż myślałem.

W tej chwili AGE posiada możliwość wyświetlania tekstu z automatycznym dzieleniem na linie przy pomocy znaku ‚\n’ oraz potrafi obliczyć prostokąt, w którym podany tekst zostałby wyświetlony. Możliwe, że w przyszłości dodam funkcje wyświetlające tekst w danym obszarze z wyrównaniem lub podobne. Przy obecnej implementacji tego wszystkiego dodanie takich funkcji jest dość prostą rzeczą.

Całą zabawę z czcionkami TTF postanowiłem podjąć dlatego, że planuję dodać konsolę, a ciężko byłoby to uczynić bez wyświetlania tekstu, prawda? 🙂

Niestety po tym jak nauczyłem AGE wyświetlać tekst zdałem sobie sprawę, że trzeba mieć jakąś czcionkę aby wyświetlać tekst konsoli i musi to być czcionka, która bedzie dostępna niezależnie od systemu operacyjnego. Rozważałem instalowanie jakiejś czcionki wraz z biblioteką jednak ten pomysł niezbyt mi się podobał. Postanowiłem więc zrobić najbardziej bezczelną rzecz jaka przyszła mi do głowy – wrzuciłem czcionkę wprost do kodu jako tablicę bajtów. Będzie to niestety kilkadziesiąt kilobajtów więcej dla biblioteki, ale z drugiej strony będę miał pewność, że czcionka będzie zawsze dostępna.

Dzięki tym kilku prostym i czasem spartańskim zabiegom mogę wreszcie rozpocząć kodowanie obsługi konsoli dla AGE 🙂

Co tam z AGE

Niedawno całkiem miałem nieprzyjemne zdarzenie w wyniku którego utraciłem aktualną na tamten czas wersję AGE. Na szczęście podczas testów pod Windowsem robiłem kopię wszystkich plików źródłowych więc nie muszę zaczynać wszystkiego od nowa. Po wstępnym obejrzeniu kodów „z odzysku” stwierdziłem, ze nie straciłem zbyt wiele więc jest dobrze 🙂

Ostatnio jednak nie miałem weny do kodzenia więc wykorzystałem czas inaczej. Rozbudowałem trochę dokumentację. Urozmaiciłem ją kilkoma przykładami wykorzystania AGE, a w planach mam jeszcze włączenie w dokumentację krótkiego tutoriala.

To tyle – wreszcie jakaś krótka notka 😉

Nowe rzeczy

Projektowanie aplikacji/biblioteki od nowa – jeśli napisało się ją już wcześniej, ma swoje ogromne zalety. Można poprawić wszelkie niedoróbki i usprawnić to co usprawnienia wymagało.

Przykładem takiego usprawnienia jest wreszcie napisany przeze mnie (jednak jeszcze nie do końca) Resource Manager. Zastosowanych kilka reguł OOP-u i już mamy całkiem fajny kawałek kodu, który jednocześnie daje się rozszerzać bez większych problemów.

Aktualnie Resource Manager składa się z dwóch części – menedżera zasobów oraz fabryki zasobów. Fabrykę można uczyć tworzenia nowych zasobów w trakcie działania programu więc programista używający AGE będzie mógł sam dodać nowy typ zasobu w zależności od potrzeb.

Obiekty tworzy się za pomocą linii tekstowych postaci:

{resource type} "{resource name}" "{resource arguments}"

Przy czym: {resource type} jest nazwą typu zasobu (np. texture, sample itp.), {resource name} jest nazwą zasobu używaną do zidentyfikowania go przez Resource Manager’a. Ostatni argument {resource arguments} jest już argumentem zależnym od typu zasobu jaki dodajemy. Przykładowo dla tekstury będzie to tylko ścieżka do obrazka.

Kolejną dobrą wiadomością jest to, że udało mi się zmusić AGE do odtwarzania utworów. Tutaj mamy dwie możliwości:

  • odtwarzanie sampli (w kółko lub pojedyńczo)
  • odtwarzanie całych utworów

O ile odtwarzanie sampli jest raczej prostą sprawą – załadować, włączyć i gra – o tyle utwory są zorganizowane trochę inaczej. Otóż utwory można ładować za pomocą ageMusicPlayer. Ten to również obiekt pozwala wybrać i zacząć odtwarzanie losowego utworu załadowanego do listy lub też odtwarzanie utworu o konkretnym numerze. Opcjonalnie można także ustawić losowanie następnego (innego niż przed chwilą grał) utworku. W ten sposób otrzymujemy coś na kształt MP3 player’a ^^

Klasy od dźwięku wymagają jeszcze drobnych usprawnień i kosmetycznych zmian, ale już potrafią zrobić trochę hałasu 🙂

To właściwie tyle z rzeczy które ostatnio robiłem. Teraz powinienem dopracować menedżer zasobów oraz odtwarzanie dźwięku, a później… to się jeszcze zobaczy ^^

AGE

Niestety nie było mnie stać na wymyślenie jakiegoś ciekawego tytułu notki więc niestety jest jaki jest… Ale nie tytuł jest najważniejszy! Zebraliśmy się tutaj, aby dowiedzieć się czegoś na temat tego co dzieje się z AGE.

Na początek – postanowiłem wreszcie porzucić zestaw GEdit+Makefile na rzecz środowiska Code::Blocks. Na początku w GEdicie było fajnie, ale niestety w miarę jak rozrastał się projekt przestał mi wystarczać taki zestaw ^^

Drugą, równie ważną, sprawą, jest to, że sprawdziłem wczoraj wieczorem (ok – w nocy) czy AGE skompiluje się pod Windowsem. Bałem się, że nie będzie to należało do przyjemnych doświadczeń. Jak się okazało – nie taki diabeł straszny jak go malują 🙂 Najwięcej czasu zajęło mi ściąganie bibliotek SDL oraz Code::Blocks pod windowsa 😉 Potem stworzyłem projekt, dodałem pliki z kodem źródłowym i włączyłem kompilację. Wyrzucił kilka warning’ów odnośnie porównywania signed-unsigned, i jeden błąd.

Okazało, się że w użyłem w jednym miejscu nazwy jaka istniała już jako definicja preprocesora w windows.h. Na szczęście poprawienie tego stanu rzeczy nie zajęło więcej niż minutę. Ponowna próba kompilacji i…. udało się 🙂 AGE skompilowało się na Windows z drobnymi poprawkami!

Okazuje się, że decyzja o użyciu SDL+OpenGL była całkiem dobra – przynajmniej względem przenośności kodu. Osiągnąłem całkiem zadowalające efekty dość niskim kosztem.

Ech.. uruchomienie tego samego kodu i zobaczenie go w akcji w 2 systemach sprawia ogromną radochę 😉 Polecam wszystkim wypróbowanie ^^