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

📄 gba 开发简单入门.txt

📁 嵌入式GBA掌机开发源码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
			  REG_DISPCNT |= BACKBUFFER;

			  video_buffer = (u16*) VRAM;

		  }

	}




 
八. GBA 的按键输入(t6)

讲了老半天的图像,虽说是对着MM,但大家一定也有点烦了,我们现在就换个方向,来看看GBA的控制.

	... ...

	// 按键控制

	#define KEY_A 1

	#define KEY_B 2

	#define KEY_SELECT 4

	#define KEY_START 8

	#define KEY_RIGHT 16

	#define KEY_LEFT 32

	#define KEY_UP 64

	#define KEY_DOWN 128

	#define KEY_R 256

	#define KEY_L 512

	volatile u32* KEYS = (volatile u32*)0x04000130;







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

	#include "gfx/image.h"

	

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

	// 图像缓冲区

	u16* video_buffer=(u16*)M5_VRAM;

	// 图像显示坐标

	int img_x,img_y;



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

	// 按键控制

	void KeyAction();

	... ...

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

	int main()

	{



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

		SetMode (MODE_5 | BG2_ENABLE); 



		while(1)

		{

			// 处理按键事件

			KeyAction();

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

			Draw(img_x,img_y,96,64,image,video_buffer);



			WaitSync();

			SwapScreen();

		}

	}



	// 处理按键事件

	void KeyAction()

	{

		// 上方向键

		if(! ( (*KEYS) & KEY_UP) )

		{

			img_y+=5;

		}

		

		// 下方向键

		if(! ( (*KEYS) & KEY_DOWN) )

		{

			img_y-=5;

		}

	}

	


简单吧,这个例子响应上下按键来控制图像上下移动.我们没有先清除背缓冲就在里面填充图像数据,所以你可以看到图像移动后,原来位置上的图像仍在背缓冲里,这样可以很清楚的看到双缓冲的工作过程.



什么?太丑了,那好,加一个背景就OK了嘛... ...后一幅是带ALPHA.

#include "bg.h"

... ...


// 先画背景
Draw(0,0,160,128,bg,video_buffer);
// 再画MM
Draw(img_x,img_y,96,64,image,video_buffer);


... ...


  

 
九. 简单声音输出(t7)

Simple is the Best(简洁至上),这里我们使用一个现成的声音模块(Troff Player,by Vova & Serge).这里还要用到一个转换工具< MOD2GBA >,用来把MOD音乐文件转换成GBA的 *.c / *.h 声音数据文件.MOD和MIDI差不多,但支持更多更强的效果.

	// MOD数据文件

	#include "song_data.h"

	// MOD播放函数文件

	#include "modplayer.h"



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

	int main()

	{

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

		SetMode (MODE_4 | BG2_ENABLE); 



		// 初始化声音(声道数,音量)

		InitSound(2, 7);

		// 初始化音乐(节拍,循环)

		InitSong(20000, 0);



		while(1)

		{

			// 更新音乐播放状态

			UpdateSong();

		}

	}




OK,就这么EZ.
 
十. 用图块建立可滚动/缩放/旋转的背景(t8)

这一节主要是源程序中注释为主,这里就不详细说明了."gba.h"包含基本宏定义,"maths.h"是sin/cos乘256后的值数组,"main.h"包括了我们定义背景结构及操作背景的函数.

程序中的地图背景是由不同的图块所构成,而这些图块统一紧挨着放在一个图像文件,这样每个图块就会有一个索引号;地图信息只要记录这张地图里共有多少个 单位(图块)以及每个单位对应的图块索引号就OK了,在例子中"gfx/tiles.h"就是图块大本营,而"gfx/level1.h"则是图块索引排列表.地图工具为"map editor beta 4".

背景的滚动/缩放/旋转是通过一系列的简单数学计算,修改GBA系统提供的一些背景属性来完成,因为是由硬件来完成背景的操作(MODE_1),所以速度很快,我还有个MODE_5下直接修改像素点位置来完成旋转的例程,待会儿大家可以比较一下.


 
十一. MODE_5下的背景旋转(t9)

这个例子通过计算旋转后像素的新位置来完成旋转,原理很简单,可以直接应用到精灵上.

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

	int main()

	{

		// 角度

		int i=0;

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

		SetMode (MODE_5 | BG2_ENABLE); 



		while(1)

		{

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

			Draw(0,0,128,128,bg,video_buffer);

			// 将旋转后的背景数据写入图像缓冲

			RotateBG(bg,video_buffer,i++);

			if (i==360)	i=0;

		}

	}



	// 旋转背景

	void RotateBG(u16 *src,u16 *dst,int angle)

	{

		int x,y,ys,yc,tx,ty;

		unsigned int srcptr=0,dstptr =0;



		// 计算旋转后像素的指针

		for (y=-80;y<80;y++)

		{

			ys = y * Sin [angle];

			yc = y * Cos [angle];

			for (x=-80;x<80;x++)

			{

				tx =(((x*Cos [angle]) - ys))>>7;

				ty =(((x*Sin [angle]) + yc))>>7;

				srcptr = (((ty<<7)+tx+(160*80+80)) & 16383);

				dst [dstptr] = src [srcptr];

				dstptr++;

			}	

		}





	}




 

 
 
十二. GBA下的中文显示

呵呵,英文的还没来得及写就先把中文搞掂了~~~~

这里所做的程序核心技术来自于DOS下的中文显示技术.其实和老外用位图来显示26个英文字母原理大同小异,我们使用16*16点阵字库来完成中文的显示.

大家一定知道在输入法里有一个从没用过区位(内码)输入法,这个输入法使用4个数字来完成中文输入----估计没有谁会用它来和MM聊天.中文字库其实也就可以看成一张很大的位图,上面按一定顺序画满了常用的汉字,而区位(内码)输入法的4个数字代表了一个汉字在字库里所在的区和具体位置.

举个例子,"说"字的区位码是"4321",当我们选择区位输入而且在记事本里输入"4321",输入法程序就会马上到字库里4321区域,然后把4321区域的点阵(位图)数据传给系统显示出来,这样"说"字就出来了.

在GBA里显示中文是一样的原理,但由于GBA没有文件输入/输出函数,我们不得不先把二进制的点阵字库转换成数组存储数据,包括区位码和点阵(位图)数组.这里就不详细说明原理了,我为大家做好了一个
转换工具----" HZK2GBA "(汉字库->GBA).附带源程序^_^.

你首先得把你所有的文字做成一个文本文件,比如" zk.txt ",然后执行" hzk2gba zk.txt "来得到" GBAZK.h "文件,这就是GBA可用的字库数组头文件.

这样做的目的是不用把字库里所有的汉字送入GBA,只留下我们用到的汉字,可以很大的节省空间和内存.

接下来的工作就是利用得到的" GBAZK.h "在GBA里写下你想写的话.

	... ...

	#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))		 // 设置GBA的色彩

	#define MAX 10240							 // 最大字符数



	// 包含中文字库数据的头文件

	#include "gfx/GBAZK.h"



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

	// 图像缓冲区

	u16* video_buffer=(u16*)VRAM;



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

	int main()

	{



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

		SetMode (MODE_5 | BG2_ENABLE); 



		// 写入字符

		DrawText("水银教程",20,20,255,0,0);

	}



//- 写中文字符函数 ----------------

	void DrawText(unsigned char *str,int x,int y,int r,int g,int b)

	{

		int i,j,k,n;

		// 字符所在区,位,实际位置

		int qu, wei, location;



		while(*str)

		{

			// 得到单字的区位码

			qu = *(str++)-0xa0; 

			wei = *(str++)-0xa0; 

			location = qu*94+wei; 

			

			// 在字库里查找

			for(n=0 ;n<NUM_STR;n++)

			{

				if(ZKQW[n]==location)

				{

					// 根据字符数据画出字符

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

						for(j=0;j<2;j++)

							for(k=0;k<8;k++) 

								if(convert(ZKDATA[n*32+i*2+j],7-k))

									DrawPixel(x+j*8+k,y+i,r,g,b); 

					x+=16; 

				}

			}

		}

	}





	int convert(u16 str,int n) 

	{ 

		return((str>>n)&0x1); 

	} 



//- 画点函数 ---------------------

	void DrawPixel(int x, int y, int r, int g, int b)

	{

		video_buffer[x+y*160] = RGB(r,g,b);

	}








就这么多了,字体样式的问题得等下一步解决TrueType字体显示才行,字体大小嘛,大家自己用背景/物体层的缩放或是直接缩放像素的方法试试.至于英文的显示~~~~~ ^_* ,好困噢~~~~ 下回见!!!!!


 
 

⌨️ 快捷键说明

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