博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
详细说明GBA的TILE方式(一)(转)
阅读量:2450 次
发布时间:2019-05-10

本文共 5365 字,大约阅读时间需要 17 分钟。

详细说明GBA的TILE方式(一)(转)[@more@]

  引言

  

  研究GBA的TILE方式已经有些时间了。这次总结一下研究成果。

  

  放在网上,希望可以对喜欢开发GBA软件的朋友有所帮助。

  

  一 理论部分

  

  1 GBA显示模式

  

  GBA有5个显示模式。MODE0 ~ 5 。估计大家已经很清楚他们之间的外部区别。

  

  模式 层数 不可旋转防缩, 旋转/防缩 色深

  TITE模式

  0 4 0,1,2,3 ------ 4BIT,8BIT

  1 3 0,1 2 4BIT,8BIT

  2 2 ------- 2,3 4BIT,8BIT

  位图模式

  3 1 -------- ------- 16BIT

  4 双缓冲 1 -------- ----- 4BIT,8BIT

  5 双缓冲 1 -------- ----- 16BIT

  

  造成这些差别的原因是由于96Kb 的VRAM造成的。其中,TILE模式的产生就是为了更好地利用VRAM 。而 3,4,5模式,则更加开放地让用户使用这96K内存。

  

  TIlE方式下,使我们能看到的许多绚丽的画面,都是由许多8X8小块(TILE)组成的。在屏幕上显示则是有一定排列方式的。分为1D方式和2D方式。

  

  关系如下

  

  1D 方式:

  tile被分割。如果想建立一个32X32,16色的OBJ,而且开始的TILE为5,那么在屏幕上显示的方式就回是这样的:

  

  ------------------------

  │ 5 │ 6 │ 7 │ 8 │

  ------------------------

  │ 9 │ 10 │ 11 │ 12 │

  ------------------------

  │ 13 │ 14 │ 15 │ 16 │

  ------------------------

  │ 17 │ 18 │ 19 │ 20 │

  ------------------------

  

  2D方式:

  TILE每一行被存储在32个格子里。 看下面。

  --------------------------------

  │ 5  │ 6  │ 7  │ 8  │

  --------------------------------

  │ 37 │ 38 │ 39 │ 40 │

  --------------------------------

  │ 69 │ 70 │ 71 │ 72 │

  --------------------------------

  │ 101 │ 102 │ 103 │ 104 │

  --------------------------------

  

  编号为此TILES在内存中的位置。

  

  而根据是否旋转又可分成 text方式和ROTATE方式.ROTATE方式下所占内存是TEXT方式下的4倍。

  

  

  2 MAP和TILE的关系

  

  MAP里记录着TILE的索引号,而真正的图象数据是保存在TILE里的,就象4/8BIT图片需要调色盘一样每个象素保存的都是调色盘里的索引值,而真正的颜色是保存在调色盘里的,然后,GBA每次都对MAP里的内容做硬件级的刷新.这就是为什么MODE4下需要翻转,而MODE 0,1,2下不用。

  

  

  3寄存器和内存

  

  由于,GBA是使用了统一编址的方式,把所有硬部件接口都直接连在了总线上,这样做的好处就是可以象操作内存一样地操作接口,方便地和这些部件交换数据,但是另一方面也减少了可利用的内存,不过对GBA来说这不算什么。

  

  几个接口内存地址,如下

  

  VRAM 0x06000000 ~ 0x06017fff 这里面存放这所有图形信息。(TILES也在里面)

  端口是16位的。 共96Kb

  PRAM 0x05000000 ~ 0x050003FF 存放调色盘信息。(什么是调色盘??自己到网上去找)

  端口也是16位的.一共1Kb

  

  还有几个重要的寄存器接口,如下

  

  名字 内存地址

  REG_BG0CNT 0x4000008

  REG_BG1CNT 0x400000A

  REG_BG2CNT 0x400000C

  REG_BG3CNT 0x400000E

  主要是定义各BG层的工作方式。而且是16位的。 (可以想象一下,他们在硬件上是怎么连的)

  

  他们的格式为:(以REG_BG0CNT为例)

  

  F E D C B A 9 8 7 6 5 4 3 2 1 0

  

  Z Z V M M M M M A C X X S S P P

  

  │_│ │ │_______│ │ │ │_│ │_│_________________ 优先级。00最高,11最低

  │ │ │ │ │ │

  │ │ │ │ │ │_______________________ TILE在显存中的开始位置

  │ │ │ │ │_____________________________ 是否有马塞克

  │ │ │ │_______________________________ 0:256色 ,1: 16 色

  │ │ │__________________________________________ MAP数据的存放地址

  │ │ Address = 0x6000000 +M * 0x800

  │ │____________________________________________ 是否可以旋转

  │________________________________________________ 大小 00 为32X32个块,256X256

  

  

  从中,我们可以看到,map的数据和TILE的数据是全部放在VRAM里的。

  

  而参数中,M和S可以分别决定MAP和TILE的开始地址。

  

  正如上面所解释的,map 的开始地址在 VRAM + M * 0x800最小单元为 128个16BIT (因为端口是16位)

  TILE开始地址在 VRAM + SS* 0X4000 最小单位是1024个16BIT

  

  

  从中,我们还可以看出,zz为

  

  text方式,最大画面限制

  00 : 256x256 (32x32 tiles)

  01 : 512x256 (64x32 tiles)

  10 : 256x512 (32x64 tiles)

  11 : 512x512 (64x64 tiles)

  

  rotate方式下最大画面限制

  00 : 128x128 (16x16 tiles)

  01 : 256x256 (32x32 tiles)

  10 : 512x512 (64x64 tiles)

  11 : 1024x1024 (128x128 tiles)

  

  

  REG_BG0HOFS0x4000010 控制BG0水平方向的卷轴

  REG_BG0VOFS0x4000012 控制BG0垂直方向的卷轴

  REG_BG1HOFS0x4000014 控制BG1水平方向的卷轴

  REG_BG1VOFS0x4000016 控制BG1垂直方向的卷轴

  REG_BG2HOFS0x4000018 控制BG2水平方向的卷轴

  REG_BG2VOFS0x400001A 控制BG2垂直方向的卷轴

  REG_BG3HOFS0x400001C 控制BG3水平方向的卷轴

  REG_BG3VOFS0x400001E 控制BG4垂直方向的卷轴

  

  OK,现在,我们已经清楚地了解这些寄存器的结构了。然后,我们可以做一些操作。

  

  二 应用举例

  

  1 在MODE0方式下对BG0画点:

  

  我们先建立一张和GBA屏幕相同大小的图片,分辨率为240X160取名叫BGM.bmp ,必须是256色的。内容随便你。

  

  然后用工具gfx2gba.exe 执行以下操作

  

  gfx2gba -fsrc -M -c256 T8 bgm.bmp

  

  然后会生成几个文件 bgm.map.c bgm.raw.c master.pal.c包含了TILE方式下必须的MAP数据和TILE数据。

  

  而-M参数是不对MAP进行压缩。

  

  我们只需要其中的bgm.map.c就够了。其他不需要。然后加到你的程序中。ARM的编译器回自动把他写入数据段而且只读。

  

  然后得设置BG控制寄存器REG_BG0CNT进行初始化。因为,一般的画点函数,内部都是直接对VRAM的开始进行操作。所以,为了那些函数的可再利用性,就必须把TILE的数据放在头部。(这是利用了2D方式的特性)。而MAP数据的位置是由mmmmmm决定的。故,我们将它放在在别的地方,而不是在头部。(一般的都设置在头部,然后跟TILE数据) 所以我们决定把这个数据放在TILE的后面。

  

  TILES数据占了240X160=38400个字节。而map数据占了60个字节( 240/8 * 160/8)

  

  TILES就放在头部。0x6000000为开始。

  

  MAP应该被放在内存的0x06009600。0x9600 / 0x800 = 0x12 所以MMMMM就等于 10010。

  

  所以就得到了:

  

  REG_BGCNT0 = 00 0 10010 1 00 0 00 00 B = 0x1210

  

  然后把MAP数据传送到0X06009600。可以用DMA,可以用FOR,随便你。

  

  最后不要忘了把调色盘数据也写入0x5000000

  

  好了,初步的工作完成了,接下来,那个画点的函数就可以象在MODE3,4,5下一样使用了。

  

  程序:

  

  //在gba.h中已经有的定义

  //macros

  #define DISPCNT*(u32*)  0x04000000//Sets DISPCNT to be

  #define BG0CNT*(u16*)  0x04000008//Sets BG0CNT to be

  //memory layout

  u16 *s_pal = (u16*)0x05000000;

  //the pallette address

  u16 *VideoBuffer = (u16*)0x06000000;

  //the tile address

  u16 *v_map0 = (u16*)0x06009600; //bkg map

  

  还有就是SetPix(int x,int y,u16 color);

  //在GBA.H里已经有了的那个

  

  //--------------------------------------------------------------------

  

  const u16 pal[16];    //这里是调色盘信息,自己写点数据进去.

  

  const u16 map[600];   //这个是GFX2GBA生成的.

  

  //function

  void initGraph()

  {

    BG0CNT = 0x1210;      //解释同上

    DISPCNT = 0x0140;     //使用MODE0

  

    DMA3( pal,s_pal,16 );   //初始化调色盘

    DMA3( map,v_map0, 600 );  //初始化MAP

  }

  

  int C_Entry()//主程序部分

  {

    initGraph();

  

    SetPix(20,20,3);      //以3号颜色在20,20的位置画一点

  

    while(1){}         //让程序无限循环

  }

  

  //因为VRAM有限,而此画点方式太占VRAM所以不支持使用

  

  2动态MAP//强烈建议

  

  大家一定完过吧,这个游戏利用了大量MAP技巧.其中有个最经典的运用就是,当你选择了一个角色的时候,回出现活动范围。

  

  原理也是对MAP数据进行操作

  

  得到角可行走的坐标后,从新构造MA

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-951693/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8225414/viewspace-951693/

你可能感兴趣的文章
android 更改软键盘_如何在Android上更改Google键盘的主题
查看>>
kodi 缓存文件夹_如何将Kodi图稿与视频存储在同一文件夹中
查看>>
windows隐藏磁盘_如何在Windows的磁盘清理工具中启用隐藏选项
查看>>
如何在Linux或macOS终端中使用Bash历史记录
查看>>
photos设置成中文_如何在OS X的Photos中设置和使用扩展程序
查看>>
大剧院自助签证_如果您的项目是《剧院》,请使用演员
查看>>
windows终端终端_Windows终端介绍
查看>>
小额免密_如何在您的应用中进行小额付款
查看>>
用开源代码如何建立网站_建立全球开源法律网络
查看>>
c&c++语言参考手册_C ++值类别快速参考:第2部分
查看>>
javascript优化_优化性能的十大JavaScript技巧
查看>>
传统网络面临问题_我们每天都面临的最流行的计算机问题
查看>>
aws cmake .._如何将Hyperledger Fabric 1.4部署到AWS
查看>>
unity 场景优化_Unity优化:您的场景层次正在抢劫您
查看>>
如何制作电子邮件而不是一团糟:实用技巧
查看>>
px em rem区别_px,em,rem,%之间有什么区别? 答案在这里
查看>>
pvs-stdio ue4_云中的PVS-Studio:Azure DevOps
查看>>
理想商城_理想产品经理的52个特征
查看>>
移动应用程序开发_7种用于移动应用程序开发的终极编程语言
查看>>
本地应用程序_应用程式本地化的十大语言
查看>>