Wingamelauncher, czyli skrypty wspierające automatyczne uruchamianie gier Windows spod Linuksa

Pomiń gadaninę i przejdź do konkretów

Tak się złożyło, że kontynuuję temat zmian “systemowych” (poprzednio przechodziłem na niewspieranego przez Xperię X10 Android 4 ICS) – po raz kolejny w życiu próbuję przenieść cały swój “ekosystem” pod Linuksa.

Zawsze dużo korzystałem z Linuksów, a w ostatnim czasie stan ten osiągnął apogeum. Systemy uniksowe mają sensowną organizację, szybki i sprawny rozwój, wspaniałego basha i tuziny innych rozwiązań (repozytoria, żeby wspomnieć najbardziej bolesny chyba brak), które mnie zdecydowanie przekonują. Doszło do tego, że do większości operacji typu kopie zapasowe, synchronizacja danych, zacząłem pisać skrypty bashowe, uruchamiane w Cygwinie (upraszczając, jest to warstwa tłumacząca polecenia linuksowe na Windows).

Co kilka lat próbowałem przenosić swój ekosystem na Linuksa, ale koniec końców zawsze miałem jakiś krytyczny problem z obsługą swojego sprzętu i mówiłem sobie “kiedyś” – w końcu to “kiedyś” nadeszło.

Zawsze coś…

Nie chcę się skupiać na wszystkich narzędziach, z których korzystam – na to jeszcze będzie czas, próbuję dostosować jakieś IDE pod siebie, przenieść swoje prototypy gier na silniki OpenGL-owe, generalnie jest jeszcze za wcześnie.

Skoncentruję się za to na nieoczywistym rozwiązaniu, które sobie wprowadziłem – tytułowym zestawie skryptów do szybkiego przełączania się pod Windows i automatycznego uruchamiania gier wideo, klikając tylko na skrót w Linuksie.

Dlaczego w ogóle mam taką potrzebę? Nigdy nie jest idealnie – w PC mam kartę graficzną ATI Radeon HD 4850, która po przejęciu przez AMD jest niezbyt wspierana przez producenta, przez co sterowniki działają, powiedzmy, tak sobie – nie mogę grać poprzez WINE z wydajnością, która by mnie satysfakcjonowała.

Rozwiązanie!

Oczywistym jest więc, że przełączam się na Windows w celu rozrywki growej.

Uważam za skrajnie niewygodne konieczność opuszczenia systemu, następnie odczekania kilku minut na możliwość ledwo zalogowania się do Windows, odczekania kolejnej chwili na załadowanie się podstawowych usług, żeby w końcu móc włączyć – ręcznie – wybrany tytuł.

Moje rozwiązanie na pewno nie jest idealne, ale sprawia, że włączenie gry spod Linuksa to wybranie skrótu i odczekanie chwili, po której odpowiednia gra jest uruchomiona i czeka na użytkownika.

Część 1 – Rozbieranie Windows

Niezbędna jest pewna konfiguracja Windowsa – na moim PC stacjonuje Windows 8 z Classic Shell, który pomija ekran startowy.

1. Wyłączyłem konieczność logowania w Windows – niestety jest to niezbędne, aby rozwiązanie było wygodne.

* Wciskamy Win+R, żeby uruchomić menu uruchamiania, wpisujemy “control userpasswords2”;
* W wyświetlonym oknie odznaczamy opcję “Users must enter a user name and password to use this computer” (mam angielskiego windowsa, opcja po polsku opisana będzie podobnie do “użytkownicy musza podać nazwę użytkownika i hasła, by używać tego komputera”).

2. Utworzyłem plik skryptowy wingamelauncher.bat (treść na razie nie jest istotna, może być pusty), utworzyłem do niego skrót i umieściłem go w windowsowym autostarcie.

3. Utworzyłem w tej samej lokalizacji, co wingamelauncher.bat, drugi skrypt – “recreatewgl.bat” o takiej treści:

DEL H:\wingamelauncher.bat
ECHO start calc.exe>H:\wingamelauncher.bat

Oczywiście ścieżkę trzeba zmodyfikować pod swoją lokalizację. Skrypt ten będzie uruchamiany po włączeniu gry, modyfikując wingamelauncher.bat aby nie włączyła się automatycznie ponownie. Zamiast niej będzie odpalony kalkulator – takie tymczasowe rozwiązanie.

Część 2 – Ubieranie Linuksa

1. Tutaj było znacznie więcej zabawy. Zacząłem od zerknięcia do GRUBa, którym wpisem jest u mnie Windows, a którym Linuks – standardowo będzie to wpis trzeci i pierwszy.

Numery te trzeba podać w kolejności od zera – więc 2 i 0.

2. Edytowałem (jako root) plik /etc/default/grub, żeby ustalić zapisywanie ostatniej ładowanej pozycji – by móc je modyfikować z poziomu skryptów.

sudo gedit /etc/default/grub

Zakomentowałem linijkę:

GRUB_DEFAULT="0"

I dodałem inną:

GRUB_DEFAULT="saved"

3. Uwaga, to nie jest ładne rozwiązanie – edytowałem pętle GRUBa 2, aby przywracać domyślne ustawienie po wybraniu innej opcji. Jeśli nie przeszkadza Ci fakt, że po uruchomieniu skryptu domyślnie będzie wybierany Windows, możesz tego rozwiązania nie stosować.

To rozwiązanie ma sporą wadę, m.in. dlatego, że będzie kasowane przez system przy każdej aktualizacji GRUBa – jeśli opracuję inną metodę, to oczywiście polecę.

Otworzyłem plik /boot/grub/grub.cfg:

sudo gedit /boot/grub/grub.cfg

Znalazłem wpisy dla moich systemów (rozpoczynają się od “menuentry”):

menuentry 'Linux Mint 14 Cinnamon 64-bit, 3.5.0-17-generic (/dev/sda8)' --class linuxmint --class gnu-linux --class gnu --class os {
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos8'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos8 --hint-efi=hd0,msdos8 --hint-baremetal=ahci0,msdos8 e3df731f-6c30-4b10-8088-e7d0311c4102
else
search --no-floppy --fs-uuid --set=root e3df731f-6c30-4b10-8088-e7d0311c4102
fi
linux /boot/vmlinuz-3.5.0-17-generic root=UUID=e3df731f-6c30-4b10-8088-e7d0311c4102 ro quiet splash $vt_handoff
initrd /boot/initrd.img-3.5.0-17-generic

}

Dodałem polecenie “savedefault 0“, które sprawiło, że po wybraniu pozycji, ustawienie będzie zresetowane i następnym razem w GRUBie zostanie wybrana automatycznie pierwsza opcja (z indeksem 0).

menuentry 'Linux Mint 14 Cinnamon 64-bit, 3.5.0-17-generic (/dev/sda8)' --class linuxmint --class gnu-linux --class gnu --class os {
savedefault 0
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='hd0,msdos8'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos8 --hint-efi=hd0,msdos8 --hint-baremetal=ahci0,msdos8 e3df731f-6c30-4b10-8088-e7d0311c4102
else
search --no-floppy --fs-uuid --set=root e3df731f-6c30-4b10-8088-e7d0311c4102
fi
linux /boot/vmlinuz-3.5.0-17-generic root=UUID=e3df731f-6c30-4b10-8088-e7d0311c4102 ro quiet splash $vt_handoff
initrd /boot/initrd.img-3.5.0-17-generic

}

Analogiczną zmianę wykonałem dla wpisu Windows – powinien znajdować się jeden-dwa bloki niżej.

4. Edytowałem uprawnienia dla uruchamianie komend w pliku /etc/sudoers, żeby skrypty mogły uruchamiać się bez zapytania o hasło administratora:

sudo gedit /etc/sudoers

Na końcu pliku, przed komendą “#includedir /etc/sudoers.d”, dodałem następujące wiersze:

draiser ALL=(ALL)NOPASSWD:/usr/bin/wingamelauncher
draiser ALL=(ALL)NOPASSWD:/home/draiser/Skrypty/wingamelauncher.sh
draiser ALL=(ALL)NOPASSWD:/usr/sbin/grub-reboot
draiser ALL = NOPASSWD: /sbin/shutdown
draiser ALL=NOPASSWD: /usr/sbin/s2disk

Gdzie “draiser” to nazwa mojego użytkownika (można podać też “ALL” jako zamiennik dla wszystkich użytkowników), a skrypty podane po “NOPASSWD:” to moje lokalizacje skryptu, który zaraz będę prezentował, dodatkowo także odnośniki do systemowych funkcji rebootu ze zmianą kolejności w GRUB, wyłączania systemu i hibernacji.

5*. Krok opcjonalny – s2disk, czyli hibernacja przed ponownym uruchamianiem

Początkowo napisałem skrypt tak, aby po prostu restartował system, ale oczywiście zdecydowanie wygodniej jest, kiedy zapisuje stan pamięci na dysku, a następnie, już po ponownym włączeniu Linuksa, powraca do niego.

Do tego rozwiązania potrzebna jest partycja SWAP o rozmiarze zbliżonym do ilości pamięci RAM w PC, a także pakiet uswsusp, który instalujemy metodą:

sudo apt-get install uswsusp

Jest on konfigurowany po instalacji (wystarczy podać mu lokalizację partycji swap w formacie /dev/sdXY, np /dev/sda1) i następnie nadaje się do użytku.

6. Napisałem następnie właściwy skrypt, który miał za zadanie utworzyć plik wingamelauncher.bat (usuwając poprzednio istniejący) dla Windowsa, wybrać pozycję w GRUBie na Windows i wreszcie zrestartować system – albo korzystając z hibernacji (patrzy krok 5), albo standardowo.

#!/bin/sh
#wingamelauncher - sh linux part
#by dRaiser
#http://draiser.net
if [ -f /mnt/Multimedia/wingamelauncher.bat ]
then
rm /mnt/Multimedia/wingamelauncher.bat
fi
echo "\"$1\"\r\nrecreatewgl.bat" > /mnt/Multimedia/wingamelauncher.bat
sudo grub-reboot 2
#sudo shutdown -r now
sudo s2disk -P 'shutdown method = reboot'

Potrzebne są w nim 3 modyfikacje – czyli podanie właściwej lokalizacji pliku wingamelauncher.bat z punktu widzenia Linuksa – u mnie to punkt montowania “/mnt/Multimedia”, a następnie, w zależności od wybranej metody rebootu:

1) Dla hibernacji przed rebootem, z użyciem pakietu uswsusp, pozostawienie bez zmian;
2) Dla rozwiązania bez hibernacji – usunięcie albo zakomentowanie znakiem “#” linijki “sudo s2disk(…)”, za to odkomentowanie (usunięcie znaku “#”) linijki “sudo shutdown -r now”.

7. Następnie umieściłem link symboliczny do skryptu w katalogu /usr/bin, żeby był wygodnie uruchamiany z dowolnego miejsca w systemie:

sudo ln -s /home/draiser/Skrypty/wingamelauncher.sh /usr/bin/wingamelauncher

Gdzie “/home/draiser/Skrypty/wingamelauncher.sh” to oczywiście fizyczna lokalizacja zapisanego skryptu.

8. Pozostał w zasadzie tylko ostatni krok, tj. utworzenie aktywatora (skrótu) do uruchamiania konkretnej gry. W każdym środowisku graficznym tworzenie launchera wygląda podobnie, pozwolę sobie więc podać wyłącznie schemat polecenia aktywatora:

wingamelauncher "H:\Program Files\Diablo III\Diablo III\Diablo III.exe"

Gdzie ścieżka podana jako parametr polecenia to fizyczna lokalizacja pliku uruchomieniowego gry – widoczna dla Windows.

Na koniec

Jeśli wszystko poszło poprawnie, to uruchomienie skryptu powinno bezproblemowo zamknąć (albo zahibernować) Linuksa, wybrać w GRUB automatycznie Windows, uruchomić go, zalogować się, włączyć launcher Diablo 3. Słowem – wystarczy wyklikać skrót i zrobić sobie kilkuminutową przerwę, a następnie można już siekać bestie. :)

Niegłupim pomysłem jest odchudzenie Windowsa, żeby uruchamiał się możliwie najszybciej, powyłączanie zbędnych usług, et cetera.

Rozwiązanie powinno działać zarówno pod GRUB, jak i GRUB2; systemami debianopochodnymi, jak i resztą.

Zdaję sobie sprawę, że pewnie całą sprawę można rozwiązać lepiej/prościej – pisałem w bashu zawsze “przy okazji” i dopiero zaczynam bawić się weń na poważniej, ale nie znalazłem gotowego rozwiązania dla tego problemu – może komuś, poza mną, się ono przyda. Oczywiście można w ten sposób uruchomić cokolwiek, nie tylko gry. ;)

Grafika pochodzi z artykułu Blizzard sprawdzi się na Linuksie w 2013.

Leave a Reply

Your email address will not be published. Required fields are marked *