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

Project1

 找回密码
 注册会员
搜索
楼主: 柳之一
打印 上一主题 下一主题

[原创发布] 快速存储Bitmap的Marshal(高难度API,不解释)

 关闭 [复制链接]
头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

31
发表于 2008-8-6 18:48:02 | 只看该作者
以下引用沉影不器于2008-8-4 17:16:44的发言:

想求教楼主这儿:
class Font
def marshal_dump;end
def marshal_load(obj);end
end

建个空函数目的是?

这份量的脚本,对很多内部类的了解不敢说透彻,也有五六成...
像我问楼主的这个...虽然位图和字体的关系我也猜出一些来,毕竟没有您那么强大,您既然写得这脚本,可否共享一点点这些内部类
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1624
在线时间
1609 小时
注册时间
2007-8-28
帖子
3253

第3届短篇游戏大赛主流游戏组冠军第1届Title华丽大赛新人奖

32
 楼主| 发表于 2008-8-6 20:55:41 | 只看该作者
我晕,你的短信竟然没有开{/gg}
参见ruby资源的rb_obj_id,还有DATA_PTR

我的ruby删了,不好意思麻烦您自己下吧。
里面有关于操作内存和Font的marshal
“我推荐你一个游戏吧,avg的,剧情特感人”
“我擦,都是文字图片的游戏有啥好玩的,连个战斗都没有!”
“我推荐你一个游戏吧,rpg的,战斗也新颖”
“我擦,怎么米有作i弊器?“
”你不是喜欢战斗么?”
“不,我是剧情党!!”

继续阅读请点击
http://rpg.blue/blog-53316-10027.html
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

33
发表于 2008-8-9 04:16:31 | 只看该作者
需要安装ruby么,要这么麻烦么...楼主给大概解释下不就好了{/fd}
签名被屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
50
在线时间
0 小时
注册时间
2008-7-20
帖子
20
34
发表于 2008-8-9 19:59:16 | 只看该作者
既然能用获得内存地址和长度的方式保存Bitmap对象,不知道这方法能否用于所有Object呢?:D
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

35
发表于 2008-8-9 20:09:57 | 只看该作者
我一直很好奇  
我觉得  最关键是lz最早是怎么得到bitmap的图像数据是保存在Bitmap实例内存首地址偏移这么多的量之后的内存地址中的
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1624
在线时间
1609 小时
注册时间
2007-8-28
帖子
3253

第3届短篇游戏大赛主流游戏组冠军第1届Title华丽大赛新人奖

36
 楼主| 发表于 2008-8-9 20:17:52 | 只看该作者
以下引用link006007于2008-8-9 12:09:57的发言:

我一直很好奇  
我觉得  最关键是lz最早是怎么得到bitmap的图像数据是保存在Bitmap实例内存首地址偏移这么多的量之后的内存地址中的


日本的一个程序员告诉我的
“我推荐你一个游戏吧,avg的,剧情特感人”
“我擦,都是文字图片的游戏有啥好玩的,连个战斗都没有!”
“我推荐你一个游戏吧,rpg的,战斗也新颖”
“我擦,怎么米有作i弊器?“
”你不是喜欢战斗么?”
“不,我是剧情党!!”

继续阅读请点击
http://rpg.blue/blog-53316-10027.html
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

37
发表于 2008-8-9 20:25:15 | 只看该作者
{/ll}  你不会是那个程序员吧~~~
哎  劫狱去...{/hx}
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

粉蜘蛛秀秀

梦石
0
星屑
76
在线时间
39 小时
注册时间
2007-6-4
帖子
384

贵宾第1届Title华丽大赛新人奖

38
发表于 2008-8-10 00:21:53 | 只看该作者
这个帖子这么受人关注了
先不管柳之一这些内部方法怎么得到的
柳之一不解释。。。。
。。。我来解释下这个强贴吧
我到后面也有些疑问,麻烦柳之一解释下吧
如有分析的不对的地方,请指正{/hx}
[quote]
RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
一个是 传送字符串到内存 参数1:字符串 参数2:地址 参数3:长度
另一个 传送整型到内存   参数1:整型   参数2:地址 参数3:长度

def _dump(limit)
data = "rgba" * width * height
RtlMoveMemory_pi.call(data, address, data.length)
[width, height, Zlib::Deflate.deflate(data)].pack("LLa*") # 压缩
end

这个方法是开辟临时内存空间的
"rgba"看作是4个字节
data = "rgba" * width * height
像素的集合块(其实是开辟内存空间,并没有实质内容,就是字符串"rgba"的循环)

RtlMoveMemory_pi.call(data, address, data.length)
把像素集合块存储到内存地址
记得这个定义的时候是传送字符串么 就是把"rgba"的字符串循环存入
实际已经占用了内存
参数指定了数据块,要传送的地址,数据块长度

[width, height, Zlib::Deflate.deflate(data)].pack("LLa*")
这个是把宽度,高度,数据组成的数祖转换成2进制形式字符串组
这里转换3个数据
第一和第二个是把bitmap的 宽度,高度打成长型(一个字节用C,超过一个字节用I或者L)
第三个a*是先把数据块所有字符串用Zlib压缩成压缩数据 然后打包成ASCII形式
不过这个不知道这么做有啥用。。
纯粹打包下成字符串 也没有带入变量
请柳之一解释。。

def self._load(str)
w, h, zdata = str.unpack("LLa*"); b = new(w, h)
RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); b
end

这个是定义从内存读取像素点阵块

w, h, zdata = str.unpack("LLa*");
记得之前的方法最后已经把数据打包成的字符串组么
这个就是把字符串组里面的数据打包还原成数组
感觉和之前那个没有带入变量的字符串组有点联系{/gg}
并且分别传给变量w,h,zdata(还未Inflate)

b = new(w, h)
生成bitmap对象 带入b

RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); b
把Inflate后的zdata数据 存入对象偏移后的地址(这个稍后解释)
这个api定义的时候是i型的 因为存入的是实际rgba像素值和透明度值了
并不是之前那个定义为p的"rgba"临时字符串组 这些小细节不知道大家注意了没有{/wx}

def address
buffer, ad = "xxxx", object_id * 2 + 16
RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 8
RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 16
RtlMoveMemory_pi.call(buffer, ad, 4); return buffer.unpack("L")[0]
end

这个adress方法就是定义要存入的地址
返回的是一个地址
buffer, ad = "xxxx", object_id * 2 + 16
buffer = "xxxx"  定义字符串"xxxx"
ad = object_id * 2 + 16   定义初始化内存偏址
object_id是 是这个bitmap对象的内部分配的id
根据ad = object_id * 2 + 16 判断
这个object_id 和对象存放数据的地址有关

RtlMoveMemory_pi.call(buffer, ad, 4)
把字符串"xxxx"存入初始化内存 地址为:object_id * 2 + 16

ad = object_id * 2 + 16
ad = buffer.unpack("L")[0] + 8
ad = buffer.unpack("L")[0] + 16

这三个地址分别 存入4个字节 也就是 "xxxx"

概括就是 存入四个字节"xxxx" 偏移4个字节
再存入四个字节"xxxx" 偏移12个字节
再存入四个字节"xxxx"
不知道有什么用....{/gg}

最后返回的是
return buffer.unpack("L")[0]
应该是实际数据要存入的内存地址

解释完毕....

我也补充下疑问...
return buffer.unpack("L")[0]
应该是实际存放地址开始部分
但是之前的注释
# [[[bitmap.object_id * 2 + 16] + 8] + 16] == 数据的开头
应该是相等的地址。。。。
但怎么想也联系不到一起。。。{/gg}
其实也就是object_id 和 buffer.unpack("L")[0] 的关系
麻烦柳之一解释下。。。{/wx}


http://rpg.blue/upload_program/files/hide_xiu_96911465.png
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

39
发表于 2008-8-10 04:02:37 | 只看该作者
ls...  写了这么长... 没说到我想要的{/dk}
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

40
发表于 2008-8-10 06:26:18 | 只看该作者
以下引用link006007于2008-8-9 12:09:57的发言:

我一直很好奇  
我觉得  最关键是lz最早是怎么得到bitmap的图像数据是保存在Bitmap实例内存首地址偏移这么多的量之后的内存地址中的

object_id * 2 + 16<---这个楼主很早就说明了在ruby资源文件里头说的
这脚本的伟大还在于真的需要了解到很多内部类的构成啊啊啊...
签名被屏蔽
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-20 05:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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