标题: ls11格式详解
性别:男-离线 三国在飞
(天外怪魔 分封不动)

合肥侯谏议大夫

Rank: 14Rank: 14Rank: 14Rank: 14Rank: 14
组别 翰林学士
级别 安东将军
好贴 2
功绩 668
帖子 3313
编号 1650
注册 2003-10-24
来自 江西




QUOTE:
原帖由gameplore于2005-04-14, 23:52:21发表

QUOTE:
原帖由三国在飞于2005-04-05, 18:13:18发表
[quote]原帖由gameplore于2005-04-05, 18:03:46发表
可以改的

乱码是因为解压缩之后还是BIG5,要用AppLocale启动UE32,选择繁体中文语言(BIG5),然后再打开文件解压缩后的文件,就可以看见文字了。

至于输入,随便哪一个能输入BIG5码的输入法都可以

我做不出来的,不会解压啊,更不要说解压更改后再压缩回去!你能不能帮忙做个出来呢(修改器)

原来是不会解压缩啊,其实前面的代码已经给出了。这里附上了一个简单的压缩/解压缩程序

我没有测试过,只在以前试过修改人名是可以的。完整的源代码也附上,想做完整的msg修改器的朋友可以以此为基础

程序仅仅提供压缩、解压缩功能,没有提供BIG5/GBK转码及修改功能。

使用方法:
1. 将m_msg.s9解压缩,假设解压后为m_msg_dec.s9;
2.用applocale开ultraedit32打开m_msg_dec.s9进行修改;
3.将m_msg_dec.s9压缩,假设压缩后为m_msg_enc.s9;
4.备份原来的m_msg.s9,将m_msg_enc.s9重命名为m_msg.s9,修改生效。 [/quote]
谢谢。转码的可以到别处。

我试过,只能改对应的字(两个的改两个,三个的改三个)加多个都不行,会有乱码。

比如我们自制的剧本都要加些关之类的,如果把且兰加多个关字,进入游戏后很多字看不到且乱码。


顶部
性别:未知-离线 boylinming

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 2
编号 36874
注册 2005-4-16


发表于 2005-4-16 08:52 资料 短消息 只看该作者
我是新人,前两天才知道有这个论坛,看了LS的解压缩,不知道你们如何测试出来的,我觉得GetCode函数应该改进,昨晚测到0点30分,应该快了不少,方法是利用查表代替测试Bit位。(为了能够让大家看明白意思,我没有做进一步的优化)

m_bitPos初始化为0,不是7了。

struct CompressValue
{
        union
        {
                int nValue;
                BYTE byValue[4];
        };
};

int g_CodeLen[] =
{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 10
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 11
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // 12
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // 13
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  // 14
        4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,  // 15
};

int g_nValue[] =
{
        0, 2, 6, 14, 30, 62, 126, 254
};

int g_nMask[] =
{
        1, 3, 7, 15, 31, 63, 127, 255, 511
};

unsigned int GetCode()
{
        // 得到3个字节的数据, 反序
        CompressValue data;
        data.byValue[3] = m_pSrc[m_srcPos];
        data.byValue[2] = m_pSrc[m_srcPos+1];
        data.byValue[1] = m_pSrc[m_srcPos+2];

        // 移位, 使得最高位是有效数据
        data.nValue <<= m_bitPos;

        // 查表得到有效数据里面Bit==1的个数
        int nSetBitsNum = g_CodeLen[data.byValue[3]];

        // 查表得到uCode1
        unsigned int uCode1 = g_nValue[nSetBitsNum];

        // 数据移位, 消去uCode1使用部分
        // 同时使得data.byValue[3]的Bit0就是uCode2的Bit0
        // x <<= y, 当 y < 0 时有问题, 如果直接用汇编写, 就可能不需要分之判断
        // (我的8086的汇编忘光了, 但一些DSP芯片支持这样的指令的)
        int nShiftNum = (2*(nSetBitsNum+1) - 8);
        if (nShiftNum > 0)
        {
                data.nValue <<= nShiftNum;
        }
        else
        {
                data.nValue >>= abs(nShiftNum);
        }
       
        // 通过掩码计算, 得到uCode2
        unsigned int uCode2 = (data.byValue[3] & g_nMask[nSetBitsNum+1]);

        // 计算bitPos和srcPos的改变, 并改变之
        m_srcPos += ((2*(nSetBitsNum+1)+m_bitPos) >> 3);
        m_bitPos += 2*(nSetBitsNum+1);
        m_bitPos &= 7;

        return uCode1 + uCode2;
}


顶部
性别:男-离线 van

平曲侯泸川军节度使

Rank: 13Rank: 13Rank: 13Rank: 13
柱国(正二品) 工神
组别 节度使
级别 军师将军
好贴 3
功绩 475
帖子 984
编号 25461
注册 2004-11-24


发表于 2005-4-16 19:13 资料 主页 文集 短消息 只看该作者
论坛里面的代码是直接反汇编得到的,所以只是和光荣的实际算法保持一致,而没有考虑效率的问题做进一步的优化。
欢迎提改进意见!
顶部
性别:男-离线 van

平曲侯泸川军节度使

Rank: 13Rank: 13Rank: 13Rank: 13
柱国(正二品) 工神
组别 节度使
级别 军师将军
好贴 3
功绩 475
帖子 984
编号 25461
注册 2004-11-24


发表于 2005-4-16 20:19 资料 主页 文集 短消息 只看该作者
你的算法有些问题
int nSetBitsNum = g_CodeLen[data.byValue[3]];
unsigned int uCode1 = g_nValue[nSetBitsNum];

在你的算法中nSetBitsNum可以等于8(data.byValue[3]=255),这时g_nValue就缓冲区溢出了。另外LS算法并没有限制在0~255之间,也可以是11111111110之类的
顶部
性别:未知-离线 boylinming

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 2
编号 36874
注册 2005-4-16


发表于 2005-4-18 12:36 资料 短消息 只看该作者
我开始领会错了,是会溢出。
我修改下,生成的曹操传data.e5文件和网上下载的一样。但里面有几个if语句很不爽,谁优化下,尽量不要清空计算机的流水线。修改后的程序连续的1的个数也不能太多,12个以后也可能会出问题(曹操传data文件里面包含了几部分,不知道是否也是这个原因)。那个大表格不用动,其它改动如下:
struct CompressValue
{
        union
        {
                unsigned int nValue;
                unsigned short sValue[2];
                BYTE byValue[4];
        };
};

int g_nValue[] =
{
        0, 2, 6, 14, 30, 62, 126, 254, 510, 1022, 2046, 4094, 8190, 16382
};

int g_nMask[] =
{
        1, 3, 7, 15, 31, 63, 127, 255, 511, 1023
};

unsigned int LSCompress::GetCode()
{
        // 得到4个字节的数据, 反序
        CompressValue data;
        data.byValue[3] = m_pSrc[m_srcPos];
        data.byValue[2] = m_pSrc[m_srcPos+1];
        data.byValue[1] = m_pSrc[m_srcPos+2];
        data.byValue[0] = m_pSrc[m_srcPos+3];

        data.nValue <<= m_bitPos;

        int nSetBitsNum = g_CodeLen[data.byValue[3]];
        int nSetBitsNum1 = g_CodeLen[data.byValue[2]];

        unsigned int uCode1;       
        unsigned int uCode2;

        if (nSetBitsNum >= 8)
        {
                uCode1 = g_nValue[nSetBitsNum+nSetBitsNum1];

                int nRealShiftNum = nSetBitsNum + nSetBitsNum1 + 1;
                data.nValue <<= nRealShiftNum;
                data.nValue >>= (16-nRealShiftNum);
                uCode2 = data.sValue[1];

                m_srcPos += ((2*nRealShiftNum+m_bitPos) >> 3);
                m_bitPos += 2*(nRealShiftNum);
                m_bitPos &= 7;
        }
        else
        {               
                uCode1 = g_nValue[nSetBitsNum];

                int nShiftNum = (2*(nSetBitsNum+1) - 8);
                if (nShiftNum > 0)
                {
                        data.nValue <<= nShiftNum;
                }
                else
                {
                        data.nValue >>= abs(nShiftNum);
                }
                uCode2 = (data.byValue[3] & g_nMask[nSetBitsNum+1]);

                m_srcPos += ((2*(nSetBitsNum+1)+m_bitPos) >> 3);
                m_bitPos += 2*(nSetBitsNum+1);
                m_bitPos &= 7;
        }       

        return uCode1 + uCode2;
}
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2005-4-19 08:35 资料 文集 短消息 只看该作者
我考虑过表格的问题,不过后来测试了一下速度完全可以满足需要,因此保留了那种比较直观的算法。
顶部
性别:未知-离线 gameplore

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 忠义校尉
好贴 1
功绩 7
帖子 274
编号 17912
注册 2004-9-18


发表于 2005-4-22 20:54 资料 短消息 只看该作者


QUOTE:
原帖由三国在飞于2005-04-15, 11:51:44发表
我试过,只能改对应的字(两个的改两个,三个的改三个)加多个都不行,会有乱码。

比如我们自制的剧本都要加些关之类的,如果把且兰加多个关字,进入游戏后很多字看不到且乱码。

可能是压缩的代码处理长度时有点问题,我现在没有san9游戏。

以前写那个程序就是为了该名字的,其他的没改过。可以修改一下压缩的代码
顶部
性别:男-离线 三国在飞
(天外怪魔 分封不动)

合肥侯谏议大夫

Rank: 14Rank: 14Rank: 14Rank: 14Rank: 14
组别 翰林学士
级别 安东将军
好贴 2
功绩 668
帖子 3313
编号 1650
注册 2003-10-24
来自 江西




QUOTE:
原帖由gameplore于2005-04-22, 20:54:21发表

QUOTE:
原帖由三国在飞于2005-04-15, 11:51:44发表
我试过,只能改对应的字(两个的改两个,三个的改三个)加多个都不行,会有乱码。

比如我们自制的剧本都要加些关之类的,如果把且兰加多个关字,进入游戏后很多字看不到且乱码。

可能是压缩的代码处理长度时有点问题,我现在没有san9游戏。

以前写那个程序就是为了该名字的,其他的没改过。可以修改一下压缩的代码

只是改名字,但不能乱改,比如曹操改成三个字的人名就不行(会出错),还有就是旗子也不对(还是原来的那个)
顶部
性别:未知-离线 elvis1000

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 3
编号 40220
注册 2005-6-4


发表于 2005-6-5 16:11 资料 短消息 只看该作者
有没有人会 C & Delphi的,可不可以把上面的C翻译成DELPHI,我只会DELPHI,实在看不懂!

boylinming写的好像和gameplore的不一样!

如果一次读取一个 integer (4 bytes),是不是前两个BYTE的值可以直接当作读取字典的值?还是应该要全换成二进位来分析呢?
顶部
性别:女-离线 叶落秋寒

英国公主监造使谏议大夫

Rank: 12Rank: 12Rank: 12
组别 翰林学士
级别 后将军
功绩 447
帖子 1572
编号 108
注册 2005-1-29
来自 天界




QUOTE:
原帖由elvis1000于2005-06-05, 16:11:37发表
有没有人会 C & Delphi的,可不可以把上面的C翻译成DELPHI,我只会DELPHI,实在看不懂!

boylinming写的好像和gameplore的不一样!

如果一次读取一个 integer (4 bytes),是不是前两个BYTE的值可以直接当作读取字典的值?还是应该要全换成二进位来分析呢?

你先别看他们的代码
先把分解和还原原理看懂了(必须!)
再自已动手试着写写看。
LS文件的结构
0-15 文件头16个字节
16-271 字典256个字节
N组 12字节为一组控制信息(压缩后长度,原文长度,压缩数据起始地址)
数据段
顶部
性别:未知-离线 elvis1000

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 3
编号 40220
注册 2005-6-4


发表于 2005-6-5 18:49 资料 短消息 只看该作者
三十的240x240图片的压缩档(RGBquad+Bits)也有档头吗?还是直接把资料用lz11的原理压的?
顶部
性别:未知-离线 ALCLA

Rank: 2Rank: 2
组别 百姓
级别 破贼校尉
功绩 1
帖子 92
编号 42054
注册 2005-7-1


发表于 2005-12-11 02:22 资料 短消息 只看该作者
问一下,如何反汇编直接反汇编得到光荣的算法?而且压缩算法无论是LZ77,LZ78,LZW如果不确定具体如何操做,感觉很难解压,不知道如何得到准确的算法,我好象就不敢下手修改了,这个帖子不错,但是我想知道到底如何得到算法的?
顶部
性别:未知-离线 Maxwell

代王
监管使
枢密直学士
山南西道节度使

Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27Rank: 27
柱国(正二品)
组别 诸侯
级别 征东将军
好贴 4
功绩 1845
帖子 5799
编号 622
注册 2004-7-7


发表于 2005-12-11 22:28 资料 文集 短消息 只看该作者
这个算法是van反汇编得到的。这个算法的可靠性是有保障的,不必非要搞清楚算法的名字,由于这个算法的一些特点,很难而且也不需要搞清楚压缩算法的细节。根据解压算法很容易构造一个压缩算法,即使这个算法跟光荣的算法不一致也能让解压算法正常工作。
顶部
性别:未知-离线 ALCLA

Rank: 2Rank: 2
组别 百姓
级别 破贼校尉
功绩 1
帖子 92
编号 42054
注册 2005-7-1


发表于 2005-12-12 09:25 资料 短消息 只看该作者
谢谢,van反汇编得到?我觉得算法的实现,和解开都不是难点,这个我都做过,字典在2的19还是多少次方以内都没什么问题,只是再大我电脑内存有问题不够,关键是我不知道van太守如何反汇编得到算法?恩,我去看看怎么反汇编,毕竟总不能老是=着人家把算法讲出来嘛
顶部
性别:男-离线 神源拓也
(神源拓也)

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 45
编号 211960
注册 2007-9-6


发表于 2007-9-25 18:12 资料 短消息 只看该作者 QQ
虽然有点复杂,但还是能学习的
顶部
性别:未知-离线 隋唐英雄传

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 2
编号 290577
注册 2008-8-25


发表于 2008-8-27 11:22 资料 短消息 只看该作者
好东西
顶部

正在浏览此帖的会员 - 5 人在线 - 0 位会员(0 隐身), 5 位游客




当前时区 GMT+8, 现在时间是 2024-11-20 12:24
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.014405 second(s), 8 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP