设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2973|回复: 13
打印 上一主题 下一主题

[讨论] RGSS的C/asm扩展

[复制链接]

Lv4.逐梦者

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

跳转到指定楼层
1
发表于 2017-12-2 03:06:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 SixRC 于 2017-12-2 14:46 编辑

本来晚饭时候突然想到上次那个字体加载问题的一个解 就是新写一个dll 然后这个dll先加载一下字体 再去调用RGSS
然后突然又想到  @guoxiaomi  的 RGSS的C/C++扩展
老实说 那个时候我没怎么看懂 基于种种奇怪的原因
但今天我好好的学习理解了 这门有趣的技艺
有一些感想收获 就发个帖子吧..不过我不知道取什么标题好..就照抄了 然后因为比起这两个我更不懂 c++ ..大概 就这样

最开始的时候没懂 感觉部分原因是没看 ruby 的源码吧
代码里好多宏定义都不太明白不想看 然后今天下了 ruby 1.8.1 的源码 参考下进展比较顺利

ruby 是拿 C 写的
而拓展的基本思路就是用 ruby 源码里的一些基本函数比方 rb_define_module(name) 去以 C 的方式定义 ruby 里的模块啊类啊方法啊等等 然后再在 ruby 里用
而这些基本函数封装在 RGSSxxx dll 里面 需要逆向获取地址
就目前看来 我感觉 dll 的部分源码应该是直接复制了 ruby 的源码 因为那些编译好的函数地址的顺序和 ruby 源码里的定义顺序一样
不过我总共也没跟几个地址 只是凭感觉 ..
然后接着说拓展 按拓展的时间顺序分 应该有两种
一种是在 RGSS 载入后再加载自己写的dll 可以用来进行功能拓展
另一种是在 RGSS 载入前魔改或者替换基本函数或 dll 定义的函数等等
比方 修改 rb_define_module(name) 函数
传入参数是 name 是字符串 你把它改成先对 name 进行处理 比方 a->b b->c ... z->a 再跳回正常的模块定义
然后 脚本编辑器里写的明明是 module ABC
调用的时候却是 BCD
关于这个 用 C 定义和用 ruby 定义似乎处理方式不同..
当然 在 RGSS 载入前也可以进行一些加载字体改分辨率等的事项而不再需要重载RGSS

嗯 确实是很有趣的新思想新方式啊!暂时不知道说啥了
最后是自己写的很简陋的随机数函数 新想法暂未付诸实践
C 代码复制
  1. static char ra[]={0x0F,0xC7,0xF8,       // rdseed eax
  2.                   0xD1,0xE0,            // shl eax,1
  3.                   0x83,0xC8,0x01,       // or eax,1
  4.                   0xC3};                // ret
  5. static int (*rarand)() = (int(*)())ra;
  6. static void (*rb_define_global_function)(char*,int(*)(),int);
  7. int init(void* hmodule){
  8.     rb_define_global_function = (void (*)(char*,int(*)(),int))(hmodule+0x20BB0);
  9.     rb_define_global_function("rarand",rarand,0);
  10.     return 0;
  11. }

拓展范例.zip (630.88 KB, 下载次数: 95)


评分

参与人数 1星屑 +80 收起 理由
fux2 + 80 精品文章

查看全部评分

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42339
在线时间
7598 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

2
发表于 2017-12-2 09:00:00 | 只看该作者
的确是已经有搭好的RGSSRuntime,不过ruby函数的地址都是用的RGSS301.dll里面的233,
项目并没有公开,我就不乱发了。

点评

放在那里也不敢乱改吧···软件自己有时候也可能会出很迷的错误提示(虽然可能没有实际影响)  发表于 2017-12-12 13:33
所以为什么都不来写js呢,明明源码都放在哪里了【逃  发表于 2017-12-2 13:34
替换翻新原有的功能估计非常难,工作量也不小。但是新增功能倒是十分简单。  发表于 2017-12-2 12:54
不过新方法新库确实是可以装的 趣味无穷  发表于 2017-12-2 11:00
呃 或许不行 解释逻辑不知道能不能改  发表于 2017-12-2 10:54
RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23994
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

3
发表于 2017-12-2 20:58:03 | 只看该作者
虽然@了我,但是我只能表示心理上的支持(ง •̀_•́)ง
顺便说一下要是能像后面的版本里一样,自然的扩展分辨率就好了……

点评

原来后面的也不行啊……我才知道。我注意到论坛上的两个分辨率扩展,一个是用了4个viewport来拼成超大的地图,另外一个似乎改写了tilemap类  发表于 2017-12-3 13:35
自然的扩展分辨率是指?VX和VA的resize并不能超过640×480...是单纯指这个方法的提供?不太理解  发表于 2017-12-3 02:32
嗯  发表于 2017-12-2 21:45
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

4
 楼主| 发表于 2017-12-3 17:56:21 | 只看该作者
本帖最后由 SixRC 于 2017-12-3 19:19 编辑
guoxiaomi 发表于 2017-12-2 20:58
虽然@了我,但是我只能表示心理上的支持(ง •̀_•́)ง
顺便说一下要是能像后面的版本里一样,自然的扩展 ...

拓展分辨率 这样?
C 代码复制
  1. /* 增加 Graphics.resize_screen(width,height) 方法
  2.    自动居中放置 支持渐变 不受 640*480 限制       */
  3. #include <windows.h>
  4. /* rb_define_module_function、Bitmap_initialize 等地址逆向得到
  5.    RGSSData 是一处 RGSS 存放一些数据的地方
  6.    其下存有用来渐变的位图、窗口句柄等等数据                    */
  7. static void (*rb_define_module_function)(int,char*,int (*)(),int);
  8. // 新建 bitmap 去替换原渐变位图
  9. static int (*Bitmap_initialize)(int,int*,int*);
  10. // 两个类地址及桌面尺寸
  11. static int Graphics,Bitmap,desktoprect[4];
  12. static void** RGSSData;
  13. static int *FreezeSection,*FreezeSection2;
  14. // 窗口句柄
  15. static void* hwnd;
  16. static RECT* DesktopRect = (RECT*)desktoprect;
  17. // resize_screen 会传入 类地址 + 其他指定的参数
  18. static int resize(int graphics,int width,int height){
  19.     // 位图对象的储存方式 [flag 、类地址 、mark 、free  函数 、数据地址] 参考 ruby 源码
  20.     // 数据有三个元素 第三个是位图结构地址
  21.     // 位图结构有 0x58 大 22个元素
  22.     // FreezeSection指向的是位图结构 全复制过去就好 或复制指针 这里复制了所有的元素
  23.     // initialize 方法为可变参数 为 [argc,argv,obj]
  24.     int temp[3],size[]={width,height},new_bitmap[]={0x22,Bitmap,0,0,(int)temp};
  25.     Bitmap_initialize(2,size,new_bitmap);
  26.     // 删除旧位图 位图结构 + 2C 为位图句柄
  27.     DeleteObject((void*)FreezeSection[11]);
  28.     int *newsection = (int*)temp[2];
  29.     for(int i=0;i<22;i++){FreezeSection[i]=newsection[i];}
  30.     // 还需要修改另一块指定的渐变尺寸
  31.     FreezeSection2[4] = width;
  32.     FreezeSection2[5] = height;
  33.     FreezeSection2[50] = width;
  34.     FreezeSection2[51] = height;
  35.     // 渐变处理完毕 然后改窗口尺寸
  36.     // 因为有边框大小 调整一下 并根据桌面大小放置
  37.     // 但边框是定长的还是随不同电脑不同?是否需要获取边框尺寸?这里我懒
  38.     // ruby num 转 int
  39.     width = width >> 1;
  40.     height = height >> 1;
  41.     int x = (DesktopRect->right - width - 6)/2;
  42.     int y = (DesktopRect->bottom - height - 29)/2;
  43.     MoveWindow(hwnd,x,y,width+6,height+29,1);
  44.     // 4 为 nil
  45.     return 4;
  46. }
  47. // 初始化 传入dll名 设置变量 增加函数
  48. void Init_Graphics_Resize(char* dll){
  49.     void *hmodule = GetModuleHandle(dll);
  50.     Graphics = ((int*)(hmodule+0x12DAF4))[0];
  51.     Bitmap = ((int*)(hmodule+0x12DADC))[0];
  52.     rb_define_module_function = hmodule+0x20B80;
  53.     Bitmap_initialize = hmodule+0x50F0;
  54.     RGSSData = ((void***)(hmodule+0x12B6C4))[0];
  55.     hwnd = ((void**)RGSSData)[2];
  56.     FreezeSection = ((int**)(RGSSData+0x144/4))[0];
  57.     FreezeSection2 = ((int**)(RGSSData+0x148/4))[0];
  58.     SystemParametersInfo(48,0,DesktopRect,0);
  59.     // 设置两个参数 但是实际传入的时候多一个 类地址
  60.     rb_define_module_function(Graphics,"resize_screen",resize,2);
  61.     return;
  62. }

调用
RUBY 代码复制
  1. Win32API.new('resize','Init_Graphics_Resize','p','v').call("RGSS103J")
  2. Graphics.resize_screen(1280,720)

Resize.zip (210.14 KB, 下载次数: 92)
突然想到传入 dll 名没什么意义..因为版本间不通用......

点评

我试试看~  发表于 2017-12-3 19:56

评分

参与人数 2星屑 +88 +2 收起 理由
fux2 + 88 + 1 精品文章
guoxiaomi + 1 塞糖

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-15 00:25

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表