[Zrób to sam] Arkanoid Controller
*

Offline kryniors

  • 2
  • papug
[Zrób to sam] Arkanoid Controller
« dnia: Stycznia 26, 2024, 12:30:01 »
Cześć!

Odkąd wszedłem w posiadanie Famicoma zastanawiałem się jak to jest grać w Arkanoid w sposób jaki mieli na myśli twórcy, czyli z dedykowanym kontrolerem dołączonym do gry w oficjalnej dystrybucji. Taki kontroler był zbudowany z dwóch timerów, licznika oraz rejestru przesuwnego (https://www.nesdev.org/wiki/Arkanoid_controller#Hardware).

Przeglądając internet natrafiłem na projekt repliki kontrolera dla portu gry na komputery MSX, opartym na mikrokontrolerze ATtiny85. Ponieważ kontrolery w wersji dla MSX i Famicoma nie różnią się zbytnio od siebie, w teorii powinno być możliwe dostosowanie projektu pod Famicoma.

Z przyjemnością mogę stwierdzić, że to się udało, a efekt prac zamieściłem na swoim GitHubie.

Co jest potrzebne?
  • 1 x Płytka Digispark ATtiny85
  • 1 x Potencjometr liniowy 10kΩ 1/8W
  • 1 x Rezystor 1kΩ 1/8W
  • 1 x Przycisk (przełącznik ON-OFF chwilowy)
  • 1 x Kabel DA-15
  • 1 x Plastikowa obudowa 97x63x30mm (takiej użyłem ja, jednak oryginał jest dużo dłuższy)

Wszystkie komponenty za wyjątkiem kabla kupiłem w Botlandzie (to nie jest reklama). Kabel DA-15 to zwykły przedłużacz dla portu rozszerzeń dla Famicoma lub kontrolera dla Neo-Geo do dostania na Aliexpress.

Schemat połączenia


Do pinu P3 płytki Digispark podłączony jest potencjometr i napięcie na tym pinie jest mierzone przez przetwornik analogowo-cyfrowy. Gdy gra chce zresetować i uruchomić na na nowo zliczanie aktualnej pozycji paletki, wartość "1" jest pisana pod adres $4016, aby zaraz potem być wyzerowana - to z kolei zapala pin 12 podłączony do pinu płytki pod nazwą P1. W oryginalnym kontrolerze, przez krótki czas po wyzerowaniu licznika (ok. 7 ms) stara wartość była trzymana w rejestrze przesuwnym - dlaczego to jest istotne opowiem zaraz.

Gra odczytuję pozycję paletki odpytując adres $4017 i bit 1. Każde takie odczytanie generuje impuls na pinie 9 (pin P2 na płytce), który w zamierzeniu był podłączony do rejestru przesuwnego i powodował przesunięcie bitowe o 1. Żeby odczytać 8-bitową wartość należało odpytać adres $4017 osiem razy - informacja była zapalana na pinie 7 (P0 na płytce). Ponieważ implementacja w grze sprowadzała się do odczytu pozycji zaraz po wysłania impulsu do resetu licznika, przez krótki czas były dostępne stare dane. Aby stare i nowe bity nie nakładały się na siebie w połowie, zastosowałem sztuczne opóźnienie o ok. 3 ms - jest to pierwsza istotna zmiana względem oryginału z MSX. Pin 13 jest podłączony rezystorem podciągającym bezpośrednio z przyciskiem - gdy przycisk jest wciśnięty, stan niski jest wysyłany do konsoli sygnalizując oddanie strzału, w przeciwnym wypadku otrzymywany jest ciągły stan wysoki - odzwierciedla to odczyt z adresu $4016, bit 1.

Piny P4 i P5 są niewykorzystane. Warto wspomnieć, że w klonach Digispark, stan niski na P5 powoduje reset mikrokontrolera, więc najprościej było wykorzystać inne piny - na przykład P3 lub P4 - jednak one są też używane do komunikacji USB, więc po podłączeniu potencjometra płytka nie była wykrywana w komputerze. W moim przypadku pomogło ustawienie gałki na 50% przed każdym programowaniem.

Liniowość potencjometra liniowego - albo jego brak
Po testowym odpaleniu Arkanoida zauważyłem, że paletka coraz wolnej się porusza im bardziej zbliża się do lewej ściany. Analogicznie przyspiesza im bardziej trzyma się prawej strony. Próbkując pozycję w gałki różnych miejscach i notując wartość wyjściową narysowałem charakterystykę wyjściową, która nie napawa optymizmem:


Korzystając ze skryptu w Pythonie napisanego na kolanie sporządziłem wykres, który ma pokazać jakie wartości wyjściowe przesłać do konsoli na podstawie odczytu z ADC:


Pomiędzy punktami pomiaru zastosowałem interpolację liniową - na podstawie 14 próbek wygenerowałem 1024 wartości odpowiadających 10-bitowej rozdzielczości przetwornika. Tak naprawdę rejestr przesuwny może zwrócić 9 bitów danych, jednak najmniej znaczący bit jest odrzucany przez grę, stąd w programie przesunięcie bitowe jest o zaledwie jeden (zakres na wyjściu do konsoli 0-511).

Skrypt generuje gotową tablicę przeszukiwań do wklejenia w kod źródłowy. Po jego zastosowaniu, paletka porusza się w końcu w sposób liniowy. Jednak należy mieć na uwadze, że różne potencjometry reklamowane przez producentów mogą mieć różną charakterystykę i konieczne może być dokonanie własnoręcznych pomiarów i wygenerowanie własnej tablicy LUT.

A tak wygląda końcowy projekt ;p




Link do projektu: https://github.com/kkusz/avrkanoid-fami

PS. Do grania wymagana jest japońska wersja Arkanoida, która jest również zawarta w składance 168-in-1. Można jednak w łatwy sposób spatchować amerykańską wersję, aby obsługiwała Famicomową wersję kontrolera, dla zainteresowanych mogę załączyć patcha do ROM-u.

PS2. Nadal mam trudności z przejściem trzeciego poziomu nieważne w jakiej wersji. ;p
I only meant to stay a while.

*

Offline Preki

  • **
  • 432
Odp: [Zrób to sam] Arkanoid Controller
« Odpowiedź #1 dnia: Stycznia 26, 2024, 12:42:46 »
Za ile byś taki wykonał? :D Z ciekawości pytam, chociaż czasami mam ochotę zamówić takie akcesorium, bo szczerze, kończy mi się cierpliwość do pewnego kolegi któremu zleciłem naprawę oryginalnego kontrolera jakieś... TRZY lata temu.

*

Offline OsA

  • ***
  • 590
    • #58OsA
Odp: [Zrób to sam] Arkanoid Controller
« Odpowiedź #2 dnia: Stycznia 26, 2024, 13:36:14 »
Pewnie to kwestia wprawy, ale grając na tym oryginalnym kontrolerze na zlocie - grało mi się trudniej niż na padzie.
Choć fakt, da się szybciej "przeskoczyć" z jednej strony na drugą.
Nie wiedzieliśmy, że tworzymy wspomnienia. Po prostu dobrze się bawiliśmy.

Odp: [Zrób to sam] Arkanoid Controller
« Odpowiedź #3 dnia: Stycznia 26, 2024, 16:42:54 »
Nie wszystko kumam z opisu, choćby to jak dokonać kalibracji potencjometra. Na GitHub jest podany link do ROM testowego ale i tak nie wiedziałbym jak tego użyć / wymaga to dla mnie za wiele zachodu, dlatego ustawiam się w kolejce za użytkownikiem @Preki, bo projekt wygląda na warty docenienia czymś więcej, niż dobrym słowem.

@OsA, nie tylko Tobie było trudniej. Na padzie grałem całe życie, na Vausie jakieś dwadzieścia minut, trudno oczekiwać cudów.

*

Offline Mcin

  • ***
  • 817
  • أَلْقُنْتْرابَنْديطا
Odp: [Zrób to sam] Arkanoid Controller
« Odpowiedź #4 dnia: Stycznia 26, 2024, 18:46:05 »
A więc to nie tylko ja lamiłem na kręćku :D Projekt szacowny, tylko jednej rzeczy nie dopisałeś - skąd obudowa? recykling odpadów czy druk trzy de?
@Verteks jak rozumiem, pomiary polegały na wychyleniu potencjometru i sprawdzeniu wartości. Czyli narzędzia to usb i kątomierz ;) potem interpolacja liniowa w bibliotekach pythona, można to zrobić i w excelu albo licząc na kalkulatorze, jak kto woli :P Statystycy by się załamali, co taka mała próbka robi tak blisko regresji liniowej, ale skoro działa, to działa, czyli jest dobrze.

*

Offline kryniors

  • 2
  • papug
Odp: [Zrób to sam] Arkanoid Controller
« Odpowiedź #5 dnia: Stycznia 26, 2024, 20:47:51 »
@Mcin, obudowę wziąłem stąd https://botland.com.pl/obudowy/6226-obudowa-plastikowa-kradex-z119-97x63x30mm-czarna-5905275013876.html - sam nie wiem jak została wykonana, najpewniej jest to wtrysk patrząc po śladach po frezarce na domniemanej formie (?) :D Dziury na przycisk, gałkę i kabel wydrążone wiertarko-wkrętarką.

@Verteks, dokładnie jak @Mcin wspomniał - zrobiłem serię fotek, gdzie był pokazana zarówno gałka jak i wartość odczytana przez konsolę. Kąt gałki mierzyłem wirtualnym kątomierzem (wtyczka do Chrome), gdzie wybierasz jakiś punkt odniesienia (obojętnie jaki, może to być godzina dziewiąta, ważne żeby się go trzymać) i notujesz skrupulatnie kąt od tego odniesienia dla każdej próbki. W przypadku odczytu z potencjometru posiłkowałem się ROM-em, który wypluwał 9-bitową wartość heksadecymalną, ale równie dobrze można by podłączyć potencjometr bezpośrednio do Arduino i wypisywać obecne wskazanie ADC do komputera komunikacją seryjną, albo całkiem pojechać po bandzie i użyć multimetru w trybie woltomierza - tylko nie wiem jak z dokładnością takiego pomiaru - mamy na sali metrologa?


Jeśli chcesz się przekonać jak działa ten testowy ROM, wystarczy go odpalić w Nintendulatorze i ustawieniach Input wybrać Arkanoid Controller - będzie on emulowany za pomocą myszki.

Do regresji liniowej wykorzystałem dwa punkty odniesienia - Dla dolnego progu szukałem dla jakiej pozycji gałki dostanę na wyjściu wartość 0x9C (9-bit), która w przypadku Arkanoida II oznacza minimalną wartość jaką gra uznaje (czy to prawda to dowiem się, gdy wyjmę kartridża z paczkomatu  :D ). Odczyt z ADC jest 10-bitowy, więc to równa się 0x138 (312 dec). W moim przypadku pozycja gałki przy tym punkcie to było jakieś 20 stopni counter-clockwise względem godziny 9. Górna granica, czyli 0x3FF (1023 dec), to z kolei największe odchylenie potencjometra zgodnie ze wskazówkami zegara, czyli jakieś 215 stopni.

W skrypcie pythonowskim każda próbka jest zapisana w tablicach xp i yp, natomiast punkty odniesienia do regresji liniowej są w tablicach xline i yline - to są jedyne rzeczy, które trzeba zmienić w skrypcie, aby wygenerować własnego look-up-table.

@Preki: niestety na chwilę obecną nie oferuję takich usług  :( . Samo badanie każdego z przewodów z osobna wyjęło mi pół dnia życia, jeśli znajdę sposób na mniej upierdliwe lutowanie każdego z 6 przewodów z osobna to mógłbym pomyśleć  :D

Ale żeby nie było, zamieszczam kosztorys - nie zawarłem w nim kosztów takich jak lutownica, przewody, luty, gumki termokurczliwe, gdyż kupuje się je zazwyczaj w partiach, gdzie są wykorzystywane w więcej niż jednym projekcie.
Przedłużacz DA-15   19,40  zł
Gałka potencjometru  1,38  zł
Potencjometr         1,50  zł
Przycisk             5,90  zł
Digispark ATtiny85  29,90  zł
Obudowa             11,90  zł
SUMA                69,98  zł


Jak widać, cenowo wychodzi mniej więcej ile w Japonii wołają za używany oryginał - oczywiście nie uwzględniając kosztów przesyłki ;p
I only meant to stay a while.