Game debug untuk NES: bagaimana hal itu terjadi hari ini

gambar

Jika Anda pernah terlibat dalam pemrograman, Anda terbiasa dengan konsep bug. Jika mereka tidak mengganggu kami, proses pengembangan akan menjadi jauh lebih cepat dan lebih menyenangkan. Tetapi bug ini hanya menunggu saat untuk merusak kode kami, jadwal kerja dan aliran kreatif. Untungnya, ada banyak alat dan strategi untuk membunuh bug bahkan dalam kode programmer retro-game.

Alat Debugging


Salah satu cara terbaik untuk men-debug kode adalah dengan menggunakan debugger. Beberapa versi emulator FCEUX dan Mesen memiliki debugger bawaan yang memungkinkan Anda mengganggu program kapan saja untuk memeriksa kesehatan kode.


FCEUX emulator debugger

Perlu dicatat bahwa metode ini lebih cocok untuk pemrogram tingkat lanjut yang bekerja dengan bahasa assembly. Tapi kami baru, jadi kami akan menulis dalam C (cc65). Tentu saja, kompiler akan bermain dengan aturannya sendiri, dan akan sulit bagi kita untuk berurusan dengan kode mesin yang dikompilasi dari kode C.

Editor hex FCEUX

Katakanlah kita perlu mengamati beberapa jenis variabel atau array. Tambahkan baris berikut ke opsi tautan (ld65): -Ln labels.txt

Setelah mengkompilasi proyek, file labels.txt akan muncul di foldernya. Buka saja di program apa saja untuk melihat teks dan cari nama variabel yang ingin kita amati.

( Catatan: jika Anda mendeklarasikan variabel statis, itu tidak akan dimasukkan dalam daftar ini. Oleh karena itu, alih-alih static unsigned char playerX gunakan unsigned char playerX )


Sekarang kita tahu alamat variabel yang diinginkan, tidak buruk. Mari kita temukan di debugger. Jalankan game ROM di emulator FCEUX. Di menu Debug, pilih item Hex Editor, dan di jendela yang terbuka, tekan Ctrl + G dan masukkan alamat variabel kami:


Tekan OK, dan kursor akan pindah ke alamat tempat variabel itu berada. Mari kita melihatnya:


Ini berguna untuk memeriksa apakah array diisi dengan benar atau untuk melacak perubahan pada variabel tertentu. Selain itu, Anda bisa merasa seperti Kakak, dengan hati-hati memperhatikan kode Anda.

Lihat alat emulator FCEUX lain yang berguna untuk menu Debug seperti PPU Viewer, Name table Viewer, dll.

Sederhanakan proses debugging


Dan jika kita tidak ingin menjalankan debugger setiap saat untuk mengamati variabel? Cara yang lebih maju adalah menulis prosedur yang menampilkan nilai ke layar. Mari kita coba gunakan skor di antarmuka untuk menampilkan posisi pemain pada sumbu Y:


Ini bekerja dengan sempurna!

Pemilik blog retro-coder dan nesdoug, Doug Fraker telah menciptakan metode serupa untuk menggunakan visualisasi di layar untuk keperluan debugging. Prosedur yang ditunjukkan di bawah ini membuat garis abu-abu pada layar yang dengan jelas menunjukkan tingkat beban CPU:

 // void gray_line(void); // For debugging. Insert at the end of the game loop, to see how much frame is left. // Will print a gray line on the screen. Distance to the bottom = how much is left. // No line, possibly means that you are in v-blank. _gray_line: lda <PPU_MASK_VAR and #$1f ;no color emphasis bits ora #1 ;yes gray bit sta PPU_MASK ldx #20 ;wait @loop2: dex bne @loop2 lda <PPU_MASK_VAR ;normal sta PPU_MASK rts 

Anda cukup menyalin prosedur ini ke dalam kode Anda atau memasukkan pustaka nesdoug.h dalam proyek. Prosedur harus dipanggil setelah selesainya siklus permainan, maka bilah abu-abu akan ditampilkan di layar.


Itu berhasil, tetapi sepertinya saya memiliki satu bug lagi! Kami akan menyingkirkannya nanti. Sementara itu, mari kita lanjutkan.

Kekuatan makro


Macro juga bisa menjadi alat debugging yang berguna. Mereka akan memungkinkan Anda untuk menemukan tempat dalam kode yang telah menjadi sumber bug.

Mari kita buat semacam makro yang akan memberi kita sinyal pada waktu yang tepat, misalnya memainkan suara atau memilih nol palet dengan nilai yang diperlukan. Kami memiliki beberapa makro yang mengubah palet nol menjadi warna merah, biru dan acak, serta mereproduksi suara:


Bagaimana cara kerjanya? Misalkan Anda berhasil menyusun proyek, Anda memulai emulator dengan permainan Anda, klik tombol Start dan ...


Tampaknya tidak ada yang lain selain layar putih. Selain itu, beberapa emulator dapat melaporkan "CPU macet!" Di bilah status. Apa yang harus dilakukan selanjutnya?

Pertama, Anda perlu melokalkan kode di mana kesalahan terjadi. Dan di sini makro suara saya ikut bermain.

Kami tahu pasti bahwa menu utama berfungsi. Mari kita lihat apa yang terjadi setelahnya:

 playMainMenu(); player.lives = 9; points = 0; gameFlags = 0; while(current_level<7 && player.lives>0) { set_world(current_world); debugSound; playCurrentLevel(); } 

Saya curiga bahwa game mogok saat prosedur set_world . Mari kita periksa firasat ini. Saya cukup memasukkan nama makro di baris berikutnya setelah prosedur diperiksa.

Kami memulai proyek dan ... Saya mendengar suara! Yaitu, prosedur ini berhasil, dan kami perlu memeriksa yang berikut: playCurrentLevel . Mari kita pindahkan makro debug di bawah ini:

 while(current_level<7 && player.lives>0) { set_world(); playCurrentLevel(): debugSound; } 

Saya memulai proyek lagi, tetapi saya tidak dapat mendengar suara. Ini berarti bahwa prosedur tidak selesai, dan kegagalan terjadi di dalamnya.

Dalam kasus seperti itu, Anda harus membuka kode prosedur dan terus menerapkan teknik ini sampai Anda dapat mempersempit pencarian Anda untuk kemungkinan lokasi bug.

Makro yang mengubah palet juga dapat berguna untuk memeriksa kondisi. Misalnya, kode kami melakukan pengujian kompleks terhadap beberapa kondisi:

 if ( (getTile(objX, objY+16) || collide16() ) || (objsOX[i] && objY>objsOX[i])) { debugRed; objsSTATE[i]=THWOMP_SMASH; objY=objsY[i]-=4; objsFRM[i]=0; sfx_play(SFX_THWOMP_SLAM_DOWN,2); } 

Jika kita mengubah warna palet di sini, kita akan melihat apakah kondisinya terpenuhi:


Ayam ini sepertinya baik-baik saja. Tetapi jika bendera tidak berfungsi, maka salah satu syaratnya tidak terpenuhi. Dalam hal ini, Anda perlu memeriksa semuanya secara terpisah dan kemudian, mungkin, Anda akan menemukan bug lain.

Opsi nuklir


Baru-baru ini saya menemukan bahwa salah satu hantu dalam permainan saya menunjukkan semacam perilaku mencurigakan. Dari waktu ke waktu, dia menolak untuk menyerang pemain.

Lihatlah hantu ini terkena bug - ia hanya menyerang ketika karakternya dekat dengan tengah layar:


Tidak peduli sekeras apa pun saya mempelajari kode prosedur ini, saya tidak dapat menemukan di mana bug itu disembunyikan, jadi saya memutuskan untuk mengambil langkah ekstrem dan menguji kerja kode ini dalam lingkungan pengembangan modern.

Saya mengambil semua yang saya butuhkan: peta layar, array dengan atribut meta-file, kode prosedur, dan cukup memasukkannya ke dalam Visual Studio 2017:


Di PC, kodenya bekerja persis sama. Ternyata, bug itu bersembunyi di prosedur yang mengisi cache untuk menemukan rintangan antara pemain dan musuh. Array salah diisi. Saya yakin harus ada 0 bukan 0x80.


Jadi, saya akan mencoba langkah demi langkah men-debug kode untuk mencari tahu mengapa ini terjadi.


Ini lucu, tapi sepertinya saya melakukan tindakan dalam urutan yang salah. Mari kita perbaiki dan periksa array lagi!


Tampaknya sekarang array sudah diisi dengan benar. Artinya, saya hanya perlu memperbaiki kode cc65 dan mengkompilasi proyek NES lagi.


Jadi, alat pengembangan modern dapat membantu dalam debugging algoritma dan memperbaiki bug.

Singkirkan bug dengan tenang


Bug mengganggu, seperti halnya kode mengganggu. Tetap tenang, jangan kehilangan kendali dan gunakan seluruh jajaran alat yang tersedia untuk mencari dan menghancurkan hama ini. Kualitas kode Anda dan ketenangan pikiran akan meningkat secara signifikan.

Ingin mendapatkan kiat langsung dari profesional desain retro? Selamat Datang di Perselisihan kami!

Game kami The Meating tersedia di sini !

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


All Articles