Saya telah merancang perangkat game genggam saya sendiri yang berbasis mikrokontroler AVR dan layar OLED kecil.
Saya mulai dengan layar monokrom 128x64 piksel dan dapat dengan nyaman menggambar di lebih dari 60 frame per detik.
Baru-baru ini saya mengolahnya kembali menggunakan RGB OLED, 128x128 piksel tanpa terlalu banyak berpikir hanya untuk mengetahui bahwa saya hanya dapat mencapai sekitar 4 FPS. Setelah beberapa pemikiran dan refactoring yang hati-hati saya bisa mencapai ~ 12fps jika saya tidak terlalu peduli melakukan hal lain!
Pertanyaan saya adalah - bagaimana perangkat seperti GBA (Game Boy Advance) mencapai frame rate hampir 60fps? Saya berpikir untuk memiliki 'prosesor grafis' yang terpisah tetapi menyadari bahwa saya masih akan mengalami hambatan mentransfer data tampilan ke itu.
Saya juga bertanya-tanya tentang menggunakan antarmuka paralel 8-bit vestigial yang cenderung dimiliki oleh sebagian besar layar ini, yang mungkin menambah kecepatan saya 8x, kecuali bahwa MCU modern tidak cenderung memiliki antarmuka paralel perangkat keras seperti yang mereka lakukan untuk serial dan bit- Membenturkan kemungkinan akan memakan banyak kenaikan kecepatan.
Apa pilihan lain yang ada?
Saat ini saya menggunakan ATmega1284P yang terhubung ke pengontrol OLED SSD1306 via USART-SPI. Itu versi monokrom.
Layar warna adalah SSD1351, awalnya tidak terhubung ke perangkat keras SPI. Saya tidak yakin itu akan membuat perbedaan yang cukup , itu terlalu lambat secara keseluruhan
Saya tahu saya bisa mendapatkan MCU yang lebih cepat, tetapi saya ingin tahu opsi apa yang bisa saya jelajahi - prosesor GBA jauh lebih lambat daripada 1284 saya!
sumber
Jawaban:
Jawaban lain mencakup pertanyaan Anda dengan cukup baik pada tingkat abstrak (perangkat keras), tetapi memiliki pengalaman aktual dengan GBA khususnya saya pikir penjelasan yang lebih rinci mungkin bernilai sementara.
GBA memiliki banyak mode dan pengaturan gambar yang dapat digunakan untuk mengontrol bagaimana prosesor grafis menafsirkan RAM video, tetapi satu hal yang tak terhindarkan: kecepatan bingkai. Prosesor grafis sedang menggambar ke layar dalam loop konstan hampir (lebih lanjut di bawah ini). (Ini kemungkinan bit yang paling relevan untuk pertanyaan Anda.)
Itu akan menarik satu baris pada satu waktu mengambil istirahat sangat singkat antara masing-masing. Setelah menggambar garis terakhir untuk bingkai itu akan membutuhkan istirahat kira-kira sama dengan waktu yang dibutuhkan untuk menggambar 30 garis. Kemudian mulai lagi. Waktu dari setiap baris, dan waktu dari masing-masing bingkai sudah ditentukan sebelumnya dan ditetapkan di atas batu. Dalam banyak hal prosesor grafis benar-benar menguasai sistem itu dan Anda perlu menulis gim Anda di sekitar perilakunya, karena itu akan terus melakukan apa yang dilakukannya apakah Anda siap atau tidak.
Sekitar 75-80% dari waktu itu secara aktif mendorong ke layar. Berapa frame rate yang bisa Anda capai jika Anda melakukan hal yang sama?
80% dari waktu itu juga merupakan hal yang harus dilakukan CPU untuk memproses input pengguna, menghitung keadaan gim, dan memuat sprite / ubin ke area VRAM yang saat ini mati layar (atau setidaknya tidak termasuk dalam garis saat ini sedang ditarik).
20% antar frame, semua CPU harus mengubah pengaturan video atau RAM yang akan mempengaruhi seluruh frame berikutnya.
Pada akhir setiap baris, prosesor grafis akan mengirimkan interupsi sinkronisasi saluran ke CPU. Interupsi ini dapat digunakan untuk mengubah pengaturan pada beberapa sprite, atau beberapa lapisan latar belakang (ini adalah bagaimana Anda bisa mendapatkan efek seperti sorotan kerucut, dengan mengubah ukuran dan lokasi salah satu topeng persegi panjang di antara setiap garis yang digambar. Sejauh menyangkut perangkat keras semua wilayah itu persegi panjang.). Anda harus berhati-hati untuk menjaga pembaruan ini kecil dan selesai sebelum prosesor grafis mulai menggambar baris berikutnya atau Anda bisa mendapatkan hasil yang buruk. Setiap waktu yang dihabiskan untuk memproses interupsi ini juga memotong 80% dari waktu pemrosesan CPU ...
Untuk game yang mendapatkan hasil maksimal dari sistem ini, baik CPU maupun prosesor grafis tidak pernah mengambil istirahat nyata; masing-masing mengejar yang lain di sekitar loop memperbarui apa yang saat ini tidak dilihat orang lain.
sumber
Fitur utama dari semua konsol game yang membedakan mereka dari PC awal dan hampir semua komputer rumahan (1) adalah sprite perangkat keras .
Panduan pemrograman GBA yang ditautkan menunjukkan cara kerjanya dari sudut pandang prosesor utama. Bitmap yang mewakili pemain, latar belakang, musuh dll dimuat ke satu area memori. Area memori lain menentukan lokasi sprite. Jadi alih-alih harus menulis ulang semua RAM video setiap frame, yang membutuhkan banyak instruksi, prosesor hanya perlu memperbarui lokasi sprite.
Prosesor video kemudian dapat bekerja piksel demi piksel untuk menentukan sprite mana yang akan menggambar pada titik itu.
Namun, ini membutuhkan RAM dual-port yang dibagi antara keduanya, dan saya pikir dalam GBA prosesor video berada pada chip yang sama dengan ARM utama dan prosesor Z80 sekunder.
(1) Pengecualian penting: Amiga
sumber
"Pertanyaan saya adalah - bagaimana perangkat seperti GBA mencapai kecepatan bingkai hampir 60fps?"
Untuk menjawab hanya pertanyaan, mereka melakukannya dengan pemroses grafis. Saya cukup yakin Game Boy menggunakan grafik sprite. Pada tingkat atas, itu berarti prosesor grafis memuat hal-hal seperti gambar latar belakang, dan gambar Mario, dan gambar Putri Peach, dll. Kemudian prosesor utama mengeluarkan perintah seperti "tampilkan latar belakang diimbangi dengan ini banyak di x dan y, overlay gambar Mario # 3 di x ini, posisi y ", dll. Jadi prosesor utama benar-benar positif tidak peduli dengan menggambar setiap piksel, dan prosesor grafis sama sekali positif tidak peduli dengan menghitung keadaan permainan. Masing-masing dioptimalkan untuk apa yang perlu dilakukan, dan hasilnya adalah permainan video yang cukup bagus tanpa menggunakan banyak daya komputasi.
sumber
GBA memiliki prosesor yang sangat lambat. ARM7 sangat bagus; mereka hanya menjalankannya dengan lambat dan memberikannya tanpa sumber daya.
Ada alasan mengapa banyak game Nintendo pada saat itu dan sebelumnya adalah side-scrollers. PERANGKAT KERAS. Itu semua dilakukan dalam perangkat keras. Anda memiliki beberapa lapisan ubin plus satu atau lebih sprite dan perangkat keras melakukan semua pekerjaan untuk mengekstraksi piksel dari tabel tersebut dan mendorong layar.
Anda membangun ubin yang diatur di depan dan kemudian memiliki memori bertubuh kecil yang merupakan peta ubin. Ingin ubin kiri bawah menjadi ubin 7? Anda meletakkan angka 7 di lokasi memori itu. Ingin ubin berikutnya menjadi ubin 19? Di set ubin, Anda menempatkan 19 di sana, dan seterusnya untuk setiap lapisan yang telah Anda aktifkan. Untuk sprite, Anda cukup mengatur alamat x / y. Anda juga dapat melakukan penskalaan dan rotasi dengan mengatur beberapa register dan perangkat keras menangani sisanya.
Mode 7, jika saya ingat benar, adalah mode piksel, tapi itu seperti kartu video tradisional di mana Anda meletakkan byte yang menutupi warna untuk piksel dan perangkat kerasnya menangani penyegaran video. Saya pikir Anda bisa melakukan ping pong atau setidaknya ketika Anda memiliki bingkai baru Anda bisa membalikkannya, tapi saya tidak ingat benar. Sekali lagi, prosesor itu cukup underclock untuk hari dan usia itu dan tidak memiliki sumber daya cepat terlalu banyak. Jadi, sementara beberapa permainan adalah mode 7, banyak yang menggunakan side-scrollers ...
Jika Anda menginginkan solusi dengan frame rate tinggi, Anda perlu merancang solusi itu. Anda tidak bisa hanya mengambil tampilan lama yang Anda temukan dan berbicara dengannya melalui SPI atau I²C atau sesuatu seperti itu. Letakkan setidaknya satu framebuffer di depannya, idealnya dua, dan memiliki kontrol baris dan kolom jika mungkin di atas tampilan itu.
Sejumlah display yang saya duga Anda beli memiliki controller pada mereka yang sebenarnya Anda ajak bicara. Jika Anda menginginkan kinerja tipe GBA / konsol, Anda membuat / mengimplementasikan pengontrol. Atau Anda membeli / membangun dengan gumpalan GPU / video / logika, dan menggunakan HDMI atau antarmuka umum lainnya ke monitor stok.
Hanya karena sepeda memiliki ban dan rantai serta roda gigi tidak berarti ia bisa melaju secepat sepeda motor. Anda perlu merancang sistem untuk memenuhi kebutuhan kinerja Anda, ujung ke ujung. Anda dapat meletakkan roda sepeda itu di sepeda motor itu, tetapi tidak akan bekerja seperti yang diinginkan; semua komponen harus menjadi bagian dari desain keseluruhan.
Asteroid bekerja dengan cara ini juga; itu hanya membutuhkan satu 6502. Grafik vektor dilakukan dengan logika terpisah; 6502 mengirim serangkaian kecil data ke pengontrol grafis vektor, yang menggunakan ROM dan data tersebut untuk melakukan perencanaan balok dan z, on / off ... Beberapa standup memiliki prosesor terpisah untuk menangani audio dan video terpisah dari prosesor menghitung gim. Tentu saja hari ini video tersebut ditangani oleh beberapa ratusan, jika tidak ribuan, prosesor yang terpisah dari prosesor utama ...
sumber
Perangkat keras.
Ada memori grafis, yang mungkin atau mungkin tidak berbagi bus yang sama dengan memori program / data ... tetapi yang penting adalah memiliki prosesor grafis yang membaca memori 60 kali per detik dan mengirimkan data ke LCD menggunakan antarmuka yang dioptimalkan yang dirancang untuk melakukan ini secara efisien.
Anda dapat melakukan hal yang sama dengan mikrokontroler modern yang dilengkapi dengan periferal "antarmuka LCD", misalnya LPC4330 meskipun ini mungkin terlalu berlebihan. Tentu saja Anda akan memerlukan panel LCD yang kompatibel.
Dengan mikrokontroler modern yang cepat (yaitu, ARM bukan AVR) dan layar sekecil itu, Anda mungkin tidak perlu sprite atau blitter untuk mempercepat operasi grafis. Dengan AVR 8-bit mungkin lambat.
Tapi tidak masalah cpu, sedikit membenturkan antarmuka ke layar akan menyedot.
Saya yakin Atari 2600 menggunakan CPU bit-banging untuk mengirim gambar ke TV. Itu sedikit usang.
sumber