Mesin virtual pada ESP8266 untuk menjalankan game

VM ditulis oleh tangan yang tidak pasti dari humaniora di lingkungan pemrograman Arduino menggunakan quickcode dan sepeda. Dan ada juga kompiler untuk itu dari bahasa seperti-C, ditulis dalam JavaScript menggunakan metode yang sama. Ya Anda sudah bisa buru-buru berkomentar, melempar batu. Nah, bagi yang masih tertarik, saya mengajak Anda untuk terus membaca.

Trolleybus roti

Secara umum, pekerjaan saya sudah sedikit dicakup oleh tormozedison yang disegani di sini . Tetapi pada saat itu ada prototipe bola dalam ruang hampa. Dan sekarang saya sudah mendapatkan perangkat RomanS, yang dengan ramah dia berikan kepada saya untuk percobaan yang benar-benar gratis. Perangkat ini disebut ESPboy. Ini berbeda dari kerajinan lain dengan kekompakan dan slot ekspansi menggunakan chip MCP23017. Di sini Anda dapat mempelajari lebih lanjut tentang dia.

Jika ada yang tertarik, bagaimana ide aneh itu muncul di benak saya sebagai mesin virtual pada mikrokontroler, maka Anda dapat membacanya di bawah spoiler.

Latar belakang
Setibanya di sekolah, saya dibawa oleh seorang gamemaker dari yoyogames, dan, seperti banyak orang, terpaku padanya, tidak mengerti apa. Demo yang bengkok dan ditulis dengan buruk ini masih bisa membanggakan kepada teman-teman, tetapi di Internet mereka tenggelam di antara yang serupa. Saya menyadari betapa sulitnya untuk menulis bahkan permainan sederhana sendiri, belum lagi yang serius di mana Anda bisa merampok sapi. Namun keinginan untuk menulis game tidak hilang. Ketika saya mendapatkan ponsel, saya menemukan Midlet Pascal dan bersenang-senang dengannya selama beberapa tahun. Setelah semua, saya menyadari bahwa menulis game untuk perangkat yang lemah lebih mudah daripada untuk kakak yang lebih kuat. Setidaknya, orang selalu bisa berbicara bukan tentang tangan yang bengkok, tetapi tentang kemampuan platform yang terbatas. Namun, para pemain tombol memberi jalan kepada sensor kesempatan lain untuk menaklukkan dunia yang terlewatkan. Namun demikian, pada titik tertentu saya menyadari bahwa saya dapat menghidupkan kembali mimpi saya menggunakan mikrokontroler.

Saya mulai dengan menulis permainan di bawah arduino uno, ke mana Anda akan pergi tanpa itu. Kemudian dia adalah satu-satunya saya, dan saya sangat khawatir dengan penampilannya. Saya mencoba flash sesedikit mungkin. Tapi jalan menyapu berjalan dalam langkah-langkah kecil. Setiap perubahan kecil pada kode membuatnya berkedip berulang-ulang. Dan saya memutuskan untuk menulis mesin virtual bertumpuk. Bagaimanapun, ada dua kilobyte RAM untuk byte kode dan data di papan. Tetapi betapa lambatnya itu, tetapi karena suatu alasan ingatan terus-menerus kurang. Mungkin intinya adalah bahwa semua sepeda saya dengan roda persegi dan naik perlahan. Kemudian saya memutuskan untuk menulis emulator chip-8 pada Arduino Mega yang baru saja tiba dari China. Tentu saja, kemudian saya ingin menulis emulator gameboy untuknya, playstation pertama dan beberapa superkomputer lebih mudah. Hasilnya, saya mengerti hal utama. Mesin virtual chip-8 sangat sederhana, terlalu sederhana. Sedemikian rupa sehingga ketika menulis gim Anda untuk perkalian atau pembagian, Anda harus menulis subrutin lambat yang terpisah. Jadi, Anda perlu menulis VM Anda, menyingkirkan kesalahan fatal. Pada saat ini, beberapa esp8266 lainnya tiba, dengan ruang 160MHz.

Jika Anda merasa bahwa mesin virtual adalah pemborosan sumber daya, maka saya juga menulis ulang emulator chip-8 saya untuk itu. Ternyata mesin virtual di mesin virtual pada mikrokontroler. Anda mungkin bisa melangkah lebih jauh dan menulis mesin Turing pada chip-8.

Spesifikasi Mesin Game Kecil ESP


Mesin virtual berisi 16 register masing-masing 16 bit, register nol adalah stack pointer. Setiap instruksi adalah byte ganda, beberapa instruksi mengandung dua byte data. Memori yang dapat dialamatkan 64KB. Dalam kasus ESP8266, 20KB tersedia. Program ini dapat diunduh dari SPIFFS dan UART. Jika diinginkan, Anda dapat menambahkan unduhan dari kartu memori atau melalui WiFi. Selain instruksi aritmatika dan instruksi untuk memindahkan data, ada instruksi terpisah untuk bekerja dengan sprite, layar, dan suara. Ukuran layar 128 x 128 piksel. Pada 16 warna per titik, layar membutuhkan 8KB memori, jumlah buffer yang sama untuk menggambar sprite dan partikel. Meskipun perpustakaan TFT_eSPI yang saya gunakan mampu memperbarui layar lebih dari 60 kali per detik, saya harus membatasi diri hingga 20 frame per detik. Jika tidak, waktu prosesor tidak cukup untuk mesin virtual. Anda dapat menggambar ubin dan 32 sprite hingga ukuran 128x128 piksel dengan kemungkinan rotasi dan mirroring. Untuk menghemat memori, Anda dapat menggunakan gambar bit tunggal atau kompresi RLE. Ada fisika yang disederhanakan: deteksi tabrakan sprite dengan sprite dan ubin, resolusi tabrakan, gravitasi. Layar diperbarui baris demi baris hanya jika satu baris telah mengubah piksel. Kecepatan VM, tergantung pada berapa banyak garis yang ditarik dalam bingkai, bervariasi dari 100 ribu hingga 900 ribu operasi per detik. Anda dapat menggunakan layar warna yang berbeda, ada peregangan lembut gambar ke proporsi yang diinginkan.


Beberapa game yang saya tulis dapat dilihat di sini .

Pada saat yang sama dengan VM untuk ESP8266, saya menulis emulator JavaScript untuk browser. Agar tidak mengedit bytecode secara manual, assembler sederhana telah ditambahkan, berdasarkan pengalaman saya dengan assembler untuk MOS6502. Kemudian saya memutuskan untuk menambahkan bahasa tingkat yang lebih tinggi. Namun demikian, tugas utama saya adalah menulis game sederhana dengan cepat, dan bukan kode perakitan debug yang panjang. Menurut saya menulis kompiler Anda akan lebih mudah daripada menambahkan LLVM. Dan saya menulisnya dalam JavaScript, karena saya tahu itu tidak seburuk bahasa lain. Saat ini, ia jauh dari mendukung standar C, dan ketika menyusun, Anda dapat dengan mudah menemukan kesalahan yang tidak dapat dipahami di tempat yang tidak dapat dipahami. Tapi itu cepat, karena butuh kurang dari 2000 baris.

Dan sekarang untuk pertanyaan, mengapa saya menulis semua ini di sini. Sudah sekarang Anda dapat menulis dan menjalankan game. Namun, kesempurnaan masih jauh. Jika ada yang ingin membantu saya menyelesaikan ESP LGE, atau menulis game sendiri, maka saya akan sangat senang. Jika Anda pikir ide saya menarik, dan Anda ingin tahu lebih banyak, maka saya akan dengan senang hati menjawab pertanyaan Anda. Saya peringatkan Anda, kode untuk Arduino cukup sulit dibaca. Sebagian karena aku belajar sendiri. Sebagian karena fakta bahwa saya mencoba mengurangi jumlah pemanggilan fungsi untuk meningkatkan kecepatan kerja. Akibatnya, banyak fungsi berisi jejak kode yang sangat besar. Jadi jangan biarkan ibu hamil dan anak-anak ke layar. Secara bertahap, saya akan mencoba untuk memperbaikinya dan meningkatkan keterbacaan.

Dan bagi yang sudah membaca, contohnya sebuah game. Dibutuhkan kurang dari seratus baris dan kurang dari 1KB dalam bentuk yang dikompilasi.

int stickCount; char key,previouseKey,takenSticks; void redraw(){ int i; //   setcolor(2); //   for(i = 0; i < stickCount; i++) line(22 + i * 6, 74, 22 + i * 6, 84); //   setcolor(11); //  for(i = stickCount; i < 15; i++) line(22 + i * 6, 74, 22 + i * 6, 84); //     setcolor(1); //   delayredraw(); } void playersMove(){ //    ,     .  while(key == previouseKey){ key = getkey(); } while(key != KEY_LEFT && key != KEY_DOWN && key != KEY_RIGHT){ key = getkey(); } if(key & KEY_LEFT){ takenSticks = 1; }else if(key & KEY_DOWN){ takenSticks = 2; }else{ takenSticks = 3; } printf("%d, ", takenSticks); stickCount -= takenSticks; previouseKey = key; } void computersMove(){ if(stickCount % 4){ //   ,    takenSticks = stickCount % 4; }else{ //      takenSticks = 1 + random(1); } stickCount -= takenSticks; printf("%d, ", takenSticks); } void game(){ // stickCount = 15; clearscreen(); //       gotoxy(8,0); puts(""); gotoxy(2,1); puts(" 1,2  3 .  ,   . :\n"); // 27,25  26   printf(" %c 1 %c 2 %c 3", 27, 25, 26); gotoxy(0,12); redraw(); while(1){ playersMove(); if(stickCount <= 0){ gotoxy(3,8); puts(" "); return; } redraw(); computersMove(); redraw(); if(stickCount <= 0){ gotoxy(3,8); puts(" "); return; } } } void main(){ while(1){ game(); //  settimer(1,1000); while(gettimer(1)){} while(getkey() == 0){} previouseKey = key; } } 

Anda bisa langsung mengujinya . Ikuti tautannya, lalu klik kompilasi, lalu jalankan. Jika Anda ingin tahu lebih banyak tentang kemungkinan-kemungkinan IDE, Anda dapat membaca tutorialnya . Terima kasih atas perhatian anda

Source: https://habr.com/ru/post/id459714/


All Articles