DragonLord
级别: 火花会员
编号: 618
精华: 11
发帖: 7802
威望: 25 点
配偶: 单身
火 花 币: 27499 HHB
组织纹章:
所属组织: 火花老年协会
组织头衔: 呆瓜小贼
注册时间:2002-12-09
最后登陆:2020-02-20
|
gba纹章地图修改入门。
地图这个问题终于有了进展。 我就不说应该如何跟踪了,那是基本不可能讲清楚的。我就直接说地图是如何生成的。事先声明,我玩nogba时间并不长,算不上是什么ASM高手,所以有说不清楚和说错的地方,就多多包涵了。 我拿圣魔第一章逃忘来举例子。首先,用crystaltile打开rom,定位到00 18 88 88,你可以看到10 xx xx xx的数据,凡是lz77压缩的,都是这种样子开头的,解压缩后调整,得到这个图。(顺便说一下,论坛置顶那个crystaltile早就过时了,最新的应该支持直接lz77解压缩的,我是在巴士x玩下的。)回到正题,这张图一看就知道是什么意思了,就是地图的显示。当然这仅仅是地图的显示,如果你把这里面的城堡改成斗鸡场,那么你进入游戏后会发现每当遇到这样的城堡,样子都变成了斗鸡场,但实际效果还是城堡,这当然不是我们想要的结果。附近包括这张在内,一共有8张这样的地图。游戏运行的时候,会根据当前章节数有把8张中的某一张读入一块内存,我们先设这个内存区域是X。我可以告诉你,游戏的前三章都是只读了这一张就拼成每一章的地图了,那么游戏是怎么有选择性的找出里面的地图并拼起来的呢? 你现在定位到1A6F88,是10 xx xx xx,解压缩后,看到了什么?是不是什么也没看到?我告诉你这就是第一章的地图,你不信的话,到rom里改几下就知道了。如果你想问这个地址是怎么找到的,这是一步步倒推跟踪出来的,至于怎么跟踪的,这就不是这篇文章讲的内容了。不是说我技术保密 ,而是讲汇编语句太过繁琐,而且显然不会有人有什么兴趣,所以我只说结果,不涉及具体编程。 地图生成就是从这里开始的,在你选择第一章逃亡后,后,先是把1A6F88解压缩,里面的数据全部写入到内存02001000里面。然后,再把02001000的数据,复制到内存02032FB4里面,这一次的复制和第一次不同,每次复制完30个字节后,需要“换行”,所谓换行,直观的理解就是地图上的排数,写完一排,当然要换一排,为什么是30个字节呢,因为第一章的地图宽度是15个格子,15个格子,就是30个字节,2个字节代表1个格子。30个字节复制完后,现在当前地址应该是02032FB4+1E(就是十进制的30)= 02032FD2。在开始新地址复制数据之前,把刚刚的02032FB4这个数据,记录到02032F88这里。同样道理,向02032FD2这里复制完30个字节后,把02032FD2这个数据,写入02032F90里面,也就是02032F88+8。依此类推,把02001000的数据全部复制过来。这里姑且把02032FB4,02032FD2,……,这种地址称为段地址,而像02032F88,02032F90,……这样的地址称为段地址指针。 这些东西在你选择某一章后就固定下来了。在游戏里,每次你从人物画面或者访问民家等事情切换回地图后,系统就是会根据段地址指针找出段地址(即哪一行),加上段内偏移地址,也就是每一行的第几个格子,这个合成后的地址里的数据,也就是刚刚内存02001000往内存02032FB4里写的数据,也就是rom往内存02001000里写的数据。比如说我们取1A6F8F的8C 01(之前那个0F 0A是地图大小,宽15格,高10格我这里取第二个)。 先高低位颠倒,即18C,把这个数据*2,变成318,再加上02030B88,得到了02030EA0(这个是程序里的固定算法,没有为什么),02030EA0当然也是个内存地址,把这个内存地址里的数据取出来,是个2字节的,比如20 03,再加上6000h,就是80 03,这个东西,就是一个格子里左上角那个tile的最终代码(一个格子实际是由4个小方块,也就是由4个tile组成,),接着对02030EA0这个地址进行处理,02030EA0+2这个地址就是右上角这个tile的代码,02030EA0+40就是左下角这个tile的代码,而02030EA0+40+2就是右下角这个tile的代码,由此,一个格子拼成了。02030EA0这个地址附近都是地图tile代码,如果把这块区域定义成Y,你还记得刚刚我开始说的内存区域X吗?这两个地方是对应的,Y是什么代码,x这里就根据这个代码取出20个字节,这20个字节就是具体画出某个tile的代码。X和Y这两样东西,都可以用VBA看到的,属于最终的结果。内存拼地图是从右下角拼到左上角的。 复杂的写完了,最后用概括的写一遍。这个应该很容易看懂。(括号里的字不用看) 1,ROM写到内存A(断点1100) 2,内存A写到内存B(断点080196C6) 3,内存B经过变换写到内存C(断点1270) 4,内存C取出数据,经过变换成为tile代码A 5,tile代码A经过变换成为tile代码B。 6,根据tile代码B拼成地图代码。 补充: 1,你可以完全不懂过程,也能修改,就是找到地图开始的地址,比如1A6F88,其他地图应该在附近,我没找过。解压缩后,你把某两个字节换成其他的,进入地图试试,就明白什么代表什么了。 2,由于X和Y的对应关系没有找,所以虽然可以创作出新的地图,但只是在原来的基础上修改,并不能在原有地形不变的情况下,创造出新的地形。 3,我找到的那东西,只是地图的显示而不是实际的地形效果。但实际上在rom里改了后,还是有地形效果的。因为地形效果那一段的程序,还是根据rom里这个代码来的,我只是没找到,并不代表那段程序就不起作用了。 4,跨地图修改我没研究过。比如斗鸡场和城堡不是在一张地图显示图片里。
[ 此贴被DragonLord在2007-04-17 21:28重新编辑 ]
|
|
[楼 主]
|
Posted:2007-04-17 16:12| |
顶端
| |