[Gothic 1/2] Nowy system muzyczny 2083 4

O temacie

Autor Siemekk

Zaczęty 29.09.2018 roku

Wyświetleń 2083

Odpowiedzi 4

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2153
Propsy1150
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer

Siemekk
Złote Wrota

[Gothic 1/2] Nowy system muzyczny
2018-09-29, 19:46(Ostatnia zmiana: 2018-10-20, 20:25)
Każdy kto kiedykolwiek zajmował się dodawaniem nowego soundtracku do tej gry wie jaka jest to katorga.  Dzięki inspiracji skryptami z Czasu Zapłaty opracowałem sposób na dodanie soundtracku bez większego kombinowania. System opatentowany jest na bibliotece BASS oraz Ikarusie / AST ("Union"). Tutorial będzie podzielony na wiele części. Kolejne będą ukazywać się z czasem. Pierwsza część będzie oparta na Ikarusie, druga zaś na AST / Union.
(Jutro dojdą screeny w celu jaśniejszego przekazu 29-09-2018)

Uwaga!
Zastrzegam sobie tutorial i nie zezwalam na kopiowanie go bez zgody na inne fora. Dodatkowo, jeżeli użyjesz tego pakietu warto wspomnieć kto jest jego autorem.

1.1 Inicjacja biblioteki
Zacznijmy od tego co będzie nam potrzebne:
Ikarus 1.2
Biblioteki muzyczne

Po pobraniu plików inicjujemy Ikarusa, oraz wrzucamy biblioteki do folderu "SYSTEM" gry. Teraz zaczynamy pracę. W folderze "...\_work\Data\Scripts\Content\" tworzymy sobie folder o nazwie "Music". W podanym folderze tworzymy trzy pliki:
"Music_Core.d"
"Music_Zones.d"
"Music.src"
Otwieramy plik "Music.src" i definiujemy pliki które parser ma sprawdzać w następującej kolejności:
Music_Zones.d
Music_Core.d
Po wykonaniu operacji w pliku .src, otwieramy plik Gothic.src w celu dopisania pliku "Music.src", aby parser mógł go odczytać. Ma to wyglądać mniej więcej tak:
_Intern\Ikarus.d
[...]
Music\Music.src
Story\Startup.d
[...]
Czas rozpocząć pisanie kodu. Otwórzmy plik Music_Core.d Zdefiniujmy w nim pięć zmiennych:
var int CMusic_Lib; //Pointer do biblioteki
var int CMusic_PlayMusic; //Pointer do funkcji biblioteki, która odtwarza soundtrack
var int CMusic_SetVolume; //Pointer do funkcji biblioteki, która ustawia głośność muzyki
var int CMusic_Tidy; //Pointer do funkcji biblioteki, która odpowiada za poprawne działanie biblioteki
var int CMusic_SetFolder; //Pointer do funkcji biblioteki, która ustawia folder w którym znajduje się muzyka.
Nie jest, to łatwe dla ludzi którzy nie rozumieją Ikarusa i wstrzykiwania bibliotek. Jednak, jest to wymagane. Kolejne kroki dla zielonych będą po prostu czarną magią. Definiujemy funkcję odpowiedzialną za inicjowanie biblioteki.
func void CMusic_InitLibrary()
{
CMusic_Lib = LoadLibrary("CMusic.dll"); // Załadowanie danych biblioteki do zmiennych

//Jeżeli biblioteka nie zostanie załadowana, to skrypt zostanie zatrzymany!
if(!CMusic_Lib) {
MEM_Error("CMusic:: Library was not loaded!");
return;
};
//Biblioteka została załadowana poprawnie więc teraz
//zapisujemy wskaźniki funkcji z biblioteki do zmiennych (WinApi)

//Typ funkcji razem z argumentami zostały podane w komentarzach obok
CMusic_PlayMusic = GetProcAddress(CMusic_Lib, "PlayMusic"); //void (char*, float, int)
CMusic_SetVolume = GetProcAddress(CMusic_Lib, "SetVolume"); //void (float)
CMusic_Tidy = GetProcAddress(CMusic_Lib, "Tidy"); //void ()
CMusic_SetFolder = GetProcAddress(CMusic_Lib, "SetFolder"); //void (char*)

//Nazwy funkcji są pobrane z biblioteki, można je odczytać z kodu źródłowego, lub za pomocą programu IDA.
};
Posiadamy naszą funkcję, teraz wywołajmy ją, aby dostać dane do zmiennych. Otwieramy plik Startup.d i w funkcji Init_Global (W Gothic 1 musimy takową stworzyć, zaawansowany modder będzie wiedział jak, jeżeli jesteś nierozgarniętym modderem - załóż temat jak stworzyć takową funkcję), inicjujemy Ikarusa i system muzyczny:
func void Init_Global()
{
[...]
MEM_InitAll(); // Inicjowanie Ikarusa
CMusic_InitLibrary(); // Inicjowanie systemu muzycznego.
[...]
};
Tak więc teraz mamy zainicjowaną bibliotekę odtwarzania dźwięku. Możemy teraz przejść do kolejnego kroku - "Wywołanie funkcji z biblioteki"
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2153
Propsy1150
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
1.2 Wywołanie funkcji z biblioteki
Udało nam się dostać do wartości w bibliotece, teraz należy ich użyć. Jak wiadomo Ikarus posiada metody wywołujące funkcje z WinApi. Dzięki temu możemy wywołać funkcję z dowolnej biblioteki DLL. Zacznijmy od podstaw - zobaczmy jakie argumenty ma nasza funkcja PlayMusic.
Cytuj
void (char*, float, int)
Tak więc nasza funkcja jest typu void, pierwszym argumentem jest ciąg znaków, drugim liczba zmiennoprzecinkowa, a ostatnim liczba (Dokładnie 1 lub 0). Rozpocznimy więc pracę z Ikarusem. Nasza funkcja która odtworzy muzykę wygląda w następujący sposób:
func void CMusic_Play(var string file, var int vol, var int IsInstant)
{
CALL_IntParam(IsInstant);
CALL_PtrParam(vol);
CALL_cStringPtrParam(file);
CALL__cdecl(CMusic_PlayMusic);
};
Jak widzimy, taki kod wywoła nam funkcję z biblioteki, która odpali dany plik muzyczny. Dla niektórych może być to nie zrozumiałe więc postaram się to wyjaśnić tym obrazkiem:
Spoiler

Jest to uproszczenie - przedstawia to jak sprawić, aby funkcja z biblioteki wyglądała TAK SAMO w skryptach gry.
Dodatkowo, parser czyta argumenty od tyłu, dlatego pierwszym argumentem wysłanym do biblioteki jest "IsInstant".
Spoiler

Chyba przedstawiłem to w dość jasny sposób.
Zadanie dla ciebie - wywołaj pozostałe funkcje biblioteki opierając się na tym poradniku :) W razie problemów, lub stworzenia funkcji napisz do mnie na Discordzie bądź na forum :) Zobaczymy czy zrozumiałeś lekcję.

Wyjaśnienie funkcji CALL_*
Cytuj
CALL_IntPtrParam - dla następnego CALL'a, popchnij zmienną typu int na stos
CALL_PtrParam - dla następnego CALL'a, popchnij wskaźnik na stos (to samo co IntParam);
CALL_cStringPtrParam - dla następnego CALL'a, popchnij wskaźnik typu char* z danej zmiennej typu string(tłumaczenie dokładne funkcji to CALL_charStringPtrParam)
CALL__cdecl - konwencja wywołania, funkcja nie jest metodą więc jest typu cdecl
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Splash

Splash

Moderator
posty4203
Propsy3385
ProfesjaNierób
  • Moderator
Do czego jest funkcja Tidy? Jakiś reset czy cuś?
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2153
Propsy1150
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
Odpowiada za porządkowanie soundtracków - musi być wywołana co 1/8 sekundy.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2153
Propsy1150
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
O dziwo po kilku latach biblioteka przestała działać...
Ta wersja jest naprawiona i odtwarza już normalnie dźwięk.

Nowa wersja.
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry