armoha / euddraft

System for pluginizing eudplib codes.
Other
29 stars 4 forks source link

Question: How to get non-English TBL address? #24

Closed Chromowolf closed 9 months ago

Chromowolf commented 3 years ago

GetTBLAddr(TBLkey) would return the TBL address of the corresponding TBLkey, but it is English. Suppose I change my starcraft to Chinese or Korean, GetTBLAddr(TBLkey) still get me English:

function afterTriggerExec() {
    const tblAddr = dwread_epd(EPD(0x6D1238));
    const s = StringBuffer(1024);
    s.printfAt(8, "TBL pointer = {}", hptr(tblAddr));
    s.printfAt(9, "GetTBLAddr(1) = {}", hptr(GetTBLAddr(1)));
    s.printfAt(10, "Print TBL str(1): {:s}", GetTBLAddr(1));
}

Chinese: tbl Korean: tblKo

When I open CheatEngine to browse memory, I did spot a block of memory which is similar to stat_txt.tbl, but in Chinese/Korean. This means there must be a stat_txt.tbl of Chinese/Korean version. But how Can I get the address?

armoha commented 3 years ago

Currently SC:R loads English version of stat_txt.tbl once you write on any tbl entry without providing table to pointer. Back to old versions of SC:R, it loaded English stat_txt.tbl once you accessed tbl pointer (0x6D1238) but didn't provide table.

You can extract stat texts with CascView, and include it in your map with dataDumper.

This means there must be a stat_txt.tbl of Chinese/Korean version. But how Can I get the address?

I'm not sure whether they are in EUD accessible addresses. I think comparing base address and seeking adjacent memory region might help (STR starts from 0x191943C8, default English TBL at 0x19184660. not guaranteed to be close to each other in actual memory though.)

Chromowolf commented 3 years ago

I downloaded CascView and only found one stat_txt.tbl (which is the English version) in the Game Storage. For other languages, there are xml and json files of the stat, but no tbl file. Thank you though!

armoha commented 3 years ago

Yeah, they have different structure. That's why I said stat texts, not tbl. :) EUD Editor includes Korean tbl which is manually converted from xml. (hence has some typos..) My mental model is that there is only English TBL and when EUD emulator detects writing on tbl, it loads English TBL.

Chromowolf commented 3 years ago

My mental model is that there is only English TBL and when EUD emulator detects writing on tbl, it loads English TBL.

Through my experiment: Case (1): No EUD triggers. Only one TBL could be detected through memory-browsing, corresponding to the language setting. This TBL has 1551 entries and uses 4-byte values to store the number of strings and each string's offset. I believe this is what the pointer in 0x6D1238 points to, in this case. I've tried setting the language to English/Chinese/Korean. All of them could be extracted from memory and I'm sure they are TBLs.

Case (2): There is at least one EUD trigger. But there is no trigger trying to write/modify TBL. Two TBLs could be detected through memory-browsing. One is the TBL in case (1), but I don't know who points to it. The other is the TBL that the pointer in 0x6D1238 points to, which has only 1539 entries and uses 2-byte values to store the string offsets. As can be seen in my pictures posted, the unit name at the bottom is still Chinese/Korean, while the TBL pointer points to the "strange" English TBL. This means there is some undiscovered pointer pointing to the Chn/Kor TBL in this case. Don't know how to access it by EUD. Actually, the eps function GetTBLAddr(key)'s parameter key becomes meaningless if greater than 1539, since the TBL pointer pointer points to the 1539-entry TBL for all EUD maps.

Case (3): There are some EUD triggers trying to write/modify TBL. Same as case(2), there are also 2 TBLs found in memory. However, starcraft will use the "strange" English TBL to show unit names.

Actually what I was trying to do is display unit names (providing unit ID) with respect to the user's language setting: If he sets the language to English, then the unit's English name is displayed. If Korean, then the unit's Korean name is displayed. I know I could work arround this by just manually dumping the Korean/Chinese unit names into memory, and detecting the user's language setting by some means or other...... But if that "hidden" Chn/Kor TBL pointer in case(2) is known, then I could achieve this by something like StringBuffer(1024).printfAt("name={:s}", GetTBLAddr_Chn(TBLkey));, which is much easier than dumping the texts manually.

Anyway thx for your help!

armoha commented 3 years ago

In few versions ago, 1.22 or more, both Case (2) and (3) used default English TBL. Even adding no-op condition like Memory(0x6D1238, Exactly, 0) made emulator to believe that the map has custom stat texts and loads the tbl.

StringBuffer(1024).printfAt("name={:s}", GetTBLAddr_Chn(TBLkey));, which is much easier than dumping the texts manually.

Yeah that would be cool for melee style UMS maps which use default unit names.

It is not surprise to see an EUD behavior change between SC:R patches. https://cafe.naver.com/edac/91337 For example, weapon missile rotating near target now has more boring flying trail. :(

armoha commented 9 months ago

tldr; there's no way to retrieve default stat_txt.tbl strings other than English. But not all hope is lost! LocalLocale is added in next verion of eudplib (https://github.com/armoha/eudplib/commit/74deb57ad9a773bf56a1289d7f00590969aa711d). Every maps will detect user locale on game starts, so you can embed stat texts for every supported languages in your map, and choose set of strings to use according to user locale.