GBA探索日记(-)

转载 2004年07月02日 17:18:00

GBA探索日记(-)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

mode0-2的BG与VRAM

 

GBAVRAM总共96KB,在mode3-5中,VRAM跟计算机的显示内存一样.屏幕上一个点对应一个显示内存地址.

可以看看下面两个函数,都是在mode4下的写点函数.

void PlotPixel(int x,int y, unsigned short int c)

{

                m_VideoBuffer[(y) * 120 + (x)] = (c);

}

 

void SetPixel(int x,int y,u8 color)

{

                register u16 *tc;

            tc=m_VideoBuffer+y*120+x/2;

                if(x&1)

                               *tc=((*tc&0x00FF)+(color<<8));

            else

                          *tc=(*tc&0xFF00)+color;

 

}

由于GBA支持的最小数据传输单位为16位,而16位在mode4(256色)下为两个点的信息.

所以上面的PlotPixel是对两个点的写法.而SetPixel是通过一些简单的位移运算来实现对单个点的写入.

特别指出的是一个VRAM里的u16的值低8位对应的是前面的点,高8位对应的是后面的点.

 

说了这么多mode4的,下面看看GBA最精彩的部分mode0-2

 

设置REG_DISPCNT这个寄存器

不说多了,它就是指定你要显示的模式和支持的BG.

比如看这个的语句:

*(vu16 *)REG_DISPCNT = DISP_MODE_1 |  DISP_BG0_ON ;

这段语句就是说让GBA支持MODE1的显示模式,并支持BG0

当然你也可以

*(vu16 *)REG_DISPCNT = DISP_MODE_1 |  DISP_BG0_ON | DISP_BG1_ON |DISP_BG2_ON;

但是你不能把BG3也加进来.因为mode1只能支持BG0,BG1,BG2.

 

 

mode0-2都是运用tile(图块)先来组成整个屏幕的.

mode0-2每个都有不同的BG

一个屏幕可以由多个BG组合显示出来.比如你可以安排地面为一个BG,天空为一个BG等等.

每个BG对应一个寄存器

Text BG:就是不能旋转的,似乎只能使用16色.当然,如果使用16色的调色板,当然可以使用最多到16个调色板.

Rotation BG:就是可以旋转的,放大的.只能使用256色.如果使用了256色的调色板,就不能使用16色的调色板了.因为GBA的BG调色板就只有256x2=512那么大.

 

 

再看看不同模式下的BG分配

mode 0: 4个Text BG

mode 1: Text BG:        BG0 BG1

        Rotation BG:    BG2

mode 2: Raotation BG:   BG2,BG3

接下来就看看控制这些BG的寄存器:

1.Text BG

AgbLib任天堂提供的官方开发包里面是这么写出它的寄存器

#define REG_BASE                0x04000000          // Registers

#define REG_BG0CNT      (REG_BASE + 0x8)    // BG 0 Control

#define REG_BG1CNT      (REG_BASE + 0x8)    // BG 1 Control

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

2.Rotation BG

AgbLib任天堂提供的官方开发包里面是这么写出它的寄存器

#define REG_BASE                0x04000000          // Registers

#define REG_BG2CNT      (REG_BASE + 0x8)    // BG 0 Control

#define REG_BG3CNT      (REG_BASE + 0x8)    // BG 1 Control

 

 

Poriority是指的是显示的优先权.

0最高,4最低.

再看看关于BG大小的问题.

Screen Size Setting     Text Screen                     Rotation/Scaling Screen 

                                                                                                       Screen Size  Screen Data                                                                                                 Screen Size  Screen Data 

00                      256×256        2 Kbytes        128×128        256 Bytes 

01                      512×256        4 Kbytes        256×256        1 Kbyte 

10                      256×512        4 Kbytes        512×512        4 Kbytes 

11                      512×512        8 Kbytes        1024×1024      16 Kbytes 

 

 

为了显示一张BG.

你可以通过AgbLib中提供的bmp2map.exe来把一张bmp文件转换成GBA可以用的BG数据.

BG数据分三块.

1.Character Data

前面已经说了.mode0-2下的GBA屏幕是由图块组成的.这些图块都是8x8大的.

这些图块有些人把它叫做Tile,也有些人把它叫做Character(AgbLib里面就是这么叫的).

这些数据就是保存这些8x8图块的图象数据的.

2.Map Data

Map Data可以说是图块的引索.它是记录Character Data的在屏幕中的排布的数据.

3.Palatte Data

这个不用说了,就是调色板

 

在显示一张BG前,应该把上面的上部分数据传输到GBA内存中.

看看下面的代码吧:

DmaArrayCopy(3,e1_Character,           BG_VRAM,                           32);

DmaArrayCopy(3,e1_Map,                  BG_VRAM+0x8000,             32);

DmaArrayCopy(3,e1_Palette,                               BG_PLTT+32*2,                   32);

 

DmaArrayCopy是个数据传输的函数.当然,你也可以使用for(...)一个字节一个字节地写.但是GBA里有3个DMA通道(就是不经过CPU,专门用来传输大量数据的专线),它应该是就像memcpy那样的功能.

上面的代码就是将e1图像文件Character,Map,Palette传输到GBA中对应的内存.

特别指出的是在使用16色的调色板的时候,你如果用bmp2map.exe来转换.那么就要注意这个程序中-p这个参数.它指出了这个Map用的哪个Paletee.比如我上面的那个e1的BG就是使用了-p2,即使用的第2个调色板.那么它在GBA中对应的内存地址应该是BG_PLTT+32*2(16色的调色板总共占32个字节).

你可能要问BG_VRAM,BG_PLTT是什么.

#define PLTT                    0x05000000     

#define BG_PLTT                 (PLTT +        0x0)

#define VRAM                    0x06000000 

#define BG_VRAM                 (VRAM +        0x0)

它们其实就是VRAM,Palette在内存中的指定位置.

Map Data,Character Data都是放在VRAM中的.

mode0-2中,VRAM被分成许多Block,每个2KB(0x800).Character Data比较大一点,它一个要占8个Block(16KB).Map Data比较小一点,它一个占一个Block.

还是看看这张十分有用图片

Character Base Block的值为0-3

Screen Base Block(就是装Map Data的)的值为0-31

当然,不能让他们重复,否则先写的数据就被覆盖了.

再看看设置BG的寄存器的代码吧:

#define TEXTBG_SIZE_256x256                         0x0

#define TEXTBG_SIZE_256x512                         0x8000

#define TEXTBG_SIZE_512x256                         0x4000

#define TEXTBG_SIZE_512x512                         0xC000

 

#define ROTBG_SIZE_128x128                           0x0

#define ROTBG_SIZE_256x256                           0x4000

#define ROTBG_SIZE_512x512                           0x8000

#define ROTBG_SIZE_1024x1024       0xC000

DmaArrayCopy(3,e1_Character,           BG_VRAM,                           32);

DmaArrayCopy(3,e1_Map,                  BG_VRAM+0x8000,             32);

DmaArrayCopy(3,e1_Palette,                               BG_PLTT+32*2,                   32);

*(vu16 *)REG_BG0CNT =

                                BG_COLOR_16 | TEXTBG_SIZE_256x256 | BG_PRIORITY_0

                                | 16 << BG_SCREEN_BASE_SHIFT | 0 << BG_CHAR_BASE_SHIFT;

你对应前面的图看看.

16是Screen Base Block的值,0是Character Base Block的值.

0x8000就是Base Block 16的对应偏移址,0是Base Block 0的对应偏移址

 

GBA硬件上对有很多对BG处理的支持,比如旋转,移动,放大,Alpha,马塞克.

 

我们先看看BG的移动.

这同样也是通过对GBA的寄存器的写入来实现的.

BG2(Rotation BG)中有两个寄存器控制它的位置.REG_BG2X,REG_BG2Y

还是看看它们的定义

#define REG_BASE                0x04000000          // Registers

#define REG_BG2X        (REG_BASE + 0x28)   // BG 2 Start X Coordinate

#define REG_BG2Y        (REG_BASE + 0x2c)   // BG 2 Start Y Coordinate

 

它们是只能写的寄存器,你可不要去读它们,否则读不出来什么有用的数据的.

但是你可以去写它们:

s32 x=10<<8;

s32 y=10<<8;

*(s32 *)REG_BG2X=x;

*(s32 *)REG_BG2Y=y;

需要记住的它们都是32位的数据,而且是有符号的.

x增大,BG向左移,x减小,BG向右移.

y增大,BG向上移,y减小,BG想下移.

x或y每改变256,BG移动1个像素.

所以上面的x,y都使用了<<8

 

 

5-33 地下迷宫探索 (30分) -- dfs

5-33 地下迷宫探索   (30分) 地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式。地道网是房连房、街连街、村连村的地下工事,如下图所示。 我们在回顾前辈...
  • qq_26437925
  • qq_26437925
  • 2015年10月31日 08:42
  • 1719

Android开发艺术探索读书笔记(二)

首先感谢大家支持,昨天第一篇写出来之后反响很好,主席本人也非常赞赏(捂脸~),再接再厉,推出第二篇。这篇的主要内容是对两章View的内容进行总结。不得不说,自定义View是很多开发者的痛点,一方面我们...
  • amurocrash
  • amurocrash
  • 2015年09月25日 13:48
  • 10932

《深度探索C++对象模型》读书笔记——关于对象【for_wind】

//整理之,分享之,欢迎指正。for_wind 1、C与C++的区别:       概括来说,C程序中程序性地使用全局数据[注1]。而C++采用ADT(abstract data tpye)或...
  • for_wind
  • for_wind
  • 2014年03月28日 14:08
  • 1382

游戏编程--GBA探索日记

  • 2008年10月08日 11:06
  • 497KB
  • 下载

gba探索日记

  • 2016年02月12日 20:01
  • 287KB
  • 下载

GBA MOD音乐播放探索!

这是一篇老文章了,最早放在CGDS上. GBA MOD音乐播放探索  写在前面  我并不是搞音乐的,甚至五音不全,仅仅是为了能在GBA上播放MOD音乐,我进行了一些学习,  找了大量资料后,基...
  • lrb2010
  • lrb2010
  • 2013年06月15日 13:33
  • 605

模拟器游戏修改之教你如何修改gba rom里的程序!

模拟器游戏修改之教你如何修改gba rom里的程序!=原创= 修改gba游戏必看! *献给我亲爱的wwy* 今天是它的生日!祝她生日快乐! 所用工具:No$gba1.4C (调试功能异常...
  • qdsw123
  • qdsw123
  • 2013年07月23日 18:39
  • 3770

安卓手机上玩口袋妖怪gba全集的方法

最近想起以前小时候玩口袋妖怪的回忆,想在自己的手机上玩一下口袋妖怪,发现手机市场的搜到的不是崩溃,就是广告多到爆。偶然在一个论坛发现一个口袋妖怪的合集,太高兴了哈哈。 废话少说,上截图 ...
  • penghanying110
  • penghanying110
  • 2016年08月16日 15:46
  • 294

GBA反汇编(烈火之剑<中文版>查找字库)

其实,反汇编很简单,但最好还是看一下每个功能 第一步,下载 No$GBA debug版,注意是后缀是debug; 第二步,ROM,烈火之剑的ROM. 这两样东西,都能用搜索引擎搜索到 第三步 ① ...
  • u012718252
  • u012718252
  • 2013年11月04日 21:34
  • 1463

GBA的16-Bit Multi-player分析

要使用multiBoot把ROM传输到GBA上面,首先需要用Arduino模拟GBA的16bit multi通信协义。先把信息由uart传给arduino再由他把信息转发给GBA。     开机时按s...
  • ESZETA
  • ESZETA
  • 2013年09月01日 21:25
  • 643
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GBA探索日记(-)
举报原因:
原因补充:

(最多只允许输入30个字)