2021-3-26 23:01 /
最近有人求助搞这个引擎的《巨乳人妻女教師催眠》汉化,我当时稍微看了眼,感觉这玩意儿还是比较简单的。不过我不想参与汉化里面,姑且就写了提取工具,回封之类的就没管了(其实就是懒。
解包我用的GARbro,针对这个引擎GARbro是支持的。
然后是脚本。这个游戏的脚本有两种,一种是系统定义类脚本,一种是正式的游戏文本。两种脚本都非常简单,我先从定义类脚本说起。
这就是_system,游戏的定义脚本。不难看出,每个字符串前都有一个WORD。这个WORD是记录字符串长度的。字符串非0结尾,所以需要前面记录一个长度。提取的时候根据长度进行提取即可
然后是正式的游戏文本。
游戏第一个DWORD记录当前脚本的指令数,后面就是正文。
每条指令都是以这样的结构出现:
我分析的这个游戏脚本里面,有文本的op是:
0x00150050(标题)
0x00000000(一般文本)
0x00030000(非主人公的对话文本)
0x00020000(主人公的对话文本)
0x00060000(第一个主人公对话文本)
0x00140010(选项)
解包我用的GARbro,针对这个引擎GARbro是支持的。
然后是脚本。这个游戏的脚本有两种,一种是系统定义类脚本,一种是正式的游戏文本。两种脚本都非常简单,我先从定义类脚本说起。
这就是_system,游戏的定义脚本。不难看出,每个字符串前都有一个WORD。这个WORD是记录字符串长度的。字符串非0结尾,所以需要前面记录一个长度。提取的时候根据长度进行提取即可
for (int pos = 0; pos < FileSize;)
{
WORD CharSize = *(WORD*)(FileBuff + pos);
pos += sizeof(WORD);
WriteLine((FileBuff + pos), CharSize, fp);
pos += CharSize;
}
然后是正式的游戏文本。
游戏第一个DWORD记录当前脚本的指令数,后面就是正文。
每条指令都是以这样的结构出现:
struct code_struct {
WORD code_size;
DWORD op;
BYTE code[code_size - sizeof(DWORD)];
}
我分析的这个游戏脚本里面,有文本的op是:
0x00150050(标题)
0x00000000(一般文本)
0x00030000(非主人公的对话文本)
0x00020000(主人公的对话文本)
0x00060000(第一个主人公对话文本)
0x00140010(选项)
//if (code == 0x00150050 || code == 0x00000000 || code == 0x00030000 || code == 0x00020000 || code == 0x00060000)
if (code == 0x00150050 || (code & 0x0000FFFF) == 0)
WriteLine(text_buff, text_size, fp);
else if (code == 0x00140010)//select
{
DWORD ip = pos + 0x2; //00保留
BYTE select_count = *(BYTE*)(FileBuff + ip);
ip += 1;
char* select_buff = (char*)(FileBuff + ip);
string select = BuildSelectText(string(select_buff, text_size - 3));
cout << select << endl;
DWORD select_len = select.size();
WriteLine((BYTE*)select.c_str(), select_len, fp);
}
#1 - 2022-3-25 02:55
UG