分享
 
 
 

GBA探索日记(二)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

GBA探索日记(二)

OBJ及OAM

OBJ就是指的一个个的精灵,或者说就是GBA中的小块小块的图片.它其实跟BG差不多.只是它要小一些.它也算个图层.比如GBA中的RPG游戏就喜欢把一个个的人物用OBJ来实现.这样方便控制他们的位置.当然,从GBA探索日记(-)中也可以看到BG的控制其实也是很方便的.而OBJ和BG的差别就是大小.

设置显示模式

如果你的程序里要用OBJ那么,

在设置显示模式的时候需要把DISP_OBJ_ON和DISP_OBJ_CHAR_1D_MAP加进去

*(vu16 *)REG_DISPCNT = DISP_MODE_1 | DISP_OBJ_ON | DISP_OBJ_CHAR_1D_MAP;

#define DISP_OBJ_CHAR_1D_MAP 0x0040 // OBJ Character Data 1D Mapping

#define DISP_OBJ_ON 0x1000 // OBJ ON

下面就直接来看看OBJ在GBA中怎么实现的.

首先要说明的就是OBJ在GBA中显示也是由一个个8x8的小图块拼成,跟BG一样.

共有下面12种大小.

0000: 8 x 8 1000: 8 x 16

0001: 16 x 16 1001: 8 x 32

0010: 32 x 32 1010: 16 x 32

0011: 64 x 64 1011: 32 x 64

0100: 16 x 8

0101: 32 x 8

0110: 32 x 16

0111: 64 x 32

OBJ的数据分三部分.

1.Character

它跟BG的数据格式是一样的,都是由8x8的小图块的图像数据.而且你也可以通过转换BG的工具来转换OBJ的Character.所以说BG和OBJ的数据结构基本是一样的.不过所有的OBJ总共的Character不能超过32K.

256色的OBJ能有512个Characters,每个Characters占8*8=64bytes.而16色的Characters能有1024个.每个Character占8*8/2=32Bytes.似乎比一个BG的256个Character多?但是BG可以有多个,不同的BG可以有不同的Character,而所有OBJ只能共用这512个Charater.

2.Palette

调色板就不用说了,它跟BG一样,支持一个256色调色板或16个16色的调色板.

3.OAM

OAM就是OBJ Attribure Memory的缩写.它就是控制OBJ属性的数据部分.比如OBJ的位置,大小等数据部分就放在这里.每个OBJ的OAM占8个字节,OAM是从内存中07000000h到070003FFh,共1024=8*128,所以OAM总共能有128个.

如何创建一个OBJ呢?

前面我就说过通过转换BG的工具也可以用于转换OBJ.

以前转换BG我建议使用的是AgbLib里的bmp2map.exe,同样,转换OBJ也同样用bmp2map.exe这个工具.

比如我把Character Data放到sprite_gfx这个数组里,把Palette放到sprite_pal里面.(OBJ中没有Map Data,你的转换时可以把Map data也转换进来,只不过后面用不着)

然后在程序里写入:

DmaArrayCopy(3, sprite_gfx,OBJ_MODE1_VRAM,32);

DmaArrayCopy(3, sprite_pal,OBJ_PLTT,32);

把sprite_gfx,sprite_pal拷贝到指定内存中去.

这里又设计到OBJ_MODE1_VRAM和OBJ_PLTT两个内存地址

还是看看AgbLib中是怎么定义它们的吧.

#define PLTT 0x05000000 // Palette RAM

#define PLTT_END (PLTT + 0x400)

#define BG_PLTT (PLTT + 0x0) // BG Palette RAM

#define BG_PLTT_END (PLTT + 0x200)

#define OBJ_PLTT (PLTT + 0x200) // OBJ Palette RAM

#define OBJ_PLTT_END (PLTT + 0x400)

#define VRAM 0x06000000 // VRAM

#define VRAM_END (VRAM + 0x18000)

#define BG_VRAM (VRAM + 0x0) // BG Character/Screen RAM

#define OBJ_MODE0_VRAM (VRAM + 0x10000) // OBJ Character RAM

#define OBJ_MODE1_VRAM (VRAM + 0x10000)

#define OBJ_MODE2_VRAM (VRAM + 0x10000)

#define OBJ_MODE3_VRAM (VRAM + 0x14000)

#define OBJ_MODE4_VRAM (VRAM + 0x14000)

#define OBJ_MODE5_VRAM (VRAM + 0x14000)

#define OBJ_VRAM_END (VRAM + 0x18000)

这里我把BG中的地址也包含近来了,你可以对比一下BG和OBJ中的地址.

然后就是设置OAM(OBJ Attribure Memory).

这里先看看官方文档中是怎么说这个OAM的数据结构的.

特别指出的是上面表格中Character Name是指这个OBJ的起始Character的引索

我将介绍两中方法来设置.

第一种方法很直观,也很简单.这是我在网上看到最多的.

首先定义了数据结构

typedef struct tagOAMEntry

{

u16 attribute0;

u16 attribute1;

u16 attribute2;

u16 attribute3;

}OAMEntry, *pOAMEntry;

//attribute0

#define ROTATION_FLAG 0x100

#define SIZE_DOUBLE 0x200

#define MODE_NORMAL 0x0

#define MODE_TRANSPARENT 0x400

#define MODE_WINDOWED 0x800

#define MOSAIC 0x1000

#define COLOR_16 0x0000

#define COLOR_256 0x2000

#define SQUARE 0x0

#define TALL 0x4000

#define WIDE 0x8000

//attribute1

#define ROTDATA(n) ((n)<<9)

#define HORIZONTAL_FLIP 0x1000

#define VERTICAL_FLIP 0x2000

#define SIZE_8 0x0

#define SIZE_16 0x4000

#define SIZE_32 0x8000

#define SIZE_64 0xC000

//atrribute2

#define PRIORITY(n) ((n)<<10)

#define PALETTE(n) ((n)<<12)

然后写入代码:

OAMEntry sprites[128]; // 这里把总共128个OBJ都定义了,不过我们现在只使用第一个

void InitializeSprites()

{

u16 loop;

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

{

sprites[loop].attribute0 = 160; //y to > 159

sprites[loop].attribute1 = 240; //x to > 239

}

}

void CopyOAM()

{

u16 loop;

u16* temp;

u16* _OAM = (u16*)0x7000000;

temp = (u16*)sprites;

for(loop = 0; loop < 128*4; loop++)

{

_OAM[loop] = temp[loop];

}

}

u16 spriteY=100;

u16 spriteX=100;

InitializeSprites();

sprites[0].attribute0 = COLOR_256 | SQUARE | spriteY;

sprites[0].attribute1 = SIZE_16 | spriteX;

sprites[0].attribute2 = 0 | PRIORITY(0);

由于这个OBJ的Character是从OBJ_MODE1_VRAM的首地址开始写入的,所以它的Character Name就应该是0.所以sprites[0].attribute2 = 0 | PRIORITY(0);

由于GBA中16色的OBJ和256色的OBJ中对于Characters的寻址方式是一样的.那么无论是16色的还是256色的OBJ,它们的起始Characters都应该是OBJ的VRAM+Character Name*32(虽然256色下的Character占64Bytes).

比如看看下面的例子:

如果传输256色的sprite的Character Data到OBJ_MODE1_VRAM+N*32的地址

DmaArrayCopy(3,sprite_gfx,OBJ_MODE1_VRAM+N*32,32);

那么它对应的的attribute2中的Character Name应该是N.

sprites[0].attribute2 = N;

N的范围是0-1023

对于attribute3,我们现在暂时不用.

接下来就是把sprites写到OAM中

要在程序的主循环中不断更新OAM

while(1)

{

// 等待图像缓冲同步

WaitSync();

CopyOAM();

}

第二种方法是AgbLib里面使用的方法.

比如我要显示一个是OBJ

就直接定义个

vu32 bg_oam_buffer[2];

然后同样要写Character和Palette数据进去

DmaArrayCopy(3, sprite_gfx,OBJ_MODE1_VRAM,32);

DmaArrayCopy(3, sprite_pal,OBJ_PLTT,32);

设置OAM的时候就这样写

bg_oam_buffer[0] = OAM_COLOR_256 | OAM_SQUARE |OAM_SIZE_16x16

| (100) << OAM_H_POS_SHIFT

| (72) << OAM_V_POS_SHIFT;

bg_oam_buffer[1] = 0x0400;

下面给出AgbLib中对于上面的宏的定义:

#define OAM_V_POS_SHIFT 0

#define OAM_H_POS_SHIFT 16

#define OAM_COLOR_16 0x00000000 // Select 16

#define OAM_COLOR_256 0x00002000 // Select 256 colors

#define OAM_SIZE_8x8 0x00000000 // OBJ 8 x 8 dot

#define OAM_SIZE_16x16 0x40000000 // OBJ 16 x 16 dot

#define OAM_SIZE_32x32 0x80000000 // OBJ 32 x 32 dot

#define OAM_SIZE_64x64 0xc0000000 // OBJ 64 x 64 dot

#define OAM_SIZE_16x8 0x00004000 // OBJ 16 x 8 dot

#define OAM_SIZE_32x8 0x40004000 // OBJ 32 x 8 dot

#define OAM_SIZE_32x16 0x80004000 // OBJ 32 x 16 dot

#define OAM_SIZE_64x32 0xc0004000 // OBJ 64 x 32 dot

#define OAM_SIZE_8x16 0x00008000 // OBJ 8 x 16 dot

#define OAM_SIZE_8x32 0x40008000 // OBJ 8 x 32 dot

#define OAM_SIZE_16x32 0x80008000 // OBJ 16 x 32 dot

#define OAM_SIZE_32x64 0xc0008000 // OBJ 32 x 64 dot

你可以看出.

bg_oam_buffer[0]其实就是第一种方法的attribute0,attribute1的集合.

bg_oam_buffer[1]就是第一种方法的attribute2,attribute3的集合.

然后同样地在程序住循环里不断更新写入OAM

while(1)

{

DmaCopy(3, bg_oam_buffer, OAM, 8 , 32);

}

这是OAM的定义:

#define OAM 0x07000000 // OAM

#define OAM_END (OAM + 0x400)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有