Project1

标题: 怎么让游戏的字体指定放在游戏目录下的font? [打印本页]

作者: L7-wind    时间: 2017-11-24 10:36
标题: 怎么让游戏的字体指定放在游戏目录下的font?
是这样的,我用了别的字体,然后想在游戏目录下创个font文件夹放字体文件,然后指定这个文件夹的字体文件作为游戏字体,

这样就算缺字体的话,玩家也不用特地把游戏目录下的字体拉出来,放到windows的Fonts文件夹下了,
像这样,

请问能实现吗?


作者: SixRC    时间: 2017-11-24 13:49
当然啦
首先在脚本 Main 前面插入
RUBY 代码复制
  1. # 加载字体 修改第二行为字体文件名
  2. path=Dir.pwd+"/Font/晨光熹微.ttf"
  3. MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
  4. len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
  5. path2="\0"*len*4
  6. MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
  7. Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)

记得按说明修改字体文件名字

然后把 Main 的第11行
Font.default_name = (["黑体"])
的黑体改成你的字体名字
就可以了
注意字体的文件名和字体名不一样

有问题请提

作者: fux2    时间: 2017-11-24 14:35
SixRC 发表于 2017-11-24 13:49
当然啦
首先在脚本 Main 前面插入
# 加载字体 修改第二行为字体文件名

我觉得可能这样不行,曾经有人研究过这个问题,好像必须在
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 不过还是要重载 没想到好办法 修炼不够
RUBY 代码复制
  1. # 请自行修改第 2、3、4 行 以及 Main 中的字体名字
  2. font_file="/Font/美玉体.ttf"
  3. font_name="美玉体"
  4. dll_name="RGSS103J"
  5. unless Font.exist?(font_name)
  6.   DLL=Win32API.new('kernel32','GetModuleHandle','p','l').call(dll_name)
  7.   code = [139,68,36,4,139,128,196,182,18,0,139,64,8,194,16,0].pack('C*')
  8.   hwnd = Win32API.new('user32.dll','CallWindowProc','pllll','l').call(code,DLL,0,0,0)
  9.   Win32API.new('kernel32','WriteProcessMemory','llpll','l').call(-1,DLL+0xAC25,"\x90"*5,5,0)
  10.   RGSSGameMain=Win32API.new(dll_name,'RGSSGameMain','lpp','l')
  11.   path=Dir.pwd+font_file
  12.   MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
  13.   len=MultiByteToWideChar.call(0xFDE9,0,path,-1,0,0)
  14.   path2="\0"*len*4
  15.   MultiByteToWideChar.call(0xFDE9,0,path,-1,path2,len)
  16.   Win32API.new('gdi32','AddFontResourceW','p','l').call(path2)
  17.   RGSSGameMain.call(hwnd,"Data/Scripts.rxdata","")
  18. 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 里面修改默认字体
RUBY 代码复制
  1. # 请自行修改 2、3 行
  2. font_file="/Font/美玉体.ttf"
  3. font_name="美玉体"
  4. unless Font.exist?(font_name)
  5.   GetCurrentDirectory=Win32API.new('kernel32','GetCurrentDirectoryW','lp','l')
  6.   MultiByteToWideChar=Win32API.new('kernel32','MultiByteToWideChar','llplpl','l')
  7.   len=GetCurrentDirectory.call(0,"")
  8.   buf="\0"*(len-1)*2
  9.   GetCurrentDirectory.call(len,buf)
  10.   len=MultiByteToWideChar.call(0xFDE9,0,font_file,-1,0,0)
  11.   fa="\0"*len*2
  12.   MultiByteToWideChar.call(0xFDE9,0,font_file,-1,fa,len)
  13.   path=buf+fa
  14.   Win32API.new('gdi32','AddFontResourceW','p','l').call(path)
  15. end
  16. 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