最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

口袋妖怪綠寶石——數(shù)據(jù)提取與代碼分析(3-地圖信息提取)

2022-08-18 10:53 作者:圍巾胖頭魚  | 我要投稿

說在前面:

????口袋妖怪綠寶石的ROM中保存了游戲世界中的所有地圖,這些地圖信息要比前幾期專欄介紹的文本信息更加直觀。但作者并沒有選擇這么直觀的信息作為一開始就介紹的對象,是因為要想把提取地圖信息的功能拓展到綠寶石的改版上,前幾期專欄介紹的知識和方法是必不可少的。

????在網(wǎng)絡(luò)上,提取ROM的地圖信息有很好用的工具,在這期專欄主要介紹Advance Map。

Advance Map地圖信息提取工具

????Advance Map的官方網(wǎng)址:

????http://ampage.no-ip.info/index.php?seite=advancemap

????它的最新版本是1.95,最后一次更新于2011年。在這個版本更新后的10年(2021年),工具的作者在官網(wǎng)上表示TA已經(jīng)不會再更新這款軟件了。雖然是一款比較老的工具,但是還算好用。

????打開Advance Map,如果看到的是英文界面,可以在左上角菜單欄的“Settings-Language”里面把語言改成“簡體中文”:

設(shè)置軟件語言為簡體中文

????從“文件——讀取ROM”中打開口袋妖怪綠寶石的ROM文件。如果打開的是原版綠寶石的ROM,讀取過程會十分順利,左側(cè)會出現(xiàn)3個選項,最常用的是第一個“通過頭文件”,把它展開就可以看到一些標著數(shù)字的選項,如果再次打開其中一個,比如“0”,里面會列舉出一系列地圖的名字,雙擊第一個名字,地圖的信息就會顯示在界面中間:

打開“橙華市”的地圖

????對于第一次使用這個工具的讀者,如果你們感覺這個工具很有趣的話,相信好奇心會驅(qū)使著你們探索這個工具的各種功能,這不是本期專欄的重點。網(wǎng)絡(luò)上也有一個Advance Map的簡單教程:

????https://www.hackromtools.info/advance-map/

????本期專欄是要利用Advance Map這個工具來探索ROM中地圖信息的組織結(jié)構(gòu)。

綠寶石ROM中地圖信息的組織結(jié)構(gòu)

????從Advance Map左側(cè)的列表中可以看到,每個地圖被放在一個以數(shù)字命名的文件夾內(nèi),同時每個地圖的名字后面都會有一個括號括起來的、由逗號隔開的兩個數(shù)字。例如上圖“橙華市”的地圖名稱“PETALBURG CITY (0,0)”,其中第一個0指的是它位于“0”這個文件夾內(nèi),第二個“0”表示它在該文件夾內(nèi)是第一張地圖。

????事實上,ROM中組織地圖信息的結(jié)構(gòu)也是這樣的:每張地圖用兩個數(shù)字來表示它的編號:第一個數(shù)字被稱作地圖庫編號,第二個數(shù)字被稱作地圖編號。這兩個編號就是每張地圖區(qū)別于其他地圖的標識。

????一張地圖需要存儲的信息很多,而且每張地圖大小不一定相同,這和前幾期專欄處理的“每行結(jié)構(gòu)一樣”的數(shù)據(jù)是很不一樣的。有一種辦法可以讓這些大小不一的數(shù)據(jù)擁有一個統(tǒng)一的“長度”,就是使用指針

????C語言中的指針是一個重要的知識點,本期專欄只介紹ROM中的指針。ROM中的指針是一段長度4個字節(jié)的數(shù)據(jù),這4個字節(jié)按照小端序的方式拼接起來,表示的是ROM中的一個地址,也就是這個指針指向的地址

????有了指針這個概念,無論一張地圖需要存儲多少數(shù)據(jù),只需要把這塊數(shù)據(jù)的起始地址保存成一個指針,就可以用4個字節(jié)來表示這張地圖,所有的地圖就都具有相同的長度了。這就好比一條大街上有飯店、超市、醫(yī)院等等,它們各自有長度不同的名稱,但是用“某某街某號”就可以用統(tǒng)一的方式稱呼它們一樣。

????Advance Map左側(cè)的列表中,每個以數(shù)字命名的文件夾就是地圖庫,可以把它們稱作“0號地圖庫”“1號地圖庫”……每個地圖庫中存儲的地圖數(shù)量也不相同,如果每個地圖庫都需要一個固定長度的數(shù)據(jù)來表示,指針也成為了最適合的選擇。

????指針在綠寶石ROM中的使用十分普遍,希望讀者能夠盡快熟悉指針的使用,下面馬上就會給出一個例子。

????在綠寶石源代碼的符號表中,gMapGroups這個符號表示所有的地圖庫:

gMapGroups

????我們在HxD中找到這個地址,看看gMapGroups的內(nèi)容是什么:

HxD的跳轉(zhuǎn)功能

????用HxD打開ROM文件,使用“搜索——跳轉(zhuǎn)”或者Ctrl+G快捷鍵,在輸入框內(nèi)輸入gMapGroups的地址,然后點擊確定跳轉(zhuǎn)到該地址:

全部地圖庫

????光標停留到的位置就是gMapGroups的地址,觀察一下這里的數(shù)據(jù),有個很明顯的規(guī)律就是以每4個字節(jié)為一組,組內(nèi)的后兩個字節(jié)都是48 08。這里,“以每4個字節(jié)為一組”就是指針的典型特征,把第一組數(shù)據(jù)60 5D 48 08按照小端序拼接的結(jié)果是08485D60,回到符號表中查看一下,發(fā)現(xiàn)這個地址是有名字的:

0號地圖庫的名稱

????08485D60這個地址就是0號地圖庫的指針,它的名字“gMapGroup_TownsAndRoutes”表明這個地圖庫中存儲的是各個城鎮(zhèn)(Towns)和道路(Routes)的地圖,讀者可以從Advance Map中去驗證這一點。

????以此類推,第二組4字節(jié)數(shù)據(jù)44 5E 48 08,對應(yīng)到地址08485E44,也就是“gMapGroup_IndoorLittleroot”,存儲的是未白鎮(zhèn)(Littleroot)各個房間室內(nèi)(Indoor)的地圖。

????這樣一來地圖庫的結(jié)構(gòu)就非常清晰了。gMapGroup(地址088486578)存儲了所有地圖庫的指針,并且有如下規(guī)律:地址08487578+X * 0x4 處存儲的4字節(jié)變量就是X號地圖庫的指針

????接下來可以看看地圖庫gMapGroup_TownsAndRoutes(地址08485D60)的指針指向了什么內(nèi)容:

0號地圖庫的數(shù)據(jù)

????規(guī)律很明顯,0號地圖庫存儲的也是一系列的指針,第一個指針是084824B8,同樣可以在符號表中找到名字:

0號地圖庫的0號地圖

????PetalburgCity就是橙華市,這和我們在Advance Map中看到的0號地圖庫內(nèi)的0號地圖是橙華市地圖是吻合的。這樣,地圖庫的結(jié)構(gòu)也很清晰了。地圖庫存儲了該地圖庫內(nèi)所有地圖的指針,并且有如下規(guī)律:X號地圖庫地址+Y?* 0x4 處存儲的4字節(jié)變量就是X號地圖庫Y號地圖的指針。

????因此,我們可以將gMapGroups稱作“地圖庫指針列表”,每個地圖庫也可以稱作“X號地圖庫的地圖指針列表”,這是一個完全由指針組織的數(shù)據(jù)結(jié)構(gòu),它就像一個個指路牌,指引游戲程序找到需要使用的數(shù)據(jù)。

地圖數(shù)據(jù)

????然而指路牌畢竟不是目的地本身,指針指來指去最后還是要指向有實際意義的數(shù)據(jù)才行。下面以084824B8處的PetalburgCity為例,看看一張地圖究竟包含了哪些數(shù)據(jù)。

????在Advance Map中,打開中間界面的“地圖頭”選項卡:

地圖頭選項卡

????如果讀者看到的不是這個界面,可以在“設(shè)置”中勾選“專業(yè)地圖頭查看模式”,或者按Ctrl+H快捷鍵。這個“地圖頭”就是橙華市地圖包含的數(shù)據(jù),接下來依次解釋一下:

  • 地圖庫頭:00486578,指的就是gMapGroups

  • 地圖庫編號:0號地圖庫;地圖庫地址:0號地圖庫gMapGroup_TownsAndRoutes

  • 地圖編號:0號地圖;地圖頭地址:0號地圖庫的0號地圖PetalburgCity

????這里出現(xiàn)了一個新的概念“地圖頭”,把Advance Map切換回英文界面時這個名稱是Map Header,這是按照綠寶石源代碼項目中的名字來命名的。事實上,源代碼中恰好有一個叫做MapHeader的結(jié)構(gòu)體,定義的就是地圖:

地圖頭MapHeader結(jié)構(gòu)體

????可以看到結(jié)構(gòu)體的定義里面,開頭的4個變量都是指針,分別對應(yīng)了Advance Map里面的“地圖尾地址”“事件地址”“地圖腳本地址”和“連接地址”。再后面的變量,在Advance Map的“專業(yè)地圖頭查看模式”下就看不到了,可以按Ctrl+H把它關(guān)閉了再看:

非專業(yè)模式下的地圖頭查看

????結(jié)構(gòu)體中從相對地址0x10處的變量在上圖中顯示出來,音樂、洞穴、天氣等等。

????“專業(yè)地圖頭查看模式”下,可以看到“地圖頭”的后面列舉了一串字節(jié),這就是HxD中把字節(jié)照搬過來的結(jié)果,對比MapHeader結(jié)構(gòu)體的定義、Advance Map兩種查看模式下給出的解釋,哪段數(shù)據(jù)是什么含義是一目了然的。

????利用Advance Map,提取地圖信息會變得十分方便。還有很多功能本期專欄沒有介紹,有感興趣的讀者可以在討論區(qū)討論。

Advance Map的缺陷

????作為一個超過十年沒有更新的軟件,Advance Map有各種缺陷是很正常的,其中作者認為最嚴重的兩個缺陷如下:

  • 不支持漢化版ROM,也沒有開放能夠支持漢化編碼的功能。如果使用Advance Map打開一個漢化版的綠寶石ROM,所有的地圖名稱都會顯示亂碼,這和在“設(shè)置”中把軟件語言改成“簡體中文”完全是兩回事。說明Advance Map本身就不支持對ROM中漢字的解碼。顯示亂碼還是小問題,只要能打開地圖就行,關(guān)鍵是有的亂碼里面包含了沒有配對的括號(比如只有左括號而沒有右括號),Advance Map就會提示這個地圖名稱不合法,拒絕打開地圖,但實際上能不能打開地圖和地圖的名字完全沒關(guān)系。

  • 打開ROM的過程中,出現(xiàn)的報錯信息不夠詳細,有時很難根據(jù)報錯信息找到打不開ROM的原因。對于一些改版的ROM,里面存儲的地圖信息的位置可能發(fā)生了變化,導(dǎo)致Advance Map找不到,這時它就會出現(xiàn)報錯信息。有的報錯信息會告訴你是因為哪個符號沒找到導(dǎo)致的ROM打不開,有的報錯信息則沒有什么信息量,需要自己去配置文件里一個一個調(diào)整才能發(fā)現(xiàn)問題在哪。下面的一個小節(jié)會給出報錯信息的例子。

????既然Advance Map的作者不打算修bug了,那么這個系列的專欄會給出一些彌補的辦法。

用Advance Map打開ROM

????打開原版綠寶石時,作者用簡單的一句“文件——讀取ROM”就帶過了,但實際上如果打算用Advance Map打開一個改版過的綠寶石ROM,會遇到數(shù)不清的問題。下圖為作者試圖打開某個改版ROM時,Advance Map的報錯信息:

報錯信息1
報錯信息2

????一般來說,只要這種報錯的信息框彈出來,左側(cè)就不會顯示任何地圖的列表,什么地圖信息也沒有。在第二張報錯圖里面,軟件還“好心地”提示有什么問題可以聯(lián)系軟件作者的郵箱,當(dāng)然這個辦法肯定是不管用了。

????解決報錯問題的關(guān)鍵,在于修改Advance Map的配置文件,它涉及的內(nèi)容很多,留到下期專欄具體來講。

瞬移金手指和地圖編號的關(guān)系

????在綠寶石系列游戲中,有一類金手指被稱作“瞬移金手指”,打開適當(dāng)?shù)乃惨平鹗种负螅?dāng)游戲角色進行進門、出門等操作的時候,就會瞬移到金手指指定的地點,這類金手指利用的就是地圖編號信息,下面用游戲來舉個例子。

????在符號表中,有一個符號名稱叫做gSaveBlock1Ptr:

gSaveBlock1Ptr

????以“Ptr”結(jié)尾的變量往往表示一個指針(Pointer的簡寫Ptr),它指向的是gSaveBlock1這個變量。從VBA中打開原版綠寶石的游戲,看看這個地址處是什么:

打開內(nèi)存查看器
利用內(nèi)存查看器查看數(shù)據(jù)

????03005D8C處確實是一個指針,指向02025A20,再看看這個地址處的數(shù)據(jù):

????

02025A20處的數(shù)據(jù)

????這里的001A表示Y坐標,0006表示X坐標,后面的2B18數(shù)據(jù),0x18是地圖庫編號,0x2B是地圖編號,也就是24號地圖庫、43號地圖,我們從Advance Map里驗證一下:

冠軍之路1F地圖

????這和游戲是吻合的,當(dāng)前游戲角色的確位于冠軍之路的第1層。在地圖上移動鼠標時,Advance Map的左下角會顯示當(dāng)前的X坐標和Y坐標,也可以驗證當(dāng)前角色所在的位置是不是對應(yīng)的上。

????2B18的地址是02025A24,只要修改這個地址處的2字節(jié)變量就可以實現(xiàn)瞬移金手指。

????但是,不要指望這個金手指能一直起作用!02025A24這個地址是會變化的,變化的原因需要在后續(xù)專欄分析代碼的時候給出解釋。

????本期專欄還有一個遺留問題沒有解決,就是如何修改Advance Map的配置文件以便打開改版的ROM,,這個問題留到下期專欄具體說明。

????對Advance Map還不太滿意的讀者,如果有編程能力的話不妨寫一個parser,本期專欄已經(jīng)解釋了地圖數(shù)據(jù)是如何組織的,使用程序來讀取并不困難。

????繼續(xù)感謝眾位讀者的支持!

口袋妖怪綠寶石——數(shù)據(jù)提取與代碼分析(3-地圖信息提取)的評論 (共 條)

分享到微博請遵守國家法律
台南市| 左贡县| 和田市| 广东省| 邓州市| 郸城县| 当阳市| 长汀县| 嘉定区| 玉田县| 保定市| 富蕴县| 梁河县| 年辖:市辖区| 巴中市| 南投县| 陇川县| 左权县| 中西区| 朔州市| 类乌齐县| 江门市| 汪清县| 华阴市| 鄂温| 绥宁县| 敦化市| 琼中| 百色市| 长春市| 攀枝花市| 林甸县| 泰州市| 江北区| 青海省| 兰考县| 商南县| 丰城市| 古蔺县| 沧源| 石狮市|