查看: 2419|回复: 2

[胡扯] 没有任何技术含量的控制台

[复制链接]
梦石
0
星屑
9862
在线时间
580 小时
注册时间
2017-9-28
回帖
203
发表于 2019-2-3 16:43:40 | 显示全部楼层 |阅读模式

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

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

×
好久不开论坛,冒个泡

Snipaste_2019-02-03_15-52-51.png

这次【胡扯】主要有三件事:

  • 抄一个控制台,启用 ANSI 控制符(添加颜色之类的)
  • 抄一个后台运行
  • 写一个初学者都会写的轮询文件

cat_rep.7z (1.33 MB, 下载次数: 97) (文件限制 2M 还行,刚好塞一个 RGSS301.dll,双击 run.cmd 即可)

我电脑是 win10,不保证其他环境能正常运行。以下是实现细节不看也罢:



1.1 直接抄 taroxd 的简易调试控制台
1.2 启用 ANSI 控制符其实十分简单,执行下面三行 win32api 调用即可(api 的实现见 api.rb,其实就是普通的 Win32API.new(...).call)
  1. stdout = api('kernel32', 'GetStdHandle').call(-11)
  2. api('kernel32', 'GetConsoleMode').call(stdout, buf('L'))
  3. api('kernel32', 'SetConsoleMode').call(stdout, buf[0] | 4)
复制代码
如何使用 ANSI 控制符可以看这篇 wiki

2 直接抄 SixRC 的后台运行脚本
2.0.1 为了和 RGD 兼容,做如下处理(见 bgr.rb)
  1. if defined? RGD
  2.   Graphics.background_exec = true
  3. else
  4.   # 原后台运行脚本
  5. end
复制代码


3 有了上面两个东西,发现还是不能一边在控制台里打字一边运行游戏,

这是因为游戏控制台和 Game.exe 是同一个线程,同时只能有一个在运行
所以想到开两个 rgss 进程,一个是游戏本身,另一个是控制台

不同进程之间的交流有很多种方法,比如共享内存、管道、UDP、甚至 HTTP(可以利用不死鸟之翼的 AsHttp.dll)
这里用一个十分睿智的办法:游戏进程循环读取一个文件,一旦(判断文件内容)有消息传过来,就去做相应的处理并把结果保存到文件

[fold=贴在游戏里的脚本,见 main.rb]
  1. module Debug
  2.   CMDS = {}
  3.   FILE = ENV['TEMP'].tr('\\', '/') + 'RgssDebug_add8e6.i'
  4.   ELIF = FILE.sub(/\.i$/, '.o')
  5.   File.delete FILE if File.exist? FILE
  6.   def self.update
  7.     if File.exist? FILE
  8.       begin
  9.         stdout = eval(File.read(FILE), TOPLEVEL_BINDING).inspect
  10.         open(FILE, 'wb') { |f| f.write Marshal.dump [true, stdout] }
  11.       rescue => e
  12.         stderr = ["#{e.class}: #{e}"]
  13.         e.backtrace.each do |c|
  14.           break if c.start_with?(':1:')
  15.           if parts = c.match(/^(?<file>.+):(?<line>\d+):in `(?<code>.*)'$/)
  16.             next if parts[:file] == __FILE__
  17.             cd = Regexp.escape(File.join(Dir.getwd, ''))
  18.             file = parts[:file].sub(/^#{cd}/, '')
  19.             if inner = file.match(/^\{(?<rgss>\d+)\}$/)
  20.               id = inner[:rgss].to_i
  21.               file = "[#{$RGSS_SCRIPTS[id][1]}]"
  22.             end
  23.             stderr << "   #{file} #{parts[:line]}: #{parts[:code]}"
  24.           else
  25.             stderr << "   #{c}"
  26.           end
  27.         end
  28.         open(FILE, 'wb') { |f| f.write Marshal.dump [false, stderr] }
  29.       end
  30.       File.rename FILE, ELIF
  31.     end
  32.   end
  33.   class << ::Graphics
  34.     alias _rgss_debug_update update
  35.     def update
  36.       Debug.update
  37.       _rgss_debug_update
  38.     end
  39.   end
  40. end
复制代码
[/fold][fold=“控制台”里的脚本,见 console.rb]
  1. module Debug
  2.   FILE = ENV['TEMP'].tr('\\', '/') + 'RgssDebug_add8e6.o'
  3.   ELIF = FILE.sub(/\.o$/, '.i')
  4.   File.delete FILE if File.exist? FILE
  5.   def self.send line
  6.     open(FILE, 'w') { |f| f.write line }
  7.     File.rename FILE, ELIF
  8.     sleep 0.01 while File.exist? ELIF
  9.     if File.exist? FILE
  10.       ok, ret = Marshal.load IO.binread FILE
  11.       if ok
  12.         "\e[37m#{ret}\e[0m"
  13.       else
  14.         ret[0] = "\e[4m#{ret[0]}\e[0m"
  15.         "\e[97m#{ret.join("\n")}\e[0m"
  16.       end
  17.     else
  18.       "\e[92mReconnected.\e[0m"
  19.     end
  20.   end
  21. end
复制代码
[/fold]
以上就是,游戏本体里只贴一份轮询脚本,另一份工程跑一个控制台

既然是跑控制台那就不需要什么游戏框了,直接掏一个 RGSSEval 出来用(rgss.exe)就好了(见 rgss.c)。


结语:这个东西的好处大概是不需要外部再装什么 ruby 了()

以上冒泡完毕

评分

参与人数 2赞 +2 收起 理由
Mono_kyrin + 1 精品文章
VIPArcher + 1 被触瞎

查看全部评分

喵喵喵
梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

发表于 2019-2-4 05:24:28 | 显示全部楼层
console.zip (712.05 KB, 下载次数: 106)
我也写了一个!
kk.png
那个控制台是拿 c 写的
控制台和 rgss 的交流通过 NamedPipe
读指令 传指令 指令eval 传回去结果 显示结果 读指令
输入LL就是接收几行直到LL
错误了是直接p出来 然后返回 nil
就实现了这些基本的功能
不过学到了很多东西 还是挺有意思的(??)
回复

使用道具 举报

老黄鸡

梦石
4
星屑
45700
在线时间
7948 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2019-2-4 09:20:55 | 显示全部楼层
无敌的喵喵喵,令人发指
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部