⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gba 开发简单入门.txt

📁 嵌入式GBA掌机开发源码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
GBA 开发简单入门 
 
作者:gbgba.com 文章来源:掌机之王 更新时间:2004-1-22    
 
 
一. GBA开发包--DevKitAdv 简介 
DevKitAdv 主要包括两部分,一是GCC++编译器,二是 GBA库. 

GCC++编译器功能和我们常用的VC差不多,只不过少了个编辑源代码的文本编辑器(至少我没发现,我用的是EditPlus,UltraEdit也可以),还有就是--不支持类(class),真是让人头痛,只能用struct来替代.它的作用是把我们写的代码编译成二进制的可执行文件,当然这个可执行文件是相对GBA和GBA模拟器而言的.就象Windows里的EXE文件无法在Mac机上使用是一样的道理; 

GBA库提供了图像,控制及声音一系列的函数,和GCC++配合使用. 

 
 
二. DevKitAdv 的安装 

没啥好说的,解压后就可以直接使用,编译时设置DevKitAdv的路径就可以了,建议做一个批处理文件,比如 go.bat 

set PATH=d:\devkitadv\bin;%PATH% 

cmd (win98是command) 



 
三. 最简单的 GBA 程序 (t1) 

	// main.c 

	// 一些基本数据类型

	typedef unsigned char u8;

	typedef unsigned short u16;

	typedef unsigned long u32;

	#define REG_DISPCNT *(u16*)0x04000000		// 显示寄存器地址

	#define VRAM 0x06000000			// 图像缓冲区地址

	#define M5_VRAM 0x0600A000			// M5缓冲区地址 

	#define BACKBUFFER  0x010			// 双缓冲/背缓冲地址

	#define PALETTE 0x5000000			// 调色板地址

	#define MODE_3 0x03				// 240*160 15bits/单缓冲区

	#define MODE_4 0x04				// 240*160 8bits/双缓冲区

	#define MODE_5 0x05				// 160*128 15bits/双缓冲区

	#define BG2_ENABLE 0x0400			// BG_2

	#define SetMode(Mode) REG_DISPCNT=(Mode)     // 设置显示模式的宏定义



// ----------- 主程序 ------------

	int main()

	{

		//设置屏幕模式,这里使用MODE_4

		SetMode (MODE_4 | BG2_ENABLE); 

	}
1.MODE_5和MODE_3都是16bits,但MODE_3只有单缓冲,制作动画效果肯定没双缓冲好,因此排除MODE_3; 

2.MODE_4是8bits,理论上256色对于掌机够用了,虽然16bits真彩的诱惑没有人想抗拒,可MODE_5只有160*128咧,在实际应用中建议还是使用MODE_4.

很简单吧--的确是的,现在要用GCC编译它: 

gcc -lm -o main.elf main.c 

objcopy -v -O binary main.elf main.bin 




你会看目录下多了个"main.bin",这个就是能在GBA模拟器上执行的二进制文件! 
教程中t1-t7目录为源程序目录,里面有个make.bat,修改代码后直接执行它就可以编译,但要注意我的devkitadv是装在D:,你要是装在别的盘就得改一下make.bat的path参数.





 
四. 在MODE_4背景层画图的 GBA 程序 (t2) 

在GBA的MODE_4里画一幅图要经过3个步骤:

1. 把原始256色图像文件转换成 *.h / *.c 的数据文件,我们用的是 < BMP2GBA > ,这里以"image.bmp"为例,转换后我们就得到了一个"image.h"文件;

2. 在程序开头#include "image.h",这样就能在程序中使用"image.h"定义的调色板和图像数据;

3. 在程序中把"image.h"定义的调色板和图像数据写入MODE_4背景层的调色板和图像缓冲区.

另外,GBA还有专为精灵设置的物体层,它的用法和背景层一样,只是功能有点不一样,地址是0x06000000.有关用这里就不详细说了,大家可以把精灵数据直接输出到物体缓冲区就可以了.

下面是源程序:

	... ...



	// 包含图像调色板和数据的头文件

	#include "gfx/image.h"

	

// ----------- 全局变量 --------

	// 系统调色板

	u16* palette_mem=(u16*)PALETTE;

	// 图像缓冲区

	u16* video_buffer=(u16*)VRAM;



// ----------- 函数定义 ---------

	// MODE_4绘图函数

	void Draw(u16* src_palette,u16* src_data,u16* dst_palette,u16* dst_data);



// ----------- 主程序 ------------

	int main()

	{



		// 设置屏幕模式,这里使用MODE_4

		SetMode (MODE_4 | BG2_ENABLE); 



		// 在背景层画图,Palette和Data是在"image.h"定义的调色板和图像数据数组名

		Draw(Palette,Data,palette_mem,video_buffer);

	}



	// MODE_4绘图函数

	void Draw(u16* src_palette,u16* src_data,u16* dst_palette,u16* dst_data)

	{

		int loop,x,y;



		// 写入目的调色板

		for(loop = 0; loop < 256; loop++)

			dst_palette[loop] = src_palette[loop];



		// 写入图像缓冲区

		for(x = 0; x < 120; x++)

		{

			for(y = 0; y < 160; y++)

			{

				dst_data[(y) *120 + (x)]=src_data[(y) *120 + (x)];

			}

		}

	}

编译后得到main.bin,然后在GBA模拟器里运行,就可以得到这样的结果:



大家看了可能有点失望~是啊,256色用来看PPMM实在... ...下一步我们就使用MODE_5来画16bits真彩的MM!

 
五. 在MODE_5画图的 GBA 程序 (t3) 
在GBA的MODE_5里画一幅图也要经过相似3个步骤,只不过不需要调色板数据:

1. 把原始真彩图像文件转换成 *.h / *.c 的数据文件,我们用的是 < Targa2GBA > ,这里以"image.bmp"(240*160)为例,DOS窗口下进Targa2GBA目录,输入"t2g mode5 image.bmp image.h",转换后我们就得到了一个"image.h"文件;

2. 在程序开头#include "image.h",这样就能在程序中使用"image.h"定义的图像数据;

3. 在程序中把"image.h"定义的图像数据写入图像缓冲区.

下面就是源程序:

	// 包含图像数据的头文件

	#include "gfx/image.h"

	

// ----------- 全局变量 --------

	// 图像缓冲区

	u16* video_buffer=(u16*)VRAM;



// ----------- 函数定义 ---------

	// MODE_5绘图函数

	void Draw(int x,int y,int w,int h,u16 *src_data,u16 *dst_data);



// ----------- 主程序 ------------

	int main()

	{

		// 设置屏幕模式,这里使用MODE_5

		SetMode (MODE_5 | BG2_ENABLE); 



		// 在背景层画图,image是在"image.h"定义的图像数据数组名

		Draw(0,0,240,160,image,video_buffer);

	}



	// MODE_5绘图函数

	void Draw(int x,int y,int w,int h,u16 *src_data,u16 *dst_data)

	{

		int i,o,idst;

		

		// 把源图像数据复制到图像缓冲区的指定地方

		idst =(y*160)+x;

		for (i=0;i<h;i++)

		{

			for (o=0;o<w;o++)

			{

				if (*src_data != 0) 

				{

					dst_data[idst] = *src_data;

				} 

				idst++;

				src_data++;

			} 

			idst += (160-w);

		}

	}


编译后运行结果:



呵呵,是不是很棒?这是24bits "image.bmp"(240*160) 在MODE_5 16bits下的显示结果,240*160的图像到了MODE_5下的160*128,也就是MODE_5的满屏显示画面只有这么大.

 
 
六. 全屏显示的 MODE_5 GBA 程序 (t4)

由于GBA不支持线性的图像变换,因此得到的结果会产生一些马赛克的现象,现在还是附上这个变换函数和最终结果,其实质量还是可以接受的,大家可以试试使用这个新的MODE_5.

	// 切换到新MODE_5全屏模式,page为缓冲区,原理是把显示寄存器数据X,Y交换,得到128*160的显示,GBA就会全屏显示.

	void SetFlipMode(int page)

	{

		u16  *ioreg=(u16*)0x4000000;

	

		*ioreg=5+((page&1)>>4)+(1>>10);

		ioreg[0x10]=0;

		ioreg[0x11]=256;

		ioreg[0x12]=128;

		ioreg[0x13]=0;

	}



	int main()

	{

		// 设置屏幕模式,这里使用MODE_5

		SetMode (MODE_5 | BG2_ENABLE); 



		// 切换模式

		SetFlipMode(0);



		// 在背景层画图,image是在"image.h"定义的图像数据数组名

		Draw(0,0,240,160,image,video_buffer);



		return(0);

	}


Come on,来看看结果:



此时就是新MODE_5下的全屏模式,图像被翻转并放大,因为MODEL_5的分辨率是160*128,而上面的程序画的是240*160的图像,所以有部分就看不到了.

如果要象MODEL_4那样正常显示我们的图像,那么只有对原图像文件做点手脚才行了,下面就是处理新MODEL_5下图像文件的步骤:

1.把原图像顺时针旋转90度;

2.再将图像水平翻转;

3.调整图像大小至 160*128.

这里是示意图:

原图 1 2 3 
    

OK,把步骤3后的图像编译进bin就可以得到:



大家可以看到有轻微的马赛克,但比起256色的效果还是要好一些,到底使用什么模式还得看做的游戏类型,如果是一些经典RPG/ACT/SLG等还是建议用MODE_4.

 
 
七. GBA的双缓冲显示(t5)

大家在做上面MODEL_5的程序时一定会发现图像在闪动(第六节的240*160的MM象被破了相...),而MODEL_4下却比较稳定--这是因为MODEL_5下要处理16bits(实质上是15bits)的图像,数据量比MODEL_4下的8bits大很多,在没使用双缓冲的情况下,图像填充时就会造成闪烁,这就是为什么我们抛弃了MODEL_3的原因...

原理也很简单,图像在背缓冲区里填充好之后再直接输出到前缓冲区显示,程序里就是一个 "等待同步-> 交换缓冲" 的过程:

	... ...

// ----------- 全局变量 --------

	// 图像缓冲区

	u16* video_buffer=(u16*)M5_VRAM;



// ----------- 函数定义 ---------

	... ...



	// 等待缓冲区数据同步

	void WaitSync ();

	// 交换缓冲区内容

	void SwapScreen ();



// ----------- 主程序 ------------

	int main()

	{



		// 设置屏幕模式,这里使用MODE_5

		SetMode (MODE_5 | BG2_ENABLE); 



		while(1)

		{

			// 在背景层画图,image是在"image.h"定义的图像数据数组名

			Draw(0,0,240,160,image,video_buffer);

			WaitSync();

			SwapScreen();

		}

	}





	// 等待缓冲区数据同步

	void WaitSync ()

	{

		while (*(volatile u16*)0x4000006<160) {};

	}



	// 交换缓冲区

	void SwapScreen ()

	{

		if (REG_DISPCNT & BACKBUFFER)

		  {	  

			  REG_DISPCNT &= ~BACKBUFFER;

			  video_buffer = (u16*) M5_VRAM;

		  }

		else

		  {	  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -