Obsługa inputów w moim silniku wygląda tak, że są 2 wątki, jeden nieustannie zbiera wszystkie inputy i dodaje je do kolejki (korzystam z windowsowych RAW INPUTS, obsługując komunikat WM_INPUT
), drugi zajmuje się generowaniem kolejnych klatek (logika gry, rysowanie itd.). Na początku każdej klatki następuje synchronizacja inputów, tj. zawartość kolejki zostaje przepisana do tablicy przechowującej informacje na temat stanu wszystkich klawiszy i przycisków, następnie kolejka jest zerowana. Działa to więc tak, że jeżeli w kolejce znajduje się np.:
1, "SPACJA" - wciśnięty
2. "SPACJA" - wyciśnięty
3. "SPACJA" - wciśnięty
to do tablicy trafia jedynie informacja, że w danej klatce SPACJA jest wciśnięta (czyli poszczególne przejścia są pomijane, liczy się tylko ostatni stan klawisza, jaki trafił do kolejki w chwili synchronizacji, czyli na początku klatki). Po zakończeniu klatki tablica inputów również jest zerowana, by być gotową na synchronizację kolejnych inputów w następnej klatce.
Teraz staram się dodać obsługę ruchów myszy i wydaje mi się, że takie podejście jak wyżej nie będzie dobre, bo może powodować opóźnienia albo brak odpowiedniej precyzji (co byłoby nieakceptowalne np. w FPSie). Doszedłem więc do wniosku, że muszę tu wprowadzić 2 zmiany:
- Synchronizacja nie powinna odbywać się automatycznie na początku każdej klatki, tylko ręcznie, po wywołaniu odpowiedniej funkcji np.
SynchronizeMouseMovement()
. Dzięki temu można by w jednej klatce obsłużyć więcej ruchów, zamiast przenosić je do następnej klatki (tak się dzieje w przypadku klawiszy, którym nie udało się im załapać na automatyczną synchronizację na początku danej klatki). - Obsługiwane powinny być wszystkie ruchy myszy, które odbyły się między kolejnymi synchronizacjami, a nie tylko ten ostatni (najświeższy), jak dzieje się w przypadku klawiszy. Co za tym idzie, ruchy myszy powinny mieć własną kolejkę.
Dobrze kombinuje? A jeżeli tak, to co miałbym zrobić w sytuacji, gdyby w danej klatce synchronizacja nie została wywołana? Na przykładzie pseudo kodu:
if (OknoZamkniete = true)
{
SynchronizeMouseMovement();
//Jakaś tam obsługa ruchów myszy.
}
Gdy okno jest zamknięte, ruchy są synchronizowane i obsługiwane. Jeżeli natomiast jest otwarte, ruchy myszy nie są synchronizowane, a więc gromadzą się w kolejce (być może przez bardzo długi czas) i jasnym jest, że po zamknięciu okna nie mogę one wszystkie zostać obsłużone i część powinna zostać odrzucona. Jak zaprojektować taki mechanizm, żeby jednocześnie nie pominąć żadnych ruchów, które powinno zostać obsłużone?
Jeżeli ktoś ma jakieś doświadczenia w zakresie obsługi myszy na potrzeby gier (albo czegoś podobnego, co wymaga precyzji), proszę uprzejmie o jakieś wskazówki.