Project1
标题: 怎么让游戏的字体指定放在游戏目录下的font? [打印本页]
作者: L7-wind 时间: 2017-11-24 10:36
标题: 怎么让游戏的字体指定放在游戏目录下的font?
是这样的,我用了别的字体,然后想在游戏目录下创个font文件夹放字体文件,然后指定这个文件夹的字体文件作为游戏字体,
这样就算缺字体的话,玩家也不用特地把游戏目录下的字体拉出来,放到windows的Fonts文件夹下了,
像这样,
请问能实现吗?
作者: SixRC 时间: 2017-11-24 13:49
当然啦
首先在脚本 Main 前面插入
# 加载字体 修改第二行为字体文件名
path=Dir.pwd+"/Font/晨光熹微.ttf"
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
path2="\0"*len*4
MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)
# 加载字体 修改第二行为字体文件名
path=Dir.pwd+"/Font/晨光熹微.ttf"
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
path2="\0"*len*4
MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)
记得按说明修改字体文件名字
然后把 Main 的第11行
Font.default_name = (["黑体"])
的黑体改成你的字体名字
就可以了
注意字体的文件名和字体名不一样
有问题请提
作者: fux2 时间: 2017-11-24 14:35
我觉得可能这样不行,曾经有人研究过这个问题,好像必须在
RGSSInitialize前加载字体文件才行。
作者: guoxiaomi 时间: 2017-11-24 16:15
我的做法是调用addfont的api之后,重启game.exe
作者: SixRC 时间: 2017-11-24 19:42
本帖最后由 SixRC 于 2018-2-24 15:51 编辑
完成了
老样子 Main 前插入 最好插在最前面 改一下脚本里的字体等信息 Main里改字体就可以了
update 2018.2.24
更新了窗口句柄获取的方式 从内存RGSS储存的地方拿
避免取错句柄的bug 不过还是要重载 没想到好办法 修炼不够
# 请自行修改第 2、3、4 行 以及 Main 中的字体名字
font_file="/Font/美玉体.ttf"
font_name="美玉体"
dll_name="RGSS103J"
unless Font.exist?(font_name)
DLL=Win32API.new('kernel32','GetModuleHandle','p','l').call(dll_name)
code = [139,68,36,4,139,128,196,182,18,0,139,64,8,194,16,0].pack('C*')
hwnd = Win32API.new('user32.dll','CallWindowProc','pllll','l').call(code,DLL,0,0,0)
Win32API.new('kernel32','WriteProcessMemory','llpll','l').call(-1,DLL+0xAC25,"\x90"*5,5,0)
RGSSGameMain=Win32API.new(dll_name,'RGSSGameMain','lpp','l')
path=Dir.pwd+font_file
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
path2="\0"*len*4
MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)
RGSSGameMain.call(hwnd,"Data/Scripts.rxdata","")
end
# 请自行修改第 2、3、4 行 以及 Main 中的字体名字
font_file="/Font/美玉体.ttf"
font_name="美玉体"
dll_name="RGSS103J"
unless Font.exist?(font_name)
DLL=Win32API.new('kernel32','GetModuleHandle','p','l').call(dll_name)
code = [139,68,36,4,139,128,196,182,18,0,139,64,8,194,16,0].pack('C*')
hwnd = Win32API.new('user32.dll','CallWindowProc','pllll','l').call(code,DLL,0,0,0)
Win32API.new('kernel32','WriteProcessMemory','llpll','l').call(-1,DLL+0xAC25,"\x90"*5,5,0)
RGSSGameMain=Win32API.new(dll_name,'RGSSGameMain','lpp','l')
path=Dir.pwd+font_file
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
path2="\0"*len*4
MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)
RGSSGameMain.call(hwnd,"Data/Scripts.rxdata","")
end
然后一些闲话
确实 AddFontResource 后不能直接读取字体 得下一次运行 exe 才行
是因为 RGSS 在开始的时候载入了字体列表 (EnumFontFamiliesEx)
这个东西不会在之后刷新 他觉得有就是有没有就是没有除非重载 RGSS
那就重载 RGSS 嘛!
不过直接重载的话 会多一个控制线程
一个副作用就是 10s hangup 变成了 5s 因为两个控制线程一起计数
所以重载前把创建线程的函数 nop 掉
大概 就没什么问题了?
而重载的时候 RGSSGameMain 的一个参数是加密档案地址
不过因为第一次载入的时候进行了处理 所以重载的时候直接传入空字符就可以
RMVA @Lemax
虽然载入字体资源后 Font.exist?(xxx) 总是显示 false
但实际上显示的时候是正确载入的 所以单纯载入即可
倒是 1.9 版本的 ruby 的 Dir.pwd 的编码很.. 不能直接转成 utf-8 转了也不正确..
代码
因为我下的是日文版..我不清楚有什么细节不同
可能要在 Main 里面修改默认字体
# 请自行修改 2、3 行
font_file="/Font/美玉体.ttf"
font_name="美玉体"
unless Font.exist?(font_name)
GetCurrentDirectory=Win32API.new('kernel32','GetCurrentDirectoryW','lp','l')
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=GetCurrentDirectory.call(0,"")
buf="\0"*(len-1)*2
GetCurrentDirectory.call(len,buf)
len=MultiByteToWideChar.call(0xFDE9,0,font_file,-1,0,0)
fa="\0"*len*2
MultiByteToWideChar.call(0xFDE9,0,font_file,-1,fa,len)
path=buf+fa
Win32API.new('gdi32','AddFontResourceW','p','l').call(path)
end
Font.default_name=font_name
# 请自行修改 2、3 行
font_file="/Font/美玉体.ttf"
font_name="美玉体"
unless Font.exist?(font_name)
GetCurrentDirectory=Win32API.new('kernel32','GetCurrentDirectoryW','lp','l')
MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
len=GetCurrentDirectory.call(0,"")
buf="\0"*(len-1)*2
GetCurrentDirectory.call(len,buf)
len=MultiByteToWideChar.call(0xFDE9,0,font_file,-1,0,0)
fa="\0"*len*2
MultiByteToWideChar.call(0xFDE9,0,font_file,-1,fa,len)
path=buf+fa
Win32API.new('gdi32','AddFontResourceW','p','l').call(path)
end
Font.default_name=font_name
作者: guoxiaomi 时间: 2017-11-28 16:29
SixRC 发表于 2017-11-24 19:42
完成了
老样子 Main 前插入 最好插在最前面 改一下脚本里的字体等信息 Main里改字体就可以了
# 请自行修改 ...
感觉,在rgssmain调用后,再运行一遍移除字体的操作更合适?
作者: SixRC 时间: 2019-4-9 23:01
以前的坑 我填一填
之前不知道怎么不重载RGSS加载字体
现在可以了 其实也 蛮好做的 就是我懒
我好像每次一犯懒就说积累不够...(还是真是积累不够???)
言归正传
RGSS 在开始的时候调用了 EnumFontFamiliesEx (我那时候大概是看这个函数解释一大堆就 怕了怕了)
然后它储存了所有字体名字和一些信息
只要依样再调用一次这个函数就行了
过程就是一堆查api 找关键地址
好了好了就这样
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |