铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 3520|回复: 1

[lua复刻] 在Lua中实现复刻版中的Byte类库

[复制链接]
发表于 2011-12-4 00:10 | 显示全部楼层 |阅读模式
本人纯java程序员,最近看了论坛的作品后对lua非常感兴趣。因为看游泳的鱼的代码中提到“lua本身对二进制文件处理的支持不够”,又碰巧看到了lua中进行这种操作的代码,顺手kiang了过来。我本人对各位大虾非常敬仰,纯学术研究而已。实际上这是我第一段正式的lua程序,大家见笑。私下里的意思是,希望lua的代码越多越好,C的代码越少越好,因为我不会VC,至今不知道哪里能下载到VC6。

local create = Byte.create;
Byte.create = function(size)
local str = {};
str.value = string.rep(string.char(0), size);
return str;
end

local bloadfile = Byte.loadfile;
Byte.loadfile = function(b,filename,start,length)
local INF = assert(io.open(filename, "rb"));
local _;
_, b.value = INF:read(start, length);
io.close(INF);
end

local savefile = Byte.savefile;
Byte.savefile = function(b,filename,start,length)
local INF = assert(io.open(filename, "rb"));
local _previous, _, _next = INF:read(start, length, "*all");
io.close(INF);
INF = assert(io.open(filename, "wb"));
INF:write(_previous or "", b.value , string.rep(string.char(0), length - string.len(b.value)), _next or "");
io.close(INF);
end

local cache = {};
local getnum = function(b,start, size, unsign)
local str = string.sub(b.value, start + 1, start + size);
if not cache[str] then
local sum = 0
for i = size, 1, -1 do
sum = sum * 256 + string.byte(str, i)
end
-- test for negative number
if not unsign and string.byte(str, size) > 127 then
sum = sum - math.ldexp(1, 8 * size)
end
cache[str] = sum;
end
return cache[str];
end

local setnum = function(b,start,va, size, unsign)
local v = ""
local x = math.floor(va);
if unsign or x >= 0 then
for i = 1, size do
v = v..string.char(x % 256); x = math.floor(x / 256)
end
else-- x < 0
x = -x
local carry = 1
for i = 1, size do
local c = 255 - (x % 256) + carry
if c == 256 then c = 0; carry = 1 else carry = 0 end
v = v..string.char(c); x = math.floor(x / 256)
end
end
b.value = string.sub(b.value, 1, start).. v ..string.sub(b.value, start + size + 1)
end

local get16 = Byte.get16;
Byte.get16 = function(b,start)
return getnum(b,start,2);
end

local set16 = Byte.set16;
Byte.set16 = function(b,start,v)
setnum(b,start,v, 2);
end

local getu16 = Byte.getu16;
Byte.getu16 = function(b,start)
return getnum(b,start,2, true);
end

local setu16 = Byte.setu16;
Byte.setu16 = function(b,start,v)
setnum(b,start,v, 2, true);
end

local get32 = Byte.get32;
Byte.get32 = function(b,start)
return getnum(b,start,4);
end

local set32 = Byte.set32;
Byte.set32 = function(b,start,v)
setnum(b,start,v, 4);
end

local getstr = Byte.getstr;
Byte.getstr = function(b,start,length)
return string.sub(b.value,start + 1, start + length);
end

local setstr = Byte.setstr;
Byte.setstr = function(b,start,length,str)
b.value = string.sub(b.value, 1, start).. string.sub(str, 1, length) ..string.sub(b.value, start + length + 1)
end


运行方法是加到jymodify.lua的SetModify函数里,只在JY_SDL_Lua_0.6_release上测过,如果没什么变化其他版本应该也可以吧。
附件是我自己测试的小文件,可以用 "lua5.1 jyelse.lua"单独测试。
要注意的是测试的时候那个文件(名字就是"filename")得自己先建好,哪怕是空的也行。没有文件的话,lua会报错。暂时没查到lua怎么检测文件时候存在和touch文件的方法,大虾们可以给我指条明路。如果os.execute的话可以做到,但是要和系统不相关的话估计很难。


深入讨论的话,有一点是里面的getnum我加了缓存,不知道时间长了会不会内存溢出,一开始的写法如下
local getnum = function(b,start, size, unsign)
local sum = 0
for i = size, 1, -1 do
sum = sum * 256 + string.byte(b.value, start + i)
end
-- test for negative number
if not unsign and string.byte(b.value, start + size) > 127 then
sum = sum - math.ldexp(1, 8 * size)
end
return sum
end

大同小异了。

其实可以评测一下原版,lua版,不加缓存lua版的性能哪个好一些,暂时没有做。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x

评分

参与人数 1声望 +10 收起 理由
jy02785317 + 10 原创精品

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2011-12-11 00:59 | 显示全部楼层
本帖最后由 else 于 2011-12-11 01:02 编辑

深入测试了一下,包括用程序反复读取记录,存储记录,用程序遍历大地图,重复显示状态菜单和物品栏,分别记录原C版,lua版,不加缓存lua版的耗用时间。结论是,LUA版Byte类库和C版Byte类库运行时间相差无几,比如是58秒和59秒的差别。在读取进度和存取进度,也就是文件操作上面区别比较明显,Lua版要消耗C版两倍到三倍的时间。对反复读取同一个文件进一步做些优化,可以缩短到一倍半。不过这些代码无关紧要,就不贴出来了。对getnum做缓存貌似没有明显效果,可以免去这个麻烦事了,还省得担心内存的问题。

考虑到实际上,存取游戏进度的频次不会太频繁,而且时间也还是在可以接受的范围内,所以可以认为,Lua版来做Byte类库基本上对效率不会有影响。至少如果以后我自己有做Mod的计划地话,我会采用LUA版类库而让C程序瘦身。
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-5-16 16:24

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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