Create and Fuck your AI Cum Slut -70% Summer Sale
x

VN Others WIP Do You Like Your Girlfriend's Mom? [Final] [Heiantei]

xorxorrax

Member
Modder
Apr 12, 2020
365
1,867
1734046659784.png
Description
Aoyagi Yoshino wanted to be a pianist when she was young, but she couldn't achieve that dream.
Now, she's the president of a company, is married and has a daughter.
Her daughter has talent with the piano too, so Yoshino wants her to become a pianist and achieve the dream that she couldn't.
Everything was fine until her daughter got a boyfriend.
Yoshino thinks that having a boyfriend is gonna make her daughter not want to study abroad and her piano dream will fail again.
So, Yoshino decides to seduce her daughter's boyfriend in order to make him break up with her.​

Original Name:
Kanojo no Okaa-san wa Suki Desu ka? ~Cool na Hitozuma Shachou o Rouraku Seyo!~
カノジョのお母さんは好きですか?~クールな人妻社長を籠絡せよ!~
Release Date: 2014-08-17
Developer: Heiantei -
VNDB:
Censored: Mosaic
Version: Final
Language: English (unedited gpt-4o)
Genre:
You don't have permission to view the spoiler content. Log in or register now.

Installation:
You don't have permission to view the spoiler content. Log in or register now.


STATUS: Game text should be fully translated. Missing main menu and options TL. Game may crash save often.

DOWNLOAD
Win: -
 

Acerius

Member
Mar 12, 2018
125
569
xorxorrax THX! Is there a guide to do this for other Heiantei games? I tried with Translator++, GARbro, CSystemTools, etc... I just seem to never figure what are the correct steps to put it all together. Would be nice to have some of their other games in readable English and not rely on Textractor.
 

xorxorrax

Member
Modder
Apr 12, 2020
365
1,867
xorxorrax THX! Is there a guide to do this for other Heiantei games? I tried with Translator++, GARbro, CSystemTools, etc... I just seem to never figure what are the correct steps to put it all together. Would be nice to have some of their other games in readable English and not rely on Textractor.
No guide. CSystem is niche enough for the tools that exist no to work out of the box. I've had to modify CSystemTools, VNTextProxy and VNTextPatch to make this work and sadly these modifications probably wont work on the other games.

fwiw, I plan to translate a couple more Heiantei games this year.
 
  • Yay, update!
Reactions: Acerius

xorxorrax

Member
Modder
Apr 12, 2020
365
1,867
Can I ask how to make vntextproxy turn full-width text to half-width?
Like I said in the post above you have to code it yourself, I don't really mind sharing my .dll hooks and code but it's useless unless you know how to code and reverse engineer the game. Most of the games have slight differences that makes a general solution hard to make so I just usually code every game patch separately, making changes as necessary.

C:
#include "pch.h"

void HeianteiProportionalizer::Init()
{
    ImportHooker::Hook(
        {
            { "CreateFontIndirectA", CreateFontIndirectAHook },
            { "TextOutA", TextOutAHook },
        }
    );

    // Hardcoded address for SelectObject
    OriginalSelectObject = reinterpret_cast<decltype(OriginalSelectObject)>(0x48CFC5);

    ReplacementFont.CreateFont(
        114,
        0,
        0,
        0,
        FW_SEMIBOLD,
        FALSE,
        FALSE,
        FALSE,
        DEFAULT_CHARSET,
        OUT_TT_PRECIS,
        CLIP_DEFAULT_PRECIS,
        ANTIALIASED_QUALITY,
        DEFAULT_PITCH | FF_DONTCARE,
        L"Tahoma"
    );
}

void HeianteiProportionalizer::ApplyPatches()
{
    // Hardcoded address for the function that prints characters
    OriginalCsystemPrintChar = reinterpret_cast<decltype(OriginalCsystemPrintChar)>(0x469820);

    DetourAttach(reinterpret_cast<void**>(&OriginalCsystemPrintChar), CsystemPrintCharHook);
    DetourAttach(reinterpret_cast<void**>(&OriginalSelectObject), SelectObjectHook);
}

HFONT HeianteiProportionalizer::CreateFontIndirectAHook(LOGFONTA* pFontInfo)
{
    if (LastFontName.empty())
    {

        LastFontName = L"Tahoma";
        TextFont = FontManager.FetchFont(L"Tahoma", 29, true, pFontInfo->lfItalic, pFontInfo->lfUnderline);
    }
    HFONT res = CreateFontIndirectA(pFontInfo);
    return res;
}

BOOL HeianteiProportionalizer::TextOutAHook(HDC dc, int x, int y, LPCSTR pString, int count)
{

    if (IsInCsystemPrintChar)
    {
        wstring text = SjisTunnelEncoding::Decode(pString);
        wstring halfWidth = StringUtil::ToHalfWidth(text.c_str());

        return TextOutW(dc, x + 5, y - 5, halfWidth.data(), count);
    }
    return TextOutA(dc, x, y, pString, count);
}

CFont* HeianteiProportionalizer::SelectObjectHook(CDC* pThis, UINT32 edx, CFont* pFont) {
    if (IsInCsystemPrintChar)
    {
        return OriginalSelectObject(pThis, edx, &ReplacementFont);
    }
    return OriginalSelectObject(pThis, edx, pFont);
}

UINT32 __fastcall HeianteiProportionalizer::CsystemPrintCharHook(uintptr_t pThis, UINT32 edx, UINT32 unknown1, UINT32 unknown2, CHAR* pText)
{
    int CHOICE_X_OFFSET = 380;
    static int lastY = 0;

    wstring text = SjisTunnelEncoding::Decode(pText);
    wstring halfWidth = StringUtil::ToHalfWidth(text.c_str());

    IsInCsystemPrintChar = true;

    // text positions
    int* X = reinterpret_cast<int*>(pThis + 0x1c4);
    int* Y = reinterpret_cast<int*>(pThis + 0x1c8);

    int cX = *X;
    int cY = *Y;

    //If the text is a choice (we can tell by the Y position), we need to set its X since the text is centered
    if(cY >= 520)
        AdaptRenderArgs(halfWidth.c_str(), 1, TextFont->GetHeight(), cX, cY);
    else {
        if (lastY != cY) {
            cX = CHOICE_X_OFFSET;
        }
        else {
            cX += CHOICE_X_OFFSET; // hacky trick to make the text appear in the right place
        }
        AdaptRenderArgs(halfWidth.c_str(), 1, TextFont->GetHeight(), cX, cY);
    }

    *X = cX;
    *Y = cY;
    lastY = cY;

    UINT32 res = OriginalCsystemPrintChar(pThis, edx, unknown1, unknown2, pText);

    IsInCsystemPrintChar = false;

    return res;
}
To be specific, this code here:
Code:
wstring text = SjisTunnelEncoding::Decode(pString);
wstring halfWidth = StringUtil::ToHalfWidth(text.c_str());
Is the one that converts the text to half-width.

The rest is for the font change and text positioning and kerning.
 

cadmeed

Newbie
Jan 2, 2023
23
9
Was getting lost searching for hooks, glad I stumble upon this on googling. Thanks! Aside from Heiantei, what else did you worked on? Ever did an Autobahn game?