Suatu kali, setelah cukup melihat segala macam "Sementara semua orang bermain," Saya juga ingin memainkan pi Raspberry saya. Ya, tidak hanya bermain, tetapi bermain menggunakan perangkat nyata. Mengapa di kereta bawah tanah untuk 150 rubel joystick dibeli dari Dandy (well, bukan dari pesolek, tapi Simbas Junior). Mereka yang tertarik dengan apa yang datang dapat mengklik tombol di bawah ini. Di akhir artikel akan ada tautan ke buktinya.Teman-teman Cina kami, mengumpulkannya dengan moto - tidak ada kualitas, tetapi Anda bertahan. Segera kabel asli disolder dengan penampang konduktor 2 mikron persegi, dan diganti dengan kabel dari beberapa konverter antarmuka industri, yang didapat setelah commissioning berikutnya, hanya memiliki 5 kabel.Sebelum Anda membuat perubahan pada kode, Anda harus mengetahui cara kerja gamepad itu sendiri. Gamepad memiliki register geser. Gamepad memiliki 5 kabel - 2-daya, 3 informasi - Latch (Strobe), clock (Pulse) dan data. Ketika unit logis dipasok ke Latch, keadaan input register geser disimpan, dan pada output - data, status tombol "A" segera tersedia, dan ketika level logis pada garis jam pada output - perubahan data, level tegangan yang sesuai dengan keadaan tujuh tombol lainnya muncul dalam bentuk berurutan. Tombol yang ditekan sesuai dengan - 0, tidak ditekan - 1. Selain itu, untuk permainan semuanya justru sebaliknya, perlu untuk melakukan inversi. Gambar di bawah ini menunjukkan diagram gamepad.
Kemudian diikuti pilihan emulator. Pilihannya jatuh pada versi fceu lama 0.98.12, karena memiliki modularitas yang sangat baik dan mengemulasi arsitektur konsol dengan cukup akurat, dan ditulis dalam C. Ini diikuti oleh pilihan perpustakaan untuk bekerja dengan GPIO, saya memilih bcm2835 dari Mike McCauley, yang juga ditulis dalam C dan memiliki kinerja yang baik.Karena saya seorang pemula dalam pemrograman, saya harus beralih ke salah satu selebritas dari “Sementara semua orang” bermain, dengan permintaan untuk mengomentari bagian kode. Dan cungkil hidung Anda ke fungsi-fungsi yang bertanggung jawab untuk mentransmisikan keadaan tombol ke gim. Mereka menjelaskan kepada saya dalam bahasa yang dapat diakses apa dan bagaimana. Jadi, file input.c bertanggung jawab untuk meniru input, dan di sini perubahan utama akan terjadi dengannya. Ada beberapa fungsi yang bertanggung jawab untuk mensimulasikan gamepad - FCEU_UpdateInput, ReadGP dan DECLFW (4016), pada kenyataannya, ada lebih banyak, ini adalah yang utama. Selain input.c, saya harus membuat perubahan ke file.c dan fceu.c. Dalam kasus pertama, ada kesalahan dalam file file.c, tetapi masalah ini adalah google, ada patch untuk file ini, dan dalam file fceu.c saya menambahkan inisialisasi pustaka bcm2835 dalam fungsi int FCEUI_Initialize (void):bcm2835_init();
Pra-menambahkan file header-nya#include <bcm2835.h>
Sekarang input.c, saya juga menambahkan file header library bcm2835 (mirip dengan fceu.c) dan file header library <unistd.h> agar berfungsi dengan usleep. Selanjutnya, saya mengumumkan port GPIO yang akan terlibat: #define LATCH RPI_V2_GPIO_P1_11
#define CLK RPI_V2_GPIO_P1_13
#define DATA RPI_V2_GPIO_P1_15
Dalam fungsi void InitializeInput (void), saya menambahkan kode di mana saya mendaftarkan mode operasi setiap port GPIO, dan segera mengatur ulang port yang bertanggung jawab untuk Latch (Strobe) dan jam ke 0. bcm2835_gpio_fsel(LATCH, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(CLK, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(DATA, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(DATA, BCM2835_GPIO_PUD_UP);
bcm2835_gpio_write(CLK, LOW);
bcm2835_gpio_write(LATCH, LOW);
Sekarang ke fungsi:Dan DECLFW (4016) - bertanggung jawab untuk mensimulasikan sinyal Latch (Strobe). Seperti yang dikatakan, untuk membaca keadaan tombol yang perlu Anda terapkan ke Latch - 1 untuk sementara waktu. Ada variabel Laststrobe di mana nilai terakhir yang ditulis untuk register ini ditulis. Jika Laststrobe bernilai 0, maka logis 1 ditulis, masing-masing, dan pin GPIO, yang disebut Latch, juga diumpankan 1 dan setelah 1 μs diatur ulang ke 0. Dan jika Laststrobe sama dengan 1, maka bagian kode ini diabaikan.static DECLFW(B4016)
{
if (FCExp)
if (FCExp->Write)
FCExp->Write(V & 7);
if (JPorts[0]->Write)
JPorts[0]->Write(V & 1);
if(JPorts[1]->Write)
JPorts[1]->Write(V&1);
if((LastStrobe&1) && (!(V&1)))
{
if(JPorts[0]->Strobe)
JPorts[0]->Strobe(0);
if(JPorts[1]->Strobe)
JPorts[1]->Strobe(1);
if(FCExp)
if(FCExp->Strobe)
FCExp->Strobe();
}
if (LastStrobe==0)
{
bcm2835_gpio_write(LATCH, HIGH);
usleep(1);
bcm2835_gpio_write(LATCH, LOW);
}
LastStrobe=V&0x1;
}
Nah, sekarang polling joystick itu sendiri, batal FCEU_UpdateInput (void) - dalam fungsi ini, data dibaca dari driver input yang dipilih ketika emulator dikonfigurasikan, atau ketika dimulai dengan memasukkan kunci tertentu, misalnya, gamepad, turnpad, pistol ringan, dll. ., semua itu dapat dihubungkan ke konsol. Di dalamnya, byte status tombol gamepads joy [0] ... joy [3] terbentuk, dalam jumlah dari 2 hingga 4, karena Anda dapat mengaktifkan emulasi Pribluda untuk menghubungkan 2 gamepads lebih. Di sinilah perubahan utama terjadi. Karena saya tidak perlu menggunakan kemampuan untuk bekerja dengan 4 gamepad dan menerima data dari driver lain, saya membuang semua kode dan memasukkan milik saya: joy[0] = 0;
joy[1] = 0;
for (i = 0; i <= 7; i++)
{
joy[0] ^= bcm2835_gpio_lev(DATA) << i;
joy[0] ^= (1 << i);
joy[1] ^= bcm2835_gpio_lev(DATA) << i;
joy[1] ^= (1 << i);
bcm2835_gpio_write(CLK, HIGH);
usleep(1);
bcm2835_gpio_write(CLK, LOW);
usleep(1);
}
Selain itu, saya langsung membentuk dua byte, masing-masing, dari joystick pertama dan kedua. Karena banyak permainan membaca status tombol dari 2 port secara bersamaan, bagi mereka tidak ada konsep port prioritas. Tetapi ada permainan yang memiliki konsep seperti itu - misalnya, semua Mario, Kirby, Terminator 2, dll. Artinya, mereka membaca keadaan tombol hanya dari port pertama (di Mario untuk pemain pertama, untuk yang kedua hanya dari yang kedua), yaitu, dari register 4016. Penting juga untuk menetapkan nilai nol ketika fungsi ini dipanggil, jika tidak nilai sebelumnya akan disimpan di dalamnya, dan baru sudah akan ditumpangkan pada mereka. Pada prinsipnya, dimungkinkan untuk meninggalkan byte untuk joystick kedua sama dengan nol, tapi saya membuatnya mungkin untuk bermain Mario bersama.ReadGP - sudah mengekstrak bit dari byte joy [0] ... joy [3], dan variabel ret mengembalikan keadaan tombol spesifik saat ini ke gim, nomor tombol diatur oleh variabel joy_readbit [w], di mana w adalah nomor port dari joystick, pertama atau kedua Namun dalam fungsi ini saya tidak melakukan perubahan. Ditinggalkan apa adanya.Untuk kompilasi yang berhasil, dalam Makefile (dibentuk setelah menjalankan perintah Configure), yang terletak di direktori src, Anda perlu menambahkan -lbcm2835 -lm -lrt ke tempat di mana dependensi pustaka ditulis. Baris:LIBS =
Dan secara umum, semuanya bekerja. Saya meninggalkan dasar jika tiba-tiba saya memutuskan untuk membeli joystick kedua untuk bermain bersama di tank yang sama.» Tautan ke bukti
» Data dari situs digunakan
»Terima kasih khusus kepada orang ini yang membantu saya memahami kode emulator