赞 | 86 |
VIP | 0 |
好人卡 | 1 |
积分 | 136 |
经验 | 14048 |
最后登录 | 2021-1-24 |
在线时间 | 2753 小时 |
Lv4.逐梦者
- 梦石
- 0
- 星屑
- 13562
- 在线时间
- 2753 小时
- 注册时间
- 2014-10-4
- 帖子
- 756
|
本帖最后由 SixRC 于 2019-5-4 22:57 编辑
做了一个大概
我做了一个接口 就是在显示画面前会调用一个ruby方法 这个方法自己定义(注意 这个方法中不能用 Graphics.update 因为死循环了 也不能用 p 因为它也会调用渲染那段导致死循环 用 messagebox 代替)
然后提供了将被显示的位图数据地址 这时候可以用c写个dll处理画面(效率高 用ruby也不是不可以) ruby传入必要信息
因为一个原因 请用我提供的 RGSS103J.dll (具体原因是原生的渲染是一段一段的 (640*8) 导致没法整体一次性修改)
假如目标分辨率不是原生的我再改下 因为动态改这个比较麻烦 就直接改dll了
然后这是ruby里的代码
module Graphics module_function CCBBSS_DLL = Win32API.new('kernel32','GetModuleHandleA','p','l').call('RGSS103J') CCBBSS_WPMLP = Win32API.new('kernel32','WriteProcessMemory','llpll','l') CCBBSS_WPMPL = Win32API.new('kernel32','WriteProcessMemory','lplll','l') temp = "\0"*4 CCBBSS_WPMPL.call(-1, temp, CCBBSS_DLL + 0x12B6C4, 4, 0) CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x134, 4, 0) CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0xB4, 4, 0) CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x10, 4, 0) CCBBSS_BITMAP = temp.unpack("l")[0] CCBBSS_RUBY_CODE = "Graphics.ccbbss_update" CCBBSS_CODE = [0x8B, 0x54,0x24, 0x10, 0x60, 0x68, CCBBSS_RUBY_CODE, 0xB8, CCBBSS_DLL + 0x31D70, 0xFF, 0xD0, 0x83, 0xC4, 0x04, 0x61, 0x68, 0xCC0020, 0x6A, 0x00, 0x6A, 0x00, 0x57, 0xBF, CCBBSS_DLL + 0x884CD, 0xFF, 0xE7].pack("C6pClC7lC6lC2") cc = [0xBA, CCBBSS_CODE, 0xFF, 0xE2].pack("CpC2") CCBBSS_WPMLP.call(-1, CCBBSS_DLL + 0x884C3, cc, 7, 0) CCBBSS_FUNC = Win32API.new("c/ccbbss","ccbbss_test2","lllll","v") def ccbbss_update unless $game_player return end CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80) end end
module Graphics
module_function
CCBBSS_DLL = Win32API.new('kernel32','GetModuleHandleA','p','l').call('RGSS103J')
CCBBSS_WPMLP = Win32API.new('kernel32','WriteProcessMemory','llpll','l')
CCBBSS_WPMPL = Win32API.new('kernel32','WriteProcessMemory','lplll','l')
temp = "\0"*4
CCBBSS_WPMPL.call(-1, temp, CCBBSS_DLL + 0x12B6C4, 4, 0)
CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x134, 4, 0)
CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0xB4, 4, 0)
CCBBSS_WPMPL.call(-1, temp, temp.unpack("l")[0] + 0x10, 4, 0)
CCBBSS_BITMAP = temp.unpack("l")[0]
CCBBSS_RUBY_CODE = "Graphics.ccbbss_update"
CCBBSS_CODE = [0x8B, 0x54,0x24, 0x10,
0x60, 0x68, CCBBSS_RUBY_CODE,
0xB8, CCBBSS_DLL + 0x31D70,
0xFF, 0xD0,
0x83, 0xC4, 0x04, 0x61,
0x68, 0xCC0020,
0x6A, 0x00, 0x6A, 0x00, 0x57,
0xBF, CCBBSS_DLL + 0x884CD,
0xFF, 0xE7].pack("C6pClC7lC6lC2")
cc = [0xBA, CCBBSS_CODE, 0xFF, 0xE2].pack("CpC2")
CCBBSS_WPMLP.call(-1, CCBBSS_DLL + 0x884C3, cc, 7, 0)
CCBBSS_FUNC = Win32API.new("c/ccbbss","ccbbss_test2","lllll","v")
def ccbbss_update
unless $game_player
return
end
CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80)
end
end
CCBBSS_RUBY_CODE 是会被执行的代码 这里指向了 Graphics.ccbbss_update
CCBBSS_BITMAP 保存了位图数据的地址 等下再说
然后我写了个dll来处理位图
void ccbbss_test2(unsigned char *bits, int ox, int oy, int r1, int r2){ // r1 != r2 !!! if(r1 == r2) return; int gray, xx, yy, xy, r3; int r12 = r1*r1; int r22 = r2*r2; int r21 = r2 - r1; for(int height = 479; height > -1;height--){ for(int width = 0; width < 640; width++){ xx = width - ox; yy = height - oy; xy = xx*xx + yy*yy; if(xy < r12){ // nothing }else if( xy > r22){ gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20; bits[0] = bits[1] = bits[2] = gray; }else{ r3 = (int)(sqrt((double)xy) + 0.5); xx = r3 - r1; yy = r2 - r3; gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20; bits[0] = (bits[0] * yy + gray * xx) / r21; bits[1] = (bits[1] * yy + gray * xx) / r21; bits[2] = (bits[2] * yy + gray * xx) / r21; } bits += 4; } } }
void ccbbss_test2(unsigned char *bits, int ox, int oy, int r1, int r2){
// r1 != r2 !!!
if(r1 == r2)
return;
int gray, xx, yy, xy, r3;
int r12 = r1*r1;
int r22 = r2*r2;
int r21 = r2 - r1;
for(int height = 479; height > -1;height--){
for(int width = 0; width < 640; width++){
xx = width - ox;
yy = height - oy;
xy = xx*xx + yy*yy;
if(xy < r12){
// nothing
}else if( xy > r22){
gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
bits[0] = bits[1] = bits[2] = gray;
}else{
r3 = (int)(sqrt((double)xy) + 0.5);
xx = r3 - r1;
yy = r2 - r3;
gray = (bits[2]*313524 + bits[1]*615514 + bits[0]*119538) >> 20;
bits[0] = (bits[0] * yy + gray * xx) / r21;
bits[1] = (bits[1] * yy + gray * xx) / r21;
bits[2] = (bits[2] * yy + gray * xx) / r21;
}
bits += 4;
}
}
}
同时 ruby 端的调用它 CCBBSS_FUNC.call(CCBBSS_BITMAP, $game_player.x * 32 + 16, $game_player.y * 32 + 16, 50, 80)
第一个参数是位图数据地址 保存形式是 bgra 从最后一行开始储存 也就是 第一个四字节数据是位于 x=0 y=479 的像素点 然后 x=1 ... ---> x=639 y=0
第二个第三个参数是渐变中心
然后两个是渐变半径 以内不变 以外全灰 中间折中
具体见代码
效果如下
范例
ccbbss.zip
(706.38 KB, 下载次数: 135)
走起路来灰圈圈动的不协调是因为角色坐标的更新没那么平滑
然后 上面的是例子 不是最终
因为我不太熟悉原生的脚本 没法写的很详细 连这个角色坐标转实际坐标都是现场瞎蒙的...
这个可能要麻烦别人写判断了 比方什么时候启用效果 什么时候关闭 打开菜单的时候关闭 等等等等
我会根据需要修改背后的东西 也可以写写dll啥的(现查现写)
有什么问题都可以问我
(先去睡觉了 明天早课 还一堆考试) |
评分
-
查看全部评分
|