This commit is contained in:
恍兮惚兮 2024-12-17 01:22:33 +08:00
parent 20da2cf392
commit 7bbda900d4
9 changed files with 395 additions and 94 deletions

View File

@ -116,6 +116,10 @@ void detachall()
} }
void solvefont(HookParam hp) void solvefont(HookParam hp)
{ {
if (hp.embed_hook_font & DISABLE_FONT_SWITCH)
{
Hijack::Disable_Font_Switch = true;
}
if (hp.embed_hook_font) if (hp.embed_hook_font)
{ {
attachFunction(hp.embed_hook_font); attachFunction(hp.embed_hook_font);

View File

@ -1,65 +1,157 @@
#include"XUSE.h" #include "XUSE.h"
bool InsertXUSEHook2()
{
// 最果てのイマ -COMPLETE-
bool InsertXUSEHook2() {
//最果てのイマ -COMPLETE-
ConsoleOutput("maybe XUSE2");
BYTE bytes[] = { BYTE bytes[] = {
0x68,0x34,0x01,0x00,0x00 0x68, 0x34, 0x01, 0x00, 0x00
//v39 = v16; // v39 = v16;
//v40 = v15; <----- v15 ,eax // v40 = v15; <----- v15 ,eax
//v41 = (const char*)operator new(0x134u); // v41 = (const char*)operator new(0x134u);
}; };
auto succ=false; auto succ = false;
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress); auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress);
for (auto addr : addrs) { for (auto addr : addrs)
{
HookParam hp; HookParam hp;
hp.address = addr ; hp.address = addr;
hp.offset=regoffset(eax); hp.offset = regoffset(eax);
hp.type = CODEC_ANSI_BE|NO_CONTEXT | USING_SPLIT; hp.type = CODEC_ANSI_BE | NO_CONTEXT | USING_SPLIT;
hp.split = 0; hp.split = 0;
ConsoleOutput("XUSE2 %p", addr); succ |= NewHook(hp, "XUSE2");
succ|=NewHook(hp, "XUSE2");
} }
return succ; return succ;
} }
bool InsertXUSEHook() { bool InsertXUSEHook()
//詩乃先生の誘惑授業 {
//憂ちゃんの新妻だいあり~ // 詩乃先生の誘惑授業
ConsoleOutput("maybe XUSE"); // 憂ちゃんの新妻だいあり~
BYTE bytes[] = { BYTE bytes[] = {
0x6a,0x00, 0x6a, 0x00,
XX, XX,
0x6a,0x05, 0x6a, 0x05,
XX, XX,
XX, XX,
0xff,0x15,XX4, 0xff, 0x15, XX4,
0x8b,0xf0, 0x8b, 0xf0,
0x83,0xfe,0xff 0x83, 0xfe, 0xff
}; };
auto succ=false; auto succ = false;
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress); auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress);
for(auto addr : addrs){ for (auto addr : addrs)
{
HookParam hp; HookParam hp;
hp.address = addr + 7; hp.address = addr + 7;
hp.offset=regoffset(edi); hp.offset = regoffset(edi);
hp.type = CODEC_ANSI_BE | NO_CONTEXT | USING_SPLIT; hp.type = CODEC_ANSI_BE | NO_CONTEXT | USING_SPLIT;
hp.split = stackoffset(3); hp.split = stackoffset(3);
succ |= NewHook(hp, "XUSE");
ConsoleOutput("XUSE %p", addr);
succ|=NewHook(hp, "XUSE");
} }
return succ; return succ;
} }
bool XUSE::attach_function() { bool xuse_2(DWORD addr)
{
return InsertXUSEHook() || InsertXUSEHook2(); // 久遠の絆 -THE ORIGIN-
} // 加壳了没有导入表
auto refs = findxref_reverse_checkcallop(addr, processStartAddress, processStopAddress, 0xe8);
if (refs.size() != 2)
return false;
auto a1 = MemDbg::findEnclosingAlignedFunction(refs[0]);
auto a2 = MemDbg::findEnclosingAlignedFunction(refs[1]);
if (a1 != a2)
return false;
if (!a1)
return false;
refs = findxref_reverse_checkcallop(a1, processStartAddress, processStopAddress, 0xe8);
if (refs.size() != 3)
return false;
addr = refs[refs.size() - 1];
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset = stackoffset(8);
hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_DYNA_SJIS;
hp.embed_hook_font = F_GetGlyphOutlineA | DISABLE_FONT_SWITCH; // 修改字体会卡死
return NewHook(hp, "XUSE");
}
bool xuse_1(DWORD xaddr)
{
auto import = Util::FindImportEntry(processStartAddress, (DWORD)IsDBCSLeadByteEx);
if (!import)
return xuse_2(xaddr);
BYTE bytes[] = {
0x51, 0x68, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0x15, XX4, 0x85, 0xC0};
*(int *)(bytes + 8) = import;
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset = stackoffset(8);
hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_DYNA_SJIS;
hp.embed_hook_font = F_GetGlyphOutlineA | DISABLE_FONT_SWITCH; // 修改字体会卡死
return NewHook(hp, "XUSE");
}
bool xusex()
{
// 久遠の絆 再臨詔
/*
char __cdecl sub_5BC9C0(int a1, int a2, int a3, HDC a4, UINT a5, unsigned int a6, __int64 a7)
{
if ( a6 >= 7 )
a6 = 6;
if ( a6 >= 4 )
return sub_5BC590(a1, a2, a3, a4, a5, a6 - 3, a7);
else
return sub_5BC120(a1, a2, a3, a4, a5, a6, a7, (struct _GLYPHMETRICS *)HIDWORD(a7));
}
sub_5BC590
if ( a5 == 33167 )
{
v21 = GetGlyphOutlineW;
a5 = 10084;
GlyphOutlineW = GetGlyphOutlineW(a4, 10084, v16, (LPGLYPHMETRICS)&v24, 0, 0, (const MAT2 *)&v17);
}
else
{
v21 = GetGlyphOutlineA;
GlyphOutlineW = GetGlyphOutlineA(a4, a5, v16, (LPGLYPHMETRICS)&v24, 0, 0, (const MAT2 *)&v17);
}
*/
const BYTE bytes[] = {
0x55, 0x8b, 0xec,
0x83, 0x7d, 0x1c, 0x07,
0x72, 0x07,
0xc7, 0x45, 0x1c, 0x06, 0x00, 0x00, 0x00,
0x83, 0x7d, 0x1c, 0x04,
0x73, 0x2c,
0x8b, 0x45, 0x24,
// ……
};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
if (xuse_1(addr))
return true;
HookParam hp;
hp.address = addr;
hp.offset = stackoffset(5);
hp.type = USING_CHAR | CODEC_ANSI_BE;
return NewHook(hp, "XUSE");
}
bool XUSE::attach_function()
{
return xusex() || InsertXUSEHook() || InsertXUSEHook2();
}

View File

@ -109,16 +109,16 @@ bool InsertPPSSPPHLEHooks()
auto functions = std::vector<PPSSPPFunction>{ auto functions = std::vector<PPSSPPFunction>{
// https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceCcc.cpp // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceCcc.cpp
{"sceCccStrlenSJIS", GETARG1, USING_STRING, 0, "sceCccStrlenSJIS("}, // {"sceCccStrlenSJIS", GETARG1, USING_STRING, 0, "sceCccStrlenSJIS("},
{"sceCccStrlenUTF8", GETARG1, CODEC_UTF8 | USING_STRING, 0, "sceCccStrlenUTF8("}, // {"sceCccStrlenUTF8", GETARG1, CODEC_UTF8 | USING_STRING, 0, "sceCccStrlenUTF8("},
{"sceCccStrlenUTF16", GETARG1, CODEC_UTF16 | USING_STRING, 0, "sceCccStrlenUTF16("}, // {"sceCccStrlenUTF16", GETARG1, CODEC_UTF16 | USING_STRING, 0, "sceCccStrlenUTF16("},
{"sceCccSJIStoUTF8", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF8("}, // {"sceCccSJIStoUTF8", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF8("},
{"sceCccSJIStoUTF16", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF16("}, // {"sceCccSJIStoUTF16", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF16("},
{"sceCccUTF8toSJIS", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toSJIS("}, // {"sceCccUTF8toSJIS", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toSJIS("},
{"sceCccUTF8toUTF16", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toUTF16("}, // {"sceCccUTF8toUTF16", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toUTF16("},
{"sceCccUTF16toSJIS", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toSJIS("}, // {"sceCccUTF16toSJIS", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toSJIS("},
{"sceCccUTF16toUTF8", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toUTF8("}, // {"sceCccUTF16toUTF8", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toUTF8("},
// https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceFont.cpp // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceFont.cpp
{"sceFontGetCharInfo", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharInfo("}, {"sceFontGetCharInfo", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharInfo("},
@ -126,20 +126,15 @@ bool InsertPPSSPPHLEHooks()
{"sceFontGetCharImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharImageRect("}, {"sceFontGetCharImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharImageRect("},
{"sceFontGetShadowImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowImageRect("}, {"sceFontGetShadowImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowImageRect("},
{"sceFontGetCharGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage("}, {"sceFontGetCharGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage("},
{"sceFontGetCharGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage_Clip("}, //{"sceFontGetCharGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage_Clip("},
{"sceFontGetShadowGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage("}, {"sceFontGetShadowGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage("},
{"sceFontGetShadowGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage_Clip("}, //{"sceFontGetShadowGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage_Clip("},
// https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceKernelInterrupt.cpp // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceKernelInterrupt.cpp
{"sysclib_strcat", GETARG2, USING_STRING, 0, "Untested sysclib_strcat("}, // {"sysclib_strcat", GETARG2, USING_STRING, 0, "Untested sysclib_strcat("},
{"sysclib_strcpy", GETARG2, USING_STRING, 0, "Untested sysclib_strcpy("}, // {"sysclib_strcpy", GETARG2, USING_STRING, 0, "Untested sysclib_strcpy("},
{"sysclib_strlen", GETARG1, USING_STRING, 0, "Untested sysclib_strlen("} // {"sysclib_strlen", GETARG1, USING_STRING, 0, "Untested sysclib_strlen("}
// Disabled as I am not sure how to deal with the source string
//, { "sceCccEncodeSJIS", 2, USING_STRING, 0, "sceCccEncodeSJIS(" }
//, { "sceCccEncodeUTF8", 2, CODEC_UTF8, 0, "sceCccEncodeUTF8(" }
//, { "sceCccEncodeUTF16", 2, CODEC_UTF16, 0, "sceCccEncodeUTF16(" }
//, { "sysclib_strcmp", 2, USING_STRING, 0, "Untested sysclib_strcmp(" }
}; };
auto succ = false; auto succ = false;
for (auto &&function : functions) for (auto &&function : functions)

View File

@ -161,6 +161,19 @@ namespace ppsspp
buffer->from(s); buffer->from(s);
CharFilter(buffer, '\n'); CharFilter(buffer, '\n');
} }
void NPJH50754(TextBuffer *buffer, HookParam *hp)
{
std::string s = buffer->strA();
s = std::regex_replace(s, std::regex(R"(<R(.*?)>(.*?)</R>)"), "$2"); // {みす/御簾}
buffer->from(s);
}
void ULJM06378(TextBuffer *buffer, HookParam *hp)
{
auto ws = StringToWideString(buffer->viewA(), 932).value();
strReplace(ws, L"\\", L"");
strReplace(ws, L"$", L"");
buffer->from(WideStringToString(ws, 932));
}
void NPJH50215(TextBuffer *buffer, HookParam *hp) void NPJH50215(TextBuffer *buffer, HookParam *hp)
{ {
auto ws = StringToWideString(buffer->viewA(), 932).value(); auto ws = StringToWideString(buffer->viewA(), 932).value();
@ -187,7 +200,6 @@ namespace ppsspp
} }
buffer->from(WideStringToString(ws, 932)); buffer->from(WideStringToString(ws, 932));
} }
void ULJM06119_filter(TextBuffer *buffer, HookParam *hp) void ULJM06119_filter(TextBuffer *buffer, HookParam *hp)
{ {
std::string s = buffer->strA(); std::string s = buffer->strA();
@ -197,7 +209,6 @@ namespace ppsspp
s = std::regex_replace(s, std::regex(R"(/\n+)"), " "); s = std::regex_replace(s, std::regex(R"(/\n+)"), " ");
buffer->from(s); buffer->from(s);
} }
void ULJM06036_filter(TextBuffer *buffer, HookParam *hp) void ULJM06036_filter(TextBuffer *buffer, HookParam *hp)
{ {
std::wstring result = buffer->strW(); std::wstring result = buffer->strW();
@ -205,7 +216,6 @@ namespace ppsspp
result = std::regex_replace(result, std::wregex(LR"(<[A-Z]+>)"), L""); result = std::regex_replace(result, std::wregex(LR"(<[A-Z]+>)"), L"");
buffer->from(result); buffer->from(result);
} }
namespace Corda namespace Corda
{ {
std::string readBinaryString(uintptr_t address, bool *haveName) std::string readBinaryString(uintptr_t address, bool *haveName)
@ -324,6 +334,35 @@ namespace ppsspp
std::string s = (char *)PPSSPP::emu_arg(context)[1]; std::string s = (char *)PPSSPP::emu_arg(context)[1];
buffer->from(ULJM06143Code(s)); buffer->from(ULJM06143Code(s));
} }
void NPJH50902(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
{
auto cs = (char *)PPSSPP::emu_arg(context)[3];
while (*(WORD *)(cs - 1))
cs -= 1;
cs += 1;
std::string ws;
while (*(char *)cs)
{
std::string s = cs;
for (int i = 0; i < s.size();)
{
if ((BYTE)s[i] == 0x87)
{
if (((BYTE)s[i + 1] == 0x86) || (BYTE)s[i + 1] == 0x85)
ws += "\x81\x5b";
i += 2;
}
else
{
ws += s[i];
i += 1;
}
}
cs += s.size() + 1;
}
strReplace(ws, "\n", "");
buffer->from(ws);
}
void ULJM06220(TextBuffer *buffer, HookParam *hp) void ULJM06220(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto s = buffer->strA();
@ -369,6 +408,13 @@ namespace ppsspp
return buffer->clear(); return buffer->clear();
ULJM05943F(buffer, hp); ULJM05943F(buffer, hp);
} }
void ULJM05276(TextBuffer *buffer, HookParam *hp)
{
StringFilter(buffer, "@y", 2);
StringFilter(buffer, "@w", 2);
StringFilter(buffer, "\\c", 2);
StringFilter(buffer, "\\n", 2);
}
void ULJM06289(TextBuffer *buffer, HookParam *hp) void ULJM06289(TextBuffer *buffer, HookParam *hp)
{ {
StringFilter(buffer, "\x81\x40", 2); StringFilter(buffer, "\x81\x40", 2);
@ -629,6 +675,13 @@ namespace ppsspp
last = ws; last = ws;
buffer->from(WideStringToString(ws, 932)); buffer->from(WideStringToString(ws, 932));
} }
void ULJM06397(TextBuffer *buffer, HookParam *hp)
{
auto ws = StringToWideString(buffer->viewA(), 932).value();
ws = std::regex_replace(ws, std::wregex(LR"(<(.*?),(.*?)>)"), L"$1");
strReplace(ws, L"^", L"");
buffer->from(WideStringToString(ws, 932));
}
void ULJM06129(TextBuffer *buffer, HookParam *hp) void ULJM06129(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto s = buffer->strA();
@ -727,6 +780,11 @@ namespace ppsspp
return; return;
buffer->from(addr + 0x20, *(DWORD *)(addr + 0x14) * 2); buffer->from(addr + 0x20, *(DWORD *)(addr + 0x14) * 2);
} }
void NPJH50908(TextBuffer *buffer, HookParam *hp)
{
CharFilter(buffer, L'\n');
CharFilter(buffer, L' ');
}
void ULJM05433(TextBuffer *buffer, HookParam *hp) void ULJM05433(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto s = buffer->strA();
@ -752,6 +810,13 @@ namespace ppsspp
StringFilter(buffer, "%K", 2); StringFilter(buffer, "%K", 2);
StringFilter(buffer, "%P", 2); StringFilter(buffer, "%P", 2);
} }
void ULJM05954(TextBuffer *buffer, HookParam *hp)
{
StringFilter(buffer, "%K", 2);
StringFilter(buffer, "%N", 2);
StringFilter(buffer, "%P", 2);
StringFilter(buffer, "\x81\x40", 2);
}
void ULJM06070(TextBuffer *buffer, HookParam *hp) void ULJM06070(TextBuffer *buffer, HookParam *hp)
{ {
StringFilterBetween(buffer, "[", 1, "]", 1); StringFilterBetween(buffer, "[", 1, "]", 1);
@ -773,6 +838,25 @@ namespace ppsspp
s = std::regex_replace(s, std::regex(R"(\{(.*?)\}\[(.*?)\])"), "$1"); s = std::regex_replace(s, std::regex(R"(\{(.*?)\}\[(.*?)\])"), "$1");
buffer->from(s); buffer->from(s);
} }
void NPJH00122(TextBuffer *buffer, HookParam *hp)
{
auto s = buffer->viewA();
buffer->from(s.substr(14, s.size() - 15));
}
void ULJM05249(TextBuffer *buffer, HookParam *hp)
{
auto s = buffer->viewA();
buffer->from(s.substr(0, s.find("\x81\x75")));
}
void ULJM05203(TextBuffer *buffer, HookParam *hp)
{
CharFilter(buffer, L'\n');
static std::wstring last;
auto s = buffer->viewW();
if (s == last)
return buffer->clear();
last = s;
}
void ULJM05282(TextBuffer *buffer, HookParam *hp) void ULJM05282(TextBuffer *buffer, HookParam *hp)
{ {
static std::wstring last; static std::wstring last;
@ -810,6 +894,38 @@ namespace ppsspp
}; };
buffer->from(remap(s)); buffer->from(remap(s));
} }
void ULJM05758(TextBuffer *buffer, HookParam *hp)
{
auto s = buffer->strA();
static auto katakanaMap = std::map<std::wstring, std::wstring>{
{L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"ソ", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"", L""}, {L"?", L""}, {L"", L""}};
auto remap = [](std::string &s)
{
std::wstring result;
auto ws = StringToWideString(s, 932).value();
for (auto _c : ws)
{
std::wstring c;
c.push_back(_c);
if (katakanaMap.find(c) != katakanaMap.end())
{
result += katakanaMap[c];
}
else
result += c;
}
return WideStringToString(result, 932);
};
buffer->from(remap(s));
}
void ULJM05634(TextBuffer *buffer, HookParam *hp)
{
static std::string last;
auto s = buffer->strA();
if (s == last)
return buffer->clear();
last = s;
}
void ULJS00169(TextBuffer *buffer, HookParam *hp) void ULJS00169(TextBuffer *buffer, HookParam *hp)
{ {
CharFilter(buffer, '\n'); CharFilter(buffer, '\n');
@ -916,10 +1032,25 @@ namespace ppsspp
} }
last = s; last = s;
} }
void ULJM05741(TextBuffer *buffer, HookParam *hp)
{
auto s = buffer->viewA();
s = s.substr(0, s.size() - 2);
if (s.find('#') != s.npos)
return buffer->clear();
buffer->from(s);
}
void ULJM05109(TextBuffer *buffer, HookParam *hp)
{
StringFilter(buffer, "$$", 2);
}
void ULJM06258_2(TextBuffer *buffer, HookParam *hp) void ULJM06258_2(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto s = buffer->strA();
buffer->from(strSplit(s, "\n")[1]); auto _ = strSplit(s, "\n");
if (_.size() < 2)
return buffer->clear();
buffer->from(_[1]);
} }
void ULJM06258(TextBuffer *buffer, HookParam *hp) void ULJM06258(TextBuffer *buffer, HookParam *hp)
{ {
@ -956,7 +1087,22 @@ namespace ppsspp
} }
buffer->from(s); buffer->from(s);
} }
void ULJM06200(TextBuffer *buffer, HookParam *hp)
{
NPJH50899(buffer, hp);
auto s = buffer->strA();
s = s.substr(0, 2) + std::regex_replace(s.substr(2, s.size() - 4), std::regex(R"(\x81\x77(.*?)\x81\x78)"), "$1") + s.substr(s.size() - 2);
buffer->from(s);
}
std::unordered_map<uintptr_t, emfuncinfo> emfunctionhooks = { std::unordered_map<uintptr_t, emfuncinfo> emfunctionhooks = {
// Solomon's Ring ~地の章~ ULJM06204
// Solomon's Ring ~水の章~ ULJM06203
// Solomon's Ring ~風の章~ ULJM06202
{0x88052C0, {0, 2, 0, 0, ULJM06200, "ULJM0620[234]"}},
// Solomon's Ring ~火の章~
{0x88061B0, {0, 2, 0, 0, ULJM06200, "ULJM06200"}},
// 神なる君と
{0x888F054, {0, 0, 0, 0, ULJM06289, "ULJM05975"}},
// DEARDROPS DISTORTION // DEARDROPS DISTORTION
{0x8814110, {USING_CHAR | DATA_INDIRECT, 4, 0, 0, 0, "ULJM05819"}}, {0x8814110, {USING_CHAR | DATA_INDIRECT, 4, 0, 0, 0, "ULJM05819"}},
// 流行り神PORTABLE // 流行り神PORTABLE
@ -974,8 +1120,6 @@ namespace ppsspp
{0x8850b2c, {0, 0, 0, 0, NPJH50909_filter, "ULJM05878"}}, // onscreen toast {0x8850b2c, {0, 0, 0, 0, NPJH50909_filter, "ULJM05878"}}, // onscreen toast
// Dunamis15 // Dunamis15
{0x0891D72C, {CODEC_UTF8, 0, 0, 0, ULJM06119_filter, "ULJM06119"}}, {0x0891D72C, {CODEC_UTF8, 0, 0, 0, ULJM06119_filter, "ULJM06119"}},
// Princess Evangile
{0x88506d0, {CODEC_UTF16, 2, 0, 0, ULJM06036_filter, "ULJM06036"}}, // [0x88506d0(2)...0x088507C0(?)] // name text text (line doubled)
// 金色のコルダ3 AnotherSky feat.神南 // 金色のコルダ3 AnotherSky feat.神南
{0x883C940, {0, 0, 0, ULJM05428, 0, "NPJH50845"}}, {0x883C940, {0, 0, 0, ULJM05428, 0, "NPJH50845"}},
// 金色のコルダ3 フルボイス Special // 金色のコルダ3 フルボイス Special
@ -1007,6 +1151,8 @@ namespace ppsspp
// 神々の悪戯 InFinite // 神々の悪戯 InFinite
{0x088630f8, {0, 0, 0, QNPJH50909, 0, "NPJH50909"}}, // text, choice (debounce trailing 400ms), TODO: better hook {0x088630f8, {0, 0, 0, QNPJH50909, 0, "NPJH50909"}}, // text, choice (debounce trailing 400ms), TODO: better hook
{0x0887813c, {0, 3, 4, 0, 0, "NPJH50909"}}, // Question YN {0x0887813c, {0, 3, 4, 0, 0, "NPJH50909"}}, // Question YN
// アンジェリーク ルトゥール
{0x88A4970, {CODEC_UTF16, 1, 0, 0, NPJH50908, "NPJH50908"}},
// 月華繚乱ROMANCE // 月華繚乱ROMANCE
{0x88eeba4, {0, 0, 0, 0, ULJM05943F, "ULJM05943"}}, // a0 - monologue text {0x88eeba4, {0, 0, 0, 0, ULJM05943F, "ULJM05943"}}, // a0 - monologue text
{0x8875e0c, {0, 1, 6, 0, ULJM05943F, "ULJM05943"}}, // a1 - dialogue text {0x8875e0c, {0, 1, 6, 0, ULJM05943F, "ULJM05943"}}, // a1 - dialogue text
@ -1155,6 +1301,9 @@ namespace ppsspp
{0x881BECC, {0, 0, 0, 0, 0, "ULJM05444"}}, {0x881BECC, {0, 0, 0, 0, 0, "ULJM05444"}},
// のーふぇいと! only the power of will // のーふぇいと! only the power of will
{0x889A888, {0, 0, 0, 0, ULJM05610, "ULJM05610"}}, {0x889A888, {0, 0, 0, 0, ULJM05610, "ULJM05610"}},
// 薄桜鬼 黎明録 ポータブル
{0x88AA0FC, {0, 0, 0, 0, ULJM05943F, "ULJM05917"}},
{0x88ABC14, {0, 0, 0, 0, ULJM05823_2, "ULJM05917"}},
// 薄桜鬼 遊戯録 // 薄桜鬼 遊戯録
{0x8850720, {0, 0, 0, 0, ULJM05943F, "ULJM05663"}}, {0x8850720, {0, 0, 0, 0, ULJM05943F, "ULJM05663"}},
{0x884AB78, {0, 0, 0, 0, ULJM05823_2, "ULJM05663"}}, {0x884AB78, {0, 0, 0, 0, ULJM05823_2, "ULJM05663"}},
@ -1242,6 +1391,8 @@ namespace ppsspp
{0x88750C0, {0, 1, 0, 0, NPJH50899, "NPJH50899"}}, {0x88750C0, {0, 1, 0, 0, NPJH50899, "NPJH50899"}},
// 里見八犬伝~浜路姫之記~ // 里見八犬伝~浜路姫之記~
{0x886C750, {0, 1, 0, 0, NPJH50899, "NPJH50885"}}, {0x886C750, {0, 1, 0, 0, NPJH50899, "NPJH50885"}},
// 大正鬼譚~言ノ葉櫻~
{0x88851E8, {0, 1, 0, 0, 0, "NPJH50886"}},
// 白華の檻~緋色の欠片4~ // 白華の檻~緋色の欠片4~
{0x88FE8C0, {0, 0, 0, 0, ULJM05823_2, "ULJM06167"}}, {0x88FE8C0, {0, 0, 0, 0, ULJM05823_2, "ULJM06167"}},
{0x894672C, {0, 4, 0, 0, ULJM06167, "ULJM06167"}}, {0x894672C, {0, 4, 0, 0, ULJM06167, "ULJM06167"}},
@ -1278,6 +1429,8 @@ namespace ppsspp
{0x8812600, {0, 1, 0, 0, ULJS00124, "ULJM06359"}}, {0x8812600, {0, 1, 0, 0, ULJS00124, "ULJM06359"}},
// フォトカノ // フォトカノ
{0x88F2030, {0, 1, 0, 0, ULJS00124, "ULJS00378"}}, {0x88F2030, {0, 1, 0, 0, ULJS00124, "ULJS00378"}},
// マーメイド・ゴシック
{0x888557C, {0, 1, 0, 0, 0, "NPJH50892"}},
// your diary+ // your diary+
{0x884D740, {0, 1, 0, 0, NPJH50831, "NPJH50831"}}, {0x884D740, {0, 1, 0, 0, NPJH50831, "NPJH50831"}},
{0x8829364, {0, 1, 0, 0, NPJH50831_1, "NPJH50831"}}, {0x8829364, {0, 1, 0, 0, NPJH50831_1, "NPJH50831"}},
@ -1311,11 +1464,65 @@ namespace ppsspp
{0x882C010, {0, 4, 0, 0, ULJS00579, "ULJS00579"}}, {0x882C010, {0, 4, 0, 0, ULJS00579, "ULJS00579"}},
// リアルロデ PORTABLE // リアルロデ PORTABLE
{0x886A92C, {0, 0, 0, 0, ULJM05657, "ULJM05657"}}, {0x886A92C, {0, 0, 0, 0, ULJM05657, "ULJM05657"}},
// Princess Evangile
{0x88506d0, {CODEC_UTF16, 2, 0, 0, ULJM06036_filter, "ULJM06036"}},
// Princess Arthur // Princess Arthur
{0x8841D10, {0, 0xE, 0, 0, ULJM06258_2, "ULJM06258"}}, // name+text,显示完后 {0x8841D10, {0, 0xE, 0, 0, ULJM06258_2, "ULJM06258"}}, // name+text,显示完后
{0x88A844C, {0, 1, 0, 0, ULJM06258, "ULJM06258"}}, // text {0x88A844C, {0, 1, 0, 0, ULJM06258, "ULJM06258"}}, // text
// アルコバレーノ!ポータブル // アルコバレーノ!ポータブル
{0x88AFECC, {0, 4, 0, 0, ULJM05943F, "ULJM05609"}}, {0x88AFECC, {0, 4, 0, 0, ULJM05943F, "ULJM05609"}},
// ヒイロノカケラ 新玉依姫伝承 ポータブル
{0x883FA7C, {0, 4, 0, 0, ULJM05943F, "ULJM05741"}},
{0x8813130, {0, 0xc, 0, 0, ULJM05741, "ULJM05741"}},
// 十三支演義 ~偃月三国伝~
{0x891BC1C, {0, 0, 0, 0, ULJM06289, "ULJM06090"}},
// さくらさくら-HARU URARA-
{0x8817C98, {0, 1, 0, 0, ULJM05758, "ULJM05758"}},
// どきどきすいこでん
{0x88A8FC8, {0, 1, 0, 0, ULJS00124, "ULJS00380"}},
// Jewelic Nightmare
{0x888BF24, {0, 0, 0, 0, ULJM06289, "ULJM06326"}},
// 怪盗アプリコット ポータブル
{0x8823474, {0, 1, 0, 0, 0, "ULJM05276"}},
{0x8823DF0, {0, 1, 0, 0, ULJM05276, "ULJM05276"}},
// EtudePrologue ポータブル
{0x881D160, {0, 0, 0, 0, ULJM05276, "ULJM05252"}},
{0x8822894, {0, 0, 0, 0, ULJM05276, "ULJM05252"}},
{0x881CA64, {0, 6, 0, 0, ULJM05276, "ULJM05252"}},
// for Symphony ポータブル
{0x8821B50, {0, 1, 0, 0, ULJM05276, "ULJM05258"}},
{0x881C354, {0, 0, 0, 0, ULJM05276, "ULJM05258"}},
{0x881BC74, {0, 1, 0, 0, ULJM05276, "ULJM05258"}},
// Kanon
{0x880B6E8, {CODEC_UTF16, 0, 0, 0, ULJM05203, "ULJM05203"}},
// Little Aid ポータブル
{0x8822B6C, {0, 1, 0, 0, 0, "ULJM05249"}},
{0x8823314, {0, 1, 0, 0, ULJM05249, "ULJM05249"}},
// とびたて!超時空トラぶる花札大作戦
{0x8842E48, {0, 2, 0, 0, NPJH00122, "NPJH00122"}},
// ふしぎ遊戯 玄武開伝 外伝 鏡の巫女
{0x884FC48, {0, 0, 0, 0, ULJM05823_2, "ULJM05175"}},
{0x889B8D4, {0, 0, 0, 0, ULJM06258, "ULJM05175"}},
// サクラ大戦1&2
{0x8A7F814, {0, 6, 0, 0, ULJM05109, "ULJM05109"}}, // 其一。不支持其二
// 白銀のカルと蒼空の女王
{0x8859358, {0, 3, 0, 0, ULJM05954, "ULJM05954"}},
{0x884F338, {0, 0, 0, 0, ULJM05954, "ULJM05954"}},
// カレイドイヴ
{0x8837E98, {0, 3, 0, 0, ULJM06397, "ULJM06397"}},
// 天神乱漫 Happy Go Lucky !!
{0x885C730, {0, 0xe, 0, 0, ULJM05634, "ULJM05634"}},
// 学園K -Wonderful School Days-
{0x887F838, {0, 1, 0, 0, ULJM06378, "ULJM06378"}},
// 学☆王 -THE ROYAL SEVEN STARS- +METEOR
{0x880E458, {0, 0, 0, 0, NPJH50754, "NPJH50754"}},
// 黒雪姫~スノウ・マジック~
{0x8886480, {0, 1, 0, 0, 0, "NPJH50888"}},
// ロミオVSジュリエット
{0x887B4A4, {0, 1, 0, 0, 0, "ULJM06318"}},
// うたの☆プリンスさまっ♪All Star After Secret
{0x885F3C0, {0, 3, 0, NPJH50902, 0, "NPJH50902"}},
}; };
} }

View File

@ -37,7 +37,13 @@ DEF_FUN(WideCharToMultiByte)
#undef DEF_FUN #undef DEF_FUN
/** Helper */ /** Helper */
namespace
{
inline const wchar_t *maybe_disabled_fontFamily()
{
return Hijack::Disable_Font_Switch ? L"" : commonsharedmem->fontFamily;
}
}
namespace namespace
{ // unnamed { // unnamed
UINT8 systemCharSet() UINT8 systemCharSet()
@ -45,21 +51,14 @@ namespace
enum CodePage enum CodePage
{ {
NullCodePage = 0, NullCodePage = 0,
Utf8CodePage = 65001 // UTF-8 Utf8CodePage = 65001, // UTF-8
, Utf16CodePage = 1200, // UTF-16
Utf16CodePage = 1200 // UTF-16 SjisCodePage = 932, // SHIFT-JIS
, GbkCodePage = 936, // GB2312
SjisCodePage = 932 // SHIFT-JIS KscCodePage = 949, // EUC-KR
, Big5CodePage = 950, // BIG5
GbkCodePage = 936 // GB2312 TisCodePage = 874, // TIS-620
, Koi8CodePage = 866 // KOI8-R
KscCodePage = 949 // EUC-KR
,
Big5CodePage = 950 // BIG5
,
TisCodePage = 874 // TIS-620
,
Koi8CodePage = 866 // KOI8-R
}; };
auto systemCodePage = ::GetACP(); auto systemCodePage = ::GetACP();
switch (systemCodePage) switch (systemCodePage)
@ -131,11 +130,10 @@ namespace
{ {
customizeLogFontA((LOGFONTA *)lplf); customizeLogFontA((LOGFONTA *)lplf);
std::wstring s = commonsharedmem->fontFamily; std::wstring s = maybe_disabled_fontFamily();
if (!s.empty()) if (!s.empty())
{ {
lplf->lfFaceName[s.size()] = 0; lplf->lfFaceName[s.size()] = 0;
// s->fontFamily.toWCharArray(lplf->lfFaceName);
memcpy(lplf->lfFaceName, s.c_str(), s.size()); memcpy(lplf->lfFaceName, s.c_str(), s.size());
} }
} }
@ -217,7 +215,7 @@ namespace
} }
bool isFontCustomized() bool isFontCustomized()
{ {
return commonsharedmem->fontCharSetEnabled || wcslen(commonsharedmem->fontFamily); return commonsharedmem->fontCharSetEnabled || wcslen(maybe_disabled_fontFamily());
} }
DCFontSwitcher::DCFontSwitcher(HDC hdc) DCFontSwitcher::DCFontSwitcher(HDC hdc)
: hdc_(hdc), oldFont_(nullptr), newFont_(nullptr), newfontname(L"") : hdc_(hdc), oldFont_(nullptr), newFont_(nullptr), newfontname(L"")
@ -247,18 +245,18 @@ namespace
customizeLogFontW(&lf); customizeLogFontW(&lf);
if (std::wstring(commonsharedmem->fontFamily).empty()) if (std::wstring(maybe_disabled_fontFamily()).empty())
::GetTextFaceW(hdc_, LF_FACESIZE, lf.lfFaceName); ::GetTextFaceW(hdc_, LF_FACESIZE, lf.lfFaceName);
else else
{ {
wcscpy(lf.lfFaceName, commonsharedmem->fontFamily); wcscpy(lf.lfFaceName, maybe_disabled_fontFamily());
} }
newFont_ = fonts_.get(lf); newFont_ = fonts_.get(lf);
if ((!newFont_) || (newfontname != std::wstring(commonsharedmem->fontFamily))) if ((!newFont_) || (newfontname != std::wstring(maybe_disabled_fontFamily())))
{ {
newFont_ = Hijack::oldCreateFontIndirectW(&lf); newFont_ = Hijack::oldCreateFontIndirectW(&lf);
fonts_.add(newFont_, lf); fonts_.add(newFont_, lf);
newfontname = std::wstring(commonsharedmem->fontFamily); newfontname = std::wstring(maybe_disabled_fontFamily());
} }
oldFont_ = (HFONT)SelectObject(hdc_, newFont_); oldFont_ = (HFONT)SelectObject(hdc_, newFont_);
} }
@ -275,7 +273,7 @@ HFONT WINAPI Hijack::newCreateFontIndirectA(const LOGFONTA *lplf)
// DOUT("width:" << lplf->lfWidth << ", height:" << lplf->lfHeight << ", weight:" << lplf->lfWeight); // DOUT("width:" << lplf->lfWidth << ", height:" << lplf->lfHeight << ", weight:" << lplf->lfWeight);
// if (auto p = HijackHelper::instance()) { // if (auto p = HijackHelper::instance()) {
// auto s = p->settings(); // auto s = p->settings();
std::wstring fontFamily = commonsharedmem->fontFamily; std::wstring fontFamily = maybe_disabled_fontFamily();
if (lplf && isFontCustomized()) if (lplf && isFontCustomized())
{ {
union union
@ -340,7 +338,7 @@ HFONT WINAPI Hijack::newCreateFontA(int nHeight, int nWidth, int nEscapement, in
nHeight *= s->fontScale; nHeight *= s->fontScale;
} }
*/ */
std::wstring fontFamily = commonsharedmem->fontFamily; std::wstring fontFamily = maybe_disabled_fontFamily();
if (!fontFamily.empty()) if (!fontFamily.empty())
{ {
if (all_ascii(fontFamily.c_str(), fontFamily.size())) if (all_ascii(fontFamily.c_str(), fontFamily.size()))
@ -378,7 +376,7 @@ HFONT WINAPI Hijack::newCreateFontW(int nHeight, int nWidth, int nEscapement, in
nWidth *= s->fontScale; nWidth *= s->fontScale;
nHeight *= s->fontScale; nHeight *= s->fontScale;
}*/ }*/
if (!std::wstring(commonsharedmem->fontFamily).empty()) if (!std::wstring(maybe_disabled_fontFamily()).empty())
lpszFace = (LPCWSTR)commonsharedmem; lpszFace = (LPCWSTR)commonsharedmem;
} }
return oldCreateFontW(CREATE_FONT_ARGS); return oldCreateFontW(CREATE_FONT_ARGS);

View File

@ -2,6 +2,7 @@
namespace Hijack namespace Hijack
{ {
inline bool Disable_Font_Switch = false;
#define DEF_FUN(_fun, _return, ...) \ #define DEF_FUN(_fun, _return, ...) \
typedef _return(WINAPI *_fun##_fun_t)(__VA_ARGS__); \ typedef _return(WINAPI *_fun##_fun_t)(__VA_ARGS__); \

View File

@ -98,6 +98,7 @@ enum HookParamType : uint64_t
enum HookFontType : unsigned enum HookFontType : unsigned
{ {
DECLARE_VALUE(NOT_HOOK_FONT, 0), DECLARE_VALUE(NOT_HOOK_FONT, 0),
NEXT_MASK(DISABLE_FONT_SWITCH),
NEXT_MASK(F_CreateFontA), NEXT_MASK(F_CreateFontA),
NEXT_MASK(F_CreateFontW), NEXT_MASK(F_CreateFontW),
NEXT_MASK(F_CreateFontIndirectA), NEXT_MASK(F_CreateFontIndirectA),

View File

@ -1,6 +1,6 @@
set(VERSION_MAJOR 6) set(VERSION_MAJOR 6)
set(VERSION_MINOR 12) set(VERSION_MINOR 13)
set(VERSION_PATCH 0) set(VERSION_PATCH 0)
set(VERSION_REVISION 0) set(VERSION_REVISION 0)
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")

View File

@ -38,6 +38,9 @@ class TTSbase:
@property @property
def voice(self): def voice(self):
_v = self.privateconfig["voice"] _v = self.privateconfig["voice"]
if isinstance(self.voicelist[0], tuple):
# vits的tuple在json.load后变成list了
_v = tuple(_v)
if _v not in self.voicelist: if _v not in self.voicelist:
_v = self.voicelist[0] _v = self.voicelist[0]
return _v return _v