Hack 77: Menambahkan Tiles dan Sprites ke Game GBA Anda

what is a quinella bet

bagan 32 slot

demo slot pragmatic​

oxy bet

Pengenalan

Menulis langsung ke buffer video dengan mode video bitmap di Game Boy Advance [Hack #76] memang baik, tetapi menggunakan banyak memori dan bisa lambat jika ingin melakukan animasi rumit. Alasan konsol game dan perangkat portabel mampu menghasilkan efek visual yang brilian, meskipun spesifikasi hardware rendah dibandingkan PC, adalah karena hardware grafis yang sangat terspesialisasi.

Pada GBA dan kebanyakan konsol untuk grafis 2D, hal ini hadir dalam bentuk penanganan khusus grafis tile. Dalam hack ini, saya akan menunjukkan cara menggunakan grafis tile untuk mengurangi jumlah memori yang digunakan oleh gambar dan meningkatkan kecepatan tampilannya.

Langkah Awal: Membuat Tile

Tile pada dasarnya adalah kotak 8x8 piksel yang dapat digunakan untuk menggambar gambar yang lebih besar. Tile yang lebih besar dan tidak persegi dapat terdiri dari beberapa tile 8x8. Gambar 8-24 menunjukkan satu set delapan tile 16x16 atau, dari perspektif GBA, tiga puluh dua tile 8x8.

Setelah memiliki satu set tile yang dapat digunakan, saatnya membuat data peta yang akan memberi tahu GBA tile mana yang akan ditampilkan di mana. Ada beberapa alat yang tersedia di http://gbadev untuk membuat data peta, salah satunya adalah GBA Map Editor. Saat Anda meluncurkan Map Editor, dua jendela terbuka. Satu adalah jendela Tools, tempat Anda dapat memuat bitmap yang berisi semua tile. Jendela lainnya adalah GBA Map Editor itu sendiri, yang dapat Anda gunakan untuk melukis peta menggunakan tile yang dimuat di jendela Tools. Peta yang Anda buat dengan alat ini dapat disimpan dalam format proprietary dan dimuat lagi nanti untuk diedit. Untuk menggunakan data peta di GBA, Anda dapat mengekspor data ke file sumber C yang dapat disertakan dalam proyek atau ke bitmap, yang dapat dijalankan melalui konverter gambar-ke-peta yang berbeda jika diinginkan.

Perhatikan bahwa fungsi Ekspor ke C dari GBA Map Editor tampaknya memiliki bug di mana kadang-kadang hanya mengekspor setengah data peta ke file C. Ini kadang-kadang dapat diatasi dengan mengekspor ulang data atau beralih ke peta resolusi yang lebih tinggi.

8.6.1. Memuat Peta ke dalam Memori

Setelah data peta dikonversi ke format ramah-GBA, Anda juga perlu mengonversi grafik tile. Seperti gambar yang akan dimuat dalam mode video bitmap, grafik tile harus dikonversi menjadi data palet dan data piksel. Dengan asumsi Anda telah mengonversi grafik tile ke PCX 256-warna, Anda dapat mengonversinya dengan pcx2gba, seperti ini:

pcx2gba SPR4T my_tiles.pcx my_tiles.h my_tiles

Untuk membuat set tile cepat dan kasar, buat file PCX 64x32 piksel mirip dengan yang ditunjukkan pada Gambar 8-24, menggunakan editor grafis pilihan Anda (Gimp, http://gimp, adalah pilihan gratis yang bagus). Untuk mengkompilasi contoh di seluruh hack ini, pastikan untuk membaca "Program untuk Game Boy Advance" [Hack #76] terlebih dahulu.

Seperti sebelumnya [Hack #76], perintah ini mengonversi my_tiles.pcx menjadi array data palet bernama my_tilespal dan array data piksel bernama my_tilesdata, keduanya dalam file bernama my_tiles.h. Parameter SPR4T memberi tahu program untuk memotong data menjadi serangkaian tile 8x8 dengan konversi.

Setelah semua data dikonversi ke format yang dapat digunakan oleh GBA, saatnya memuatnya. Langkah pertama adalah mengubah mode video dan memuat data palet. Langkah-langkah ini cukup mirip dengan yang telah Anda lihat sebelumnya.

#define USHORT unsigned short
#include "my_tiles.h"
int main(void) {
*(unsigned short*)0x04000000 = 0x1 | 0x400;
int i;
unsigned short *tilePalette = (unsigned short*)0x05000000;
for(i = 0; i < 256; i++) {
tilePalette[i] = my_tilespal[i];
}
}

Bagian pertama kode, tentu saja, mengubah mode video. Kali ini, saya menggunakan Mode 0 dan berniat menulis ke BG2, jadi saya pastikan itu diaktifkan. Palet untuk tile latar belakang menuju ke lokasi memori yang sama dengan palet warna untuk mode video bitmap, sehingga kode pemuatan palet hampir sama.

Selanjutnya, program memuat data piksel untuk tile dan data peta. Di sinilah hal-hal menjadi menarik. Baik data tile maupun data peta harus dimuat ke dalam wilayah memori 64KB yang sama, yang dimulai dari 0x06000000. Selain itu, GBA mengharuskan data tile disejajarkan ke wilayah 16KB yang disebut Character Base Block, yang diindeks dari 0-3, dan data peta disejajarkan ke wilayah 2KB yang disebut Screen Base Block, yang diindeks dari 0-31. Blok-blok ini pada dasarnya berfungsi sebagai penanda yang menunjukkan di mana dalam memori latar belakang harus mencari data peta dan tile. Nanti, saat Anda benar-benar menampilkan latar belakang, Anda akan menggunakan indeks Character dan Screen Base Blocks untuk memberi tahu GBA di mana mencari data tile dan peta yang relevan. Akhirnya, sangat penting bahwa Character Base Blocks dan Screen Base Blocks yang digunakan tidak tumpang tindih. Jika tumpang tindih, Anda akan mendapatkan data tile dan peta yang rusak. Gambar 8-25 mengilustrasikan konsep Character Base Blocks dan Screen Base Blocks.

Kode berikut menunjukkan bagaimana Anda dapat memuat data tile ke dalam Character Base Blocks yang disejajarkan dengan benar. Anda perlu menambahkan deklarasi variabel ini ke bagian atas contoh sebelumnya:

int tile_setCharBaseBlock = 1;
unsigned short *tileData =
(unsigned short*)( 0x06000000 + (tile_setCharBaseBlock * 0x4000) );

Dan tambahkan loop for berikut segera setelah loop for yang digunakan untuk memuat palet:

for(i = 0; i < (my_tiles_WIDTH * my_tiles_HEIGHT) / 2; i++) {
tileData[i] = my_tilesdata[i];
}

Hal pertama yang dilakukan segmen kode ini adalah mengatur variabel tile_setCharBaseBlock dengan indeks Character Base Block yang ingin Anda gunakan karena Anda akan membutuhkannya nanti. Baris kedua membuat pointer ke awal memori video (0x06000000) kemudian menambahkan 16KB (0x4000) dikalikan indeks base block yang ingin Anda gunakan. Setelah itu, kode mengikuti prosedur standar untuk memuat data dari satu bagian memori ke bagian lain.

Contoh ini melakukan tugas serupa untuk data peta:

#define USHORT unsigned short
#define u8 unsigned short
#include "my_tiles.h"
#include "my_map.c"
int main(void) {
*(unsigned short*)0x04000000 = 0x1 | 0x400;
int my_mapScreenBaseBlock = 28;
int i;
unsigned short *myMapData = (unsigned short*)my_map;
unsigned short *tileMap =
(unsigned short*) ( 0x6000000 + (my_mapScreenBaseBlock*0x800) );
for(i = 0; i < (64 * 64) / 2; i++) {
tileMap[i] = myMapData[i];
}
}

Untuk memastikan tidak ada kemungkinan tabrakan dengan data tile yang dimuat sebelumnya, kode ini bersiap menulis ke Screen Base Block 28. Karena data peta yang diimpor dari GBA Map Editor adalah array nilai 8-bit, baris kedua mentransmisikannya ke nilai 16-bit untuk memudahkan pemuatan. Mirip dengan kode pemuatan data tile, baris ketiga menghitung alamat untuk menulis sebagai 0x06000000 ditambah indeks Screen Base Block dikali 2048, atau 0x800 dalam heksadesimal. Data peta yang dimuat diekspor sebagai array 64x64 nilai 8-bit. Karena kita memuatnya sebagai nilai 16-bit yang dua kali lebih besar, kita mengulang loop setengah kali jika kita memindahkan satu nilai 8-bit setiap kali. GBA dioptimalkan untuk menulis nilai 16-bit, jadi penting untuk melakukannya sebisa mungkin.

8.6.2. Menampilkan Peta

Dengan tile dan data peta yang dimuat, saatnya untuk mulai menampilkannya. GBA dapat memiliki hingga empat lapisan latar belakang, tergantung pada mode video. Mode 1 memungkinkan BG0, BG1, dan BG2 digunakan, dengan BG0 dan BG1 statis dan BG2 sebagai latar belakang rotasi/skala. Setiap latar belakang memiliki nilai 16-bit dalam memori yang dikenal sebagai register kontrol latar belakang. Dengan menulis nilai tertentu ke salah satu register ini, Anda dapat mengubah pengaturan latar belakang tertentu. Tabel 8-4 mencantumkan alamat memori untuk empat register kontrol latar belakang.

Latar BelakangLokasi di Memori
00x4000008
10x400000A
20x400000C
30x400000E

Mengatur register kontrol latar belakang dapat dilakukan dengan cara yang mirip dengan mengatur register kontrol video, seperti pada potongan kode berikut yang memuat peta ke BG2:

*(unsigned short*)0x400000C = (tile_setCharBaseBlock << 2) |
(my_mapScreenBaseBlock << 8) | 0x80 | 0x8000;

Seperti kode pengubahan mode video, kode ini sebagian besar terdiri dari penggunaan OR logis untuk menggabungkan berbagai nilai kunci menjadi satu nilai. Baru di sini adalah operasi tile_setCharBaseBlock << 2 dan my_mapScreenBaseBlock << 8. Operasi ini mengambil nilai base block yang disimpan dari pemuatan tile dan data peta dan menggesernya ke bit yang tepat untuk mengidentifikasi Character Base Block dan Screen Base Block yang relevan saat ditempatkan di register kontrol latar belakang. Ngomong-ngomong, dengan asumsi Mode 1, kode di atas mengatur latar belakang menjadi latar belakang 512x512 piksel menggunakan tile 256-warna. Tabel 8-5 mencantumkan beberapa nilai berguna untuk mengonfigurasi latar belakang tile.

FungsiHeksadesimalBiner
Prioritas 1 (urutan tampilan)0x0
Prioritas 20x11
Prioritas 30x210
Prioritas 40x311
Warna 8-bit0x801000 0000
Warna 16-bit (hanya latar belakang statis)0x00000 0000
Dimensi 256x256 (statis)0x000000 0000 0000 0000
Dimensi 128x128 (rotasi/skala)0x000000 0000 0000 0000
Dimensi 512x256 (statis)0x40000100 0000 0000 0000
Dimensi 256x256 (rotasi/skala)0x40000100 0000 0000 0000
Dimensi 256x512 (statis)0x80001000 0000 0000 0000
Dimensi 512x512 (rotasi/skala)0x80001000 0000 0000 0000
Dimensi 512x512 (statis)0xC0001100 0000 0000 0000
Dimensi 1024x1024 (rotasi/skala)0xC0001100 0000 0000 0000

Contoh lengkap berikut menggabungkan semua yang telah Anda lihat untuk menampilkan peta di layar:

#define USHORT unsigned short
#define u8 unsigned short
#include "my_tiles.h" /* 64x32 pixel pcx, dikonversi oleh pcx2gba */
#include "my_map.c" /* 512x512 tile map, diekspor oleh map editor */
int main(void) {
int tile_setCharBaseBlock = 1;
int my_mapScreenBaseBlock = 28;
int i;
/* Inisialisasi tampilan */
*(unsigned short*)0x04000000 = 0x0 | 0x400;
/* Memuat palet */
unsigned short *tilePalette = (unsigned short*)0x05000000;
for(i = 0; i < 256; i++) {
tilePalette[i] = my_tilespal[i];
}
/* Memuat tile */
unsigned short *tileData =
(unsigned short*)( 0x06000000 + (tile_setCharBaseBlock * 0x4000) );
for(i = 0; i < (my_tiles_WIDTH * my_tiles_HEIGHT) / 2; i++) {
tileData[i] = my_tilesdata[i];
}
/* Memuat peta */
unsigned short *tileMap =
(unsigned short*) ( 0x6000000 + (my_mapScreenBaseBlock*0x800) );
unsigned short *myMapData = (unsigned short*)my_map;
for(i = 0; i < (64 * 64) / 2; i++) {
tileMap[i] = myMapData[i];
}
/* Memuat peta ke BG2 */
*(unsigned short*)0x400000C = (tile_setCharBaseBlock << 2) |
(my_mapScreenBaseBlock << 8) | 0x80 | 0x8000;
}

8.6.3. Rasa Segar dari Sprite

Game tanpa sprite pada dasarnya adalah panggung tanpa aktor. Sebagai ahli grafis 2D, GBA memiliki banyak fungsionalitas khusus yang berpusat pada sprite. Sprite, seperti latar belakang tile, adalah gambar yang terbuat dari serangkaian tile 8x8. GBA dapat menyimpan hingga 128 sprite, yang dapat berukuran antara 8x8 piksel hingga 64x64 piksel. Data piksel sprite dan data palet disimpan di bagian memori yang berbeda dari data piksel dan palet tile latar belakang, sehingga Anda dapat memiliki palet yang berbeda untuk sprite dan latar belakang.

Membuat grafik untuk sprite relatif mudah. Anda hanya perlu ingat untuk menjaga dimensi dalam batas 8x8 hingga 64x64 dan kedalaman warna 16 atau 256 warna. Mengonversi gambar untuk digunakan oleh GBA dapat dilakukan dengan pcx2gba, menggunakan metode yang sama dengan mengonversi gambar tile latar belakang.

Bagian ini mengasumsikan file .PCX bernama pat, dan file header terkait bernama pat.h. Anda dapat menghasilkan file yang benar menggunakan pat sebagai input dengan perintah ini:

pcx2gba SPR4T pat pat.h pat

Sekarang ke penampilan sprite yang sebenarnya. Seperti biasa, program dimulai dengan mengatur register kontrol video dengan nilai yang diperlukan. Baris kode berikut mengatur GBA ke Mode 1 dan mengaktifkan sprite:

*(unsigned short*)0x04000000 = 0x1 | 0x1000 | 0x40;

0x40 ekstra di akhir adalah nilai pengaturan lain yang terkait dengan sprite. Dalam memori, sprite dapat disimpan dalam array 2 dimensi atau array 1 dimensi. Secara default, GBA menyimpan sprite dalam array 2D, tetapi seringkali lebih mudah untuk mengaksesnya dalam array 1D. Meng-OR 0x40 ke dalam register kontrol video menyebabkan GBA menyimpan sprite dalam array 1D.

Memuat data piksel dan palet sprite mengikuti pola yang sudah dikenal yaitu memindahkan data ke area memori yang ditentukan—dalam hal ini, 0x05000200 untuk data palet sprite dan 0x06010000 untuk data piksel sprite. Kode berikut memuat palet dan data untuk sprite bernama pat (pastikan memiliki baris dengan #include "pat.h" di bagian atas file sumber Anda):

unsigned short *spritePalette = (unsigned short*)0x05000200;
for(int i = 0; i < 256; i++) {
spritePalette[i] = patpal[i];
}
unsigned short *spriteData = (unsigned short*)0x06010000;
for(int i = 0; i < (pat_WIDTH * pat_HEIGHT) / 2; i++) {
spriteData[i] = patdata[i];
}

Untuk benar-benar mengontrol di mana sprite ditampilkan, GBA menggunakan bagian memori yang disebut Object Attribute Memory (OAM). Memori ini memiliki tujuan yang mirip dengan register kontrol latar belakang. Nilai yang ditempatkan ke OAM menentukan bagaimana sprite berperilaku. OAM mengalokasikan 8 byte untuk masing-masing dari 128 sprite. Ukuran setiap entri di OAM membuatnya sulit untuk menangani pengaturan melalui satu variabel. Cara termudah untuk menanganinya adalah dengan mendefinisikan struktur data yang panjangnya 8 byte.

Struktur OAMSprite di bawah mendefinisikan struktur yang datanya terdiri dari array empat unsigned short. Karena setiap unsigned short panjangnya dua byte, ini berjumlah delapan byte.

struct OAMSprite {
unsigned short reg[4];
};

Struktur ini juga sejajar dengan baik dengan lokasi di memori di mana berbagai bit penting informasi sprite berada. Nilai Y dan X sprite, bersama dengan beberapa nilai konfigurasi kunci, terletak di reg[0] dan reg[1], masing-masing. Lokasi data sprite dalam memori yang akan digunakan oleh sprite tertentu dapat dirujuk dengan reg[2]. Variabel terakhir, reg[3], dapat digunakan untuk mengakses berbagai fungsi yang terkait dengan rotasi dan skala.

Pada titik ini, dimungkinkan untuk menampilkan sprite dengan kode yang mirip dengan berikut:

OAMSprite pat;
int x = 24;
int y = 86;
pat[0] = y | 0x2000;
pat[1] = x | 0x8000;
pat[2] = 0;
unsigned short *OAM = (unsigned short*)0x07000000;
unsigned short* spritePtr = (unsigned short*)&pat;
for(int i = 0; i < 4; i++) {
OAM[i] = spritePtr[i];
}

Seperti yang Anda lihat, kode ini memberikan nilai ke OAMSprite pat. Nilai x dan y bisa langsung masuk ke reg[1] dan reg[0] bersama dengan beberapa nilai untuk konfigurasi. Dalam hal ini, 0x2000 menunjukkan bahwa pat memiliki 256 warna dan 0x8000 menunjukkan bahwa pat berdimensi 32x32 piksel. Nilai di reg[2] diatur ke indeks awal gambar sprite dalam array piksel tile. Dalam hal ini, 0 merujuk ke tile pertama. Ketika sprite siap ditampilkan, itu disalin ke OAM, di lokasi memori 0x07000000. Tabel 8-6 berisi beberapa nilai berguna yang terkait dengan sprite di OAM.

AtributVariabel OAMSpriteHeksadesimalBiner
16 Warnareg[0]0x000 0000 0000 0000
256 Warnareg[0]0x200010 0000 0000 0000
8x8reg[1]0x00000 0000 0000 0000
16x16reg[1]0x4000100 0000 0000 0000
32x32reg[1]0x80001000 0000 0000 0000
64x64reg[1]0xC0001100 0000 0000 0000
Terbalik Horizontalreg[1]0x100001 0000 0000 0000
Terbalik Vertikalreg[1]0x200010 0000 0000 0000

8.6.4. Menangani Input

GBA memiliki 10 tombol berbeda yang dapat digunakan untuk input: empat tombol arah, A, B, L, R, Start dan Select. Status sepuluh tombol ini terkandung dalam nilai 16-bit yang terletak di 0x04000130. Sepuluh bit terendah dari nilai ini menunjukkan status setiap tombol, sama dengan 0 jika tombol ditekan dan 1 jika tidak, seperti yang ditunjukkan pada Gambar 8-26.

Untuk menentukan apakah tombol tertentu sedang ditekan, Anda dapat membandingkan nilai di 0x04000130 dengan angka yang sesuai dengan bit yang ingin Anda periksa menggunakan operasi AND logis. Angka 0x2, misalnya, adalah hasil yang Anda dapatkan ketika hanya bit kedua dalam angka yang 1 dan, oleh karena itu, sesuai dengan tombol B. AND logis dapat dilakukan dengan nilai di 0x04000130 dengan potongan kode berikut:

*(unsigned short*)0x04000130 & 0x2

Ekspresi ini mengembalikan 1 jika bit kedua dari kedua angka adalah 1. Karena penekanan tombol ditunjukkan oleh nilai 0 pada bit yang sesuai, ini sebenarnya kebalikan dari apa yang Anda inginkan. Jadi, Anda meniadakan ekspresi ini untuk mendapatkan sesuatu seperti ini:

if( !( *(unsigned short*)0x04000130 & 0x2 ) ) {
//Tombol B sedang ditekan
}

Tabel 8-7 berisi daftar nilai yang dapat digunakan untuk mengidentifikasi setiap tombol dalam ekspresi seperti di atas.

TombolHeksadesimalBiner
A0x11
B0x210
Select0x4100
Start0x81000
Kanan0x101 0000
TombolHeksadesimalBiner
Kiri0x2010 0000
Atas0x40100 0000
Bawah0x801000 0000
R0x1001 0000 0000
L0x20010 0000 0000

Untuk informasi lebih lanjut tentang pemrograman GBA, pastikan untuk mengunjungi http://gbadev dan http://devrs Juga lihat "Mainkan Homebrew di GBA Anda" [Hack #46] jika Anda ingin memainkan game di hardware nyata. Dengan apa yang telah Anda lihat sekarang, dan apa yang dapat Anda temukan di situs-situs itu, Anda akan memiliki informasi yang cukup untuk menyusun game GBA sederhana dengan grafis dan input.

hack slot x500

â–˛ Kembali ke atas

Platform Lainnya

BRO303

zeus138

KOI55

bgo slot

Berita Piala Dunia

ksatriagaming slot

bundesliga 2 table

slot hutang saldo

play slots for fun online

Jika Anda memiliki pertanyaan, silakan kirim email ke [email protected]

â–˛ Kembali ke atas