AtomCrafty / UniversalInjectorFramework

A framework to inject your own code into Windows applications.
46 stars 3 forks source link

Weird Duplication of Characters in Names #1

Closed SGifto73 closed 1 year ago

SGifto73 commented 1 year ago

Hello, I'm not sure if this project is still getting active development but I figured I'd shoot my shot anyways.

I'm using this tool for the translation of a visual novel using the Yu-RIS game engine (https://vndb.org/v5928), and it almost works perfectly, except for one small issue.

image For some reason, characters in names are duplicated, but only English names. The protagonist is renamable in this game but it isn't just her that suffers from the bug.

image Another name suffering from the duplication glitch.

image As you can see though, if I leave her name in Japanese, the duplication doesn't occur.

I narrowed down the bug to the "character replace" feature specifically, the problem is I need to use that to get rid of the "Japanese quotation marks" (「」) as these are generated by the engine I'm pretty sure (I don't see them in the script.)

So I guess my question is, why would the character replace function cause this? And why would it duplicate on the second characters and onward in each name?

Files.zip Here's the DLL I'm using along with the config file.

AtomCrafty commented 1 year ago

Hmm, I'm not quite sure what could be causing this. Do you know which text API the engine uses (TextOut / GetGlyphOutline)? If not, could you upload the engine .exe for me so I can check?

SGifto73 commented 1 year ago

image I should've screenshotted the console too, sorry about that. Seems like it uses TextOut.

SGifto73 commented 1 year ago

image I figured I could also show you what happens with character substitution turned off. As you can see the name renders fine, but that "u" and "v" are 「 and 」respectively, so I need to get rid of them with the character substitution tool.

AtomCrafty commented 1 year ago

winmm.zip Please try running it with this version of the .dll. I just added a line to dump all strings to the console before and after substitution.

SGifto73 commented 1 year ago

image image image

Here's the results, every character seems to be in there 5 times, most of it has no anomalies other than that so I tried to just capture the parts with anything weird possibly happening.

SGifto73 commented 1 year ago

Probably easier to put it in a text file. test.txt

AtomCrafty commented 1 year ago

Okay, I believe I understand what's going on. The engine tries to draw the name one character at a time, so for the name 伊藤綾子 it would call TextOut four times, each time passing 1 for the c parameter to only draw one character.

伊
 藤
  綾
   子

伊藤綾子 ⟵ final result

My TextOut hook however ignores the c parameter, so it draws the full string every time. With the Japanese name that isn't immediately obvious, because even though 子 is drawn multiple times, it is drawn in (almost) the same location each time.

伊藤綾子
 藤綾子
  綾子
   子

伊藤綾子 ⟵ final result

The alignment isn't perfect though, you can actually see some remnants of the first 子 in the screenshot you sent earlier.

image

Now, where that issue really becomes obvious is when we start using latin characters. They are much narrower than the kanji, but the engine still moves the cursor by the same number of pixels it would expect a full width character to take up.

Ayako
  yako
    ako
      ko
        o

Ayyaakkoo ⟵ final result

I will fix the hook to properly handle the c parameter, but I can't do much about the fact that the letters will be very far apart, as that is caused by the engine itself.

A
  y
    a
      k
        o

A y a k o ⟵ final result

I guess you could add some custom code that ignores the c parameter if and only if the string passed to it is exactly one of the character names, and ignore all subsequent TextOut calls with suffixes of said name.

Ayako      ⟵ matches a known name, so draw it entirely
 (yako)    ⟵ suffix of a name, not drawn at all
   (ako)   ⟵ suffix of a name, not drawn at all
     (ko)  ⟵ suffix of a name, not drawn at all
       (o) ⟵ suffix of a name, not drawn at all

Ayako      ⟵ final result
SGifto73 commented 1 year ago

Thanks a lot for the response! yeah I see the first 子 in the screenshot you posted, I see how it works now. The problem is that because the protagonist is nameable, I don't know if I could pull the "known name", unless there's a way to somehow fetch it, so that leaves me I think with either using the wide names after you fix that or just telling end users to use the default name (which I ideally wanted to avoid but I wouldn't be entirely against it), thank you a lot though.

AtomCrafty commented 1 year ago

Fixed by f4d3ab2

AtomCrafty commented 1 year ago

The problem is that because the protagonist is nameable, I don't know if I could pull the "known name", unless there's a way to somehow fetch it, so that leaves me I think with either using the wide names after you fix that or just telling end users to use the default name (which I ideally wanted to avoid but I wouldn't be entirely against it), thank you a lot though.

I have a few ideas how to work around it without having to hard code the names, but I believe that discussion would be more suited for Discord than a GitHub issue. My Discord tag is AtomCrafty#4511, if that's fine with you.