[转]DS游戏3D建模材质贴图搜索与定位的入门方法 by tring

这个稍微说一下:' 0-15 Texture VRAM Offset div 8',在no$gba中会给出AABBCCDD这样32位的值,而这个offset实际是CCDDh,而不是AABBh。

另外 '使得其执行将4000240~4000243的值全部修改为80的操作',把下面内存改成80后上面的指令也会变,这时要再次让游戏运行到那个指令,这时就打开LCDC了。

 

 

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

 

本帖的前提是使用收费的DEBUG版NO$GBA,没有这东西的不用找我要了。虽然不使用NO$在原理上也可以完成,但是本文只讨论最简单的入门方法,作启发之用。
至于本文所介绍方法的作用,多在于汉化方面,现在3D游戏越来越多,传统2D图片定位的方法却无法适用于3D的材质贴图上,因此某些图片的导出与修改以传统的2D方式很难实现。
以下开始是正文。

1,以NO$提供的3D引擎查看工具找到目标材质贴图
NO$自带工具可以检索当前3D引擎内已载入的建模,运行游戏,在屏幕上显示出目标的建模,之后暂停进程。
打开3D查看窗口后会看到有一系列树型列表。列表的前半部分不是我们关注的内容,从后半部分开始,会看到树型列表前带有+号可展开选项的,这部分即是当前3D引擎中被载入的建模。
这时鼠标点选这些列表项,会在左侧显示该建模的3D轮廓(以红线勾出)并且在下方显示其使用的材质贴图。找到你所要定位的目标,展开其前一项的+号(这里注意,一定是其前一项而不是其本身这项)。
在 展开的子项中,不难发现一项名称叫做teximage_param的子项,其下还有一项叫做pltt_base。注意到在这2项之前,左侧下方显示的材质 贴图还是属于上一个建模的,而这2项之后则属于目标建模的了,这是因为这2项的设定即是材质贴图的设定,在这2项之后,下次出现该2项之前的部分,全部使 用这里设置的材质贴图。
pltt_base项所包含的内容是该材质贴图所使用的色板,不在本文所讨论的范围内,有兴趣的可以自行研究。该接口定义见GBATEK的DS 3D TEXTURE ATTRIBUTES章节。
teximage_param则是材质贴图的详细信息,由于这个接口的重要,这里帖出在GBATEK里的定义几个本文用的到的说明:
40004A8h - Cmd 2Ah - TEXIMAGE_PARAM - Set Texture Parameters (W)
0-15 Texture VRAM Offset div 8 (0..FFFFh -> 512K RAM in Slot 0,1,2,3)
    (VRAM must be allocated as Texture data, see Memory Control chapter)
16   Repeat in S Direction (0=Freeze last texel-column, 1=Repeat Texture)
17   Repeat in T Direction (0=Freeze last texel-row,   1=Repeat Texture)
18   Flip in S Direction   (0=No, 1=Flip each 2nd Texture) (requires Repeat)
19   Flip in T Direction   (0=No, 1=Flip each 2nd Texture) (requires Repeat)
20-22 Texture S-Size     (for N=0..7: Size=(8 SHL N); ie. 8..1024 texels)
23-25 Texture T-Size     (for N=0..7: Size=(8 SHL N); ie. 8..1024 texels)
26-28 Texture Format     (0..7, see below)
29   Color 0 of 4/16/256-Color Palettes (0=Displayed, 1=Made Transparent)
30-31 Texture Coordinates Transformation Mode (0..3, see below)
Texture Formats:
0 No Texture
1 A3I5 Translucent Texture
2 4-Color Palette Texture
3 16-Color Palette Texture
4 256-Color Palette Texture
5 4x4-Texel Compressed Texture
6 A5I3 Translucent Texture
7 Direct Texture
由于本文仅仅是为了定位材质贴图,因此这里我们只关心0-15位的OFFSET和26-28位的材质格式。其它部分说明请自行参考GBATEK的DS 3D TEXTURE ATTRIBUTES章节。
值得一提的是,NO$的3D查看工具中会自动在该项后标注材质的格式属性等,因此这里我们只用关注0-15位的OFFSET。
OFFSET即是该项8位16进制内容的低4位,将该数值乘以8,即是材质贴图在VRAM中的偏移地址。而关于VRAM的内容,下一节详细讨论。


2,修改VRAM属性以定位材质贴图在VRAM中的地址与内容
在 介绍方法前我先大致介绍一下DS的VRAM。所谓VRAM即是显存,也就是DS的图形引擎在处理图像的时候所使用的缓存。DS的主要VRAM总共有9组, 包括传统2D图片分析时所使用的6000000,62000000,64000000,66000000等几个映射地址对应的VRAM,但是主VRAM并 非是完全对应CPU平坦地址的。除了主VRAM外,还有几个其它的VRAM,是与CPU地址完全对应的,分别是:
5000000h Engine A Standard BG Palette (512 bytes)
5000200h Engine A Standard OBJ Palette (512 bytes)
5000400h Engine B Standard BG Palette (512 bytes)
5000600h Engine B Standard OBJ Palette (512 bytes)
7000000h Engine A OAM (1024 bytes)
7000400h Engine B OAM (1024 bytes)
不过这些VRAM也不在本文的讨论范围内,有兴趣的请自行参考GBATEK的DS MEMORY CONTROL - VRAM章节
9组不同的主VRAM每一组都对应1个控制接口,以确定该VRAM的工作方式,这里帖出控制接口定义与我们关注的几种控制方式的说明,其它内容请自行参考GBATEK的DS MEMORY CONTROL - VRAM章节。
4000240h - NDS9 - VRAMCNT_A - 8bit - VRAM-A (128K) Bank Control (W)
4000241h - NDS9 - VRAMCNT_B - 8bit - VRAM-B (128K) Bank Control (W)
4000242h - NDS9 - VRAMCNT_C - 8bit - VRAM-C (128K) Bank Control (W)
4000243h - NDS9 - VRAMCNT_D - 8bit - VRAM-D (128K) Bank Control (W)
4000244h - NDS9 - VRAMCNT_E - 8bit - VRAM-E (64K) Bank Control (W)
4000245h - NDS9 - VRAMCNT_F - 8bit - VRAM-F (16K) Bank Control (W)
4000246h - NDS9 - VRAMCNT_G - 8bit - VRAM-G (16K) Bank Control (W)
4000248h - NDS9 - VRAMCNT_H - 8bit - VRAM-H (32K) Bank Control (W)
4000249h - NDS9 - VRAMCNT_I - 8bit - VRAM-I (16K) Bank Control (W)
0-2   VRAM MST         ;Bit2 not used by VRAM-A,B,H,I
3-4   VRAM Offset (0-3)   ;Offset not used by VRAM-E,H,I
5-6   Not used
7   VRAM Enable (0=Disable, 1=Enable)
There is a total of 656KB of VRAM in Blocks A-I.
Table below shows the possible configurations.
VRAM   SIZE MST OFS   ARM9, Plain ARM9-CPU Access (so-called LCDC mode)
A     128K 0   -   6800000h-681FFFFh
B     128K 0   -   6820000h-683FFFFh
C     128K 0   -   6840000h-685FFFFh
D     128K 0   -   6860000h-687FFFFh
E     64K   0   -   6880000h-688FFFFh
F     16K   0   -   6890000h-6893FFFh
G     16K   0   -   6894000h-6897FFFh
H     32K   0   -   6898000h-689FFFFh
I     16K   0   -   68A0000h-68A3FFFh

VRAM   SIZE MST OFS   Texture/Rear-plane Image
A,B,C,D 128K 3   0..3 Slot OFS(0-3)   ;(Slot2-3: Texture, or Rear-plane)

VRAM   SIZE MST OFS   Texture Palette
E     64K   3   -   Slots 0-3           ;OFS=don't care
F,G   16K   3   0..3 Slot (OFS.0*1)+(OFS.1*4) ;ie. Slot 0, 1, 4, or 5
由于本文不研究色板,故这里唯一感兴趣的就是的是可以用作材质缓存的4组VRAM:VRAM A-D即SLOT 0-3。
这 里需要特别提到一点,非常重要,“In Extended Palette and Texture Image/Palette modes, VRAM is not mapped to CPU address space, and can be accessed only by the display controller (so, to initialize or change the memory, it should be temporarily switched to Plain-CPU mode).”即是说当VRAM被设为用于存放材质贴图或者材质色板时,该VRAM便只可被DS的图形引擎使用,而对CPU不但不可用,甚至不可见,也就 是说根本不存在地址对应。而当需要访问修改其内容的时候,必须先将模式切换到对CPU地址平坦的模式(Plain-CPU或称作LCDC),这时这些 VRAM被映射到6800000开头的地址空间中,见上面对于LCDC模式的说明。而关于各VRAM当前的工作模式,可以在NO$提供的I/O MAP查看工具中的CPMEM9页看到。

关于VRAM的介绍到此为止,接下来便说明在VRAM中找到材质贴图的方法。
由于上面说道的VRAM当缓存材质贴图时对于CPU不可见这个性质,因此这步的核心在于修改VRAM的属性到LCDC模式。
最 为简单而直接的方式,可以在此时的NO$代码窗中直接修改代码,使得其执行将4000240~4000243的值全部修改为80的操作。但是切记不可直接 在内存窗修改这4个接口的值,因为NO$只有在代码运行时修改了接口才会将其反应到内核状态中,直接在内存表格中的修改将直接被忽略。
另外还有一 种方法可以设置一个4000240的写入断点,跟踪出游戏在LOAD时修改该接口的函数入口(因为游戏在LOAD材质贴图时也必须将属性切换到LCDC才 可对VRAM操作),然后直接在代码窗口中修改代码调用该函数即可。最典型的做法可以将原ROM调用等待扫描中断的函数(即运行时暂停,十有八九会停到的 地方)调用给替换成修改VRAM属性的函数调用。这时再放行程序就会发现游戏里的所有3D建模的材质贴图都不显示了,而只剩下最简单的多边形。此时用IO MAP查看器就可以看到VRAM A-D的属性全变成了LCDC

完成至此,VRAM以彻底向我们开放,即这时可以对其内容进行确认了。 这时要用到在第一步得到的那个4位16进制的OFFSET值了,将此OFFSET*8+6800000即是该材质此时对应的VRAM映射地址。得到该地址 后即可直接在内存窗口中查看该地址便是材质贴图的内容了。



3,以VRAM中的材质贴图地址和内容定位该贴图在ROM中的偏移地址
其实到这步就和传统2D时的方法没什么区别了。不过为了文章的完整性,还是大致介绍下好了。

这时其实有几种途径可以选择,最简单的方法,当然就是直接使用VRAM中的材质贴图的内容,选个10+位有有特点的数据,然后直接在ROM中搜索。这种方法往往能最快也最直接的得到所需结果,但是这种方法只能适用于未压缩过的数据

然而若要精确定位的话,则可使用下面方法,该方法对于压缩过的数据也有效。
首先对于刚才得到的材质贴图在VRAM中的地址设置一个内存写入断点,然后跟踪LOAD过程,在跟踪中找到载入材质贴图的代码,看代码找到其载入源地址(一般来说就是个普通内存空间的地址)。然后重复上面的步骤,对该内存地址设置写入断点,再找其源地址。
通常来说这时候其源会有几种情况,如果是经一个比较复杂的算法从另一段内存中运算得来的,那么这多半是一个解压算法,对那段运算前的内存地址再重复前面的步骤。
如 果说是由4100010这个接口的数据直接写入的,那么说明该数据直接读取自ROM。这时打开NO$的IO MAP查看器,在IRQ9那页的NDSSLOT项中可以看到一个B7开头的16进制数据串,这个数据串中除开B7那项,接下来的4项连接起来构成一个8位 16进制的OFFSET地址,即是该数据在ROM文件中的偏移地址了。



以上,本文仅供技术交流,内容颇为入门旨在启发各位思路。本人能力有限,若有错误还请指出并包涵。
欢迎转载,但转载请注明作者与出处。

参考文献:
GBATEK:   http://nocash.emubase.de/gbatek.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值