2004-08-21 01:25:48 +00:00
|
|
|
/*
|
|
|
|
Q3Fusion - Quake III Clone Engine
|
|
|
|
|
|
|
|
Copyright (C) 2003 Andrey Nazarov
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
//
|
|
|
|
// huff.c - Huffman compression routines for data bitstream
|
|
|
|
//
|
|
|
|
#include "quakedef.h"
|
2005-02-28 07:16:19 +00:00
|
|
|
#ifdef HUFFNETWORK
|
2004-08-21 01:25:48 +00:00
|
|
|
#define ID_INLINE
|
|
|
|
|
2013-05-11 05:03:07 +00:00
|
|
|
#define VALUE(a) (*(size_t *)&(a))
|
|
|
|
#define NODE(a) ((void*)((size_t)a))
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
#define NODE_START NODE( 1)
|
|
|
|
#define NODE_NONE NODE(256)
|
|
|
|
#define NODE_NEXT NODE(257)
|
|
|
|
|
|
|
|
#define NOT_REFERENCED 256
|
|
|
|
|
|
|
|
#define HUFF_TREE_SIZE 7175
|
|
|
|
typedef void *tree_t[HUFF_TREE_SIZE];
|
|
|
|
|
|
|
|
//
|
|
|
|
// pre-defined frequency counts for all bytes [0..255]
|
|
|
|
//
|
|
|
|
static int q3huffCounts[256] = {
|
|
|
|
0x3D1CB, 0x0A0E9, 0x01894, 0x01BC2, 0x00E92, 0x00EA6, 0x017DE, 0x05AF3,
|
|
|
|
0x08225, 0x01B26, 0x01E9E, 0x025F2, 0x02429, 0x0436B, 0x00F6D, 0x006F2,
|
|
|
|
0x02060, 0x00644, 0x00636, 0x0067F, 0x0044C, 0x004BD, 0x004D6, 0x0046E,
|
|
|
|
0x006D5, 0x00423, 0x004DE, 0x0047D, 0x004F9, 0x01186, 0x00AF5, 0x00D90,
|
|
|
|
0x0553B, 0x00487, 0x00686, 0x0042A, 0x00413, 0x003F4, 0x0041D, 0x0042E,
|
|
|
|
0x006BE, 0x00378, 0x0049C, 0x00352, 0x003C0, 0x0030C, 0x006D8, 0x00CE0,
|
|
|
|
0x02986, 0x011A2, 0x016F9, 0x00A7D, 0x0122A, 0x00EFD, 0x0082D, 0x0074B,
|
|
|
|
0x00A18, 0x0079D, 0x007B4, 0x003AC, 0x0046E, 0x006FC, 0x00686, 0x004B6,
|
|
|
|
0x01657, 0x017F0, 0x01C36, 0x019FE, 0x00E7E, 0x00ED3, 0x005D4, 0x005F4,
|
|
|
|
0x008A7, 0x00474, 0x0054B, 0x003CB, 0x00884, 0x004E0, 0x00530, 0x004AB,
|
|
|
|
0x006EA, 0x00436, 0x004F0, 0x004F2, 0x00490, 0x003C5, 0x00483, 0x004A2,
|
|
|
|
0x00543, 0x004CC, 0x005F9, 0x00640, 0x00A39, 0x00800, 0x009F2, 0x00CCB,
|
|
|
|
0x0096A, 0x00E01, 0x009C8, 0x00AF0, 0x00A73, 0x01802, 0x00E4F, 0x00B18,
|
|
|
|
0x037AD, 0x00C5C, 0x008AD, 0x00697, 0x00C88, 0x00AB3, 0x00DB8, 0x012BC,
|
|
|
|
0x00FFB, 0x00DBB, 0x014A8, 0x00FB0, 0x01F01, 0x0178F, 0x014F0, 0x00F54,
|
|
|
|
0x0131C, 0x00E9F, 0x011D6, 0x012C7, 0x016DC, 0x01900, 0x01851, 0x02063,
|
|
|
|
0x05ACB, 0x01E9E, 0x01BA1, 0x022E7, 0x0153D, 0x01183, 0x00E39, 0x01488,
|
|
|
|
0x014C0, 0x014D0, 0x014FA, 0x00DA4, 0x0099A, 0x0069E, 0x0071D, 0x00849,
|
|
|
|
0x0077C, 0x0047D, 0x005EC, 0x00557, 0x004D4, 0x00405, 0x004EA, 0x00450,
|
|
|
|
0x004DD, 0x003EE, 0x0047D, 0x00401, 0x004D9, 0x003B8, 0x00507, 0x003E5,
|
|
|
|
0x006B1, 0x003F1, 0x004A3, 0x0036F, 0x0044B, 0x003A1, 0x00436, 0x003B7,
|
|
|
|
0x00678, 0x003A2, 0x00481, 0x00406, 0x004EE, 0x00426, 0x004BE, 0x00424,
|
|
|
|
0x00655, 0x003A2, 0x00452, 0x00390, 0x0040A, 0x0037C, 0x00486, 0x003DE,
|
|
|
|
0x00497, 0x00352, 0x00461, 0x00387, 0x0043F, 0x00398, 0x00478, 0x00420,
|
|
|
|
0x00D86, 0x008C0, 0x0112D, 0x02F68, 0x01E4E, 0x00541, 0x0051B, 0x00CCE,
|
|
|
|
0x0079E, 0x00376, 0x003FF, 0x00458, 0x00435, 0x00412, 0x00425, 0x0042F,
|
|
|
|
0x005CC, 0x003E9, 0x00448, 0x00393, 0x0041C, 0x003E3, 0x0042E, 0x0036C,
|
|
|
|
0x00457, 0x00353, 0x00423, 0x00325, 0x00458, 0x0039B, 0x0044F, 0x00331,
|
|
|
|
0x0076B, 0x00750, 0x003D0, 0x00349, 0x00467, 0x003BC, 0x00487, 0x003B6,
|
|
|
|
0x01E6F, 0x003BA, 0x00509, 0x003A5, 0x00467, 0x00C87, 0x003FC, 0x0039F,
|
|
|
|
0x0054B, 0x00300, 0x00410, 0x002E9, 0x003B8, 0x00325, 0x00431, 0x002E4,
|
|
|
|
0x003F5, 0x00325, 0x003F0, 0x0031C, 0x003E4, 0x00421, 0x02CC1, 0x034C0
|
|
|
|
};
|
|
|
|
|
|
|
|
static int countinghuffCounts[256];
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// static Huffman tree
|
|
|
|
//
|
|
|
|
static tree_t huffTree;
|
|
|
|
|
|
|
|
//
|
|
|
|
// received from MSG_* code
|
|
|
|
//
|
|
|
|
static int huffBitPos;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=======================================================================================
|
|
|
|
|
|
|
|
HUFFMAN TREE CONSTRUCTION
|
|
|
|
|
|
|
|
=======================================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_PrepareTree
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_PrepareTree(tree_t tree)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **node;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
memset(tree, 0, sizeof(tree_t));
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
// create first node
|
|
|
|
node = &tree[263];
|
2008-11-09 22:29:28 +00:00
|
|
|
tree[0] = (void*)(VALUE(tree[0])+1);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
node[7] = NODE_NONE;
|
|
|
|
tree[2] = node;
|
|
|
|
tree[3] = node;
|
|
|
|
tree[4] = node;
|
|
|
|
tree[261] = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_GetNode
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void **Huff_GetNode(void **tree)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **node;
|
|
|
|
int value;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
node = (void**)tree[262];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (!node)
|
|
|
|
{
|
|
|
|
value = VALUE(tree[1])++;
|
2004-08-21 01:25:48 +00:00
|
|
|
node = &tree[value + 6407];
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree[262] = node[0];
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_Swap
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_Swap(void **tree1, void **tree2, void **tree3)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **a, **b;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[2];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a)
|
|
|
|
{
|
|
|
|
if (a[0] == tree2)
|
2004-08-21 01:25:48 +00:00
|
|
|
a[0] = tree3;
|
2008-11-09 22:29:28 +00:00
|
|
|
else
|
2004-08-21 01:25:48 +00:00
|
|
|
a[1] = tree3;
|
|
|
|
}
|
2008-11-09 22:29:28 +00:00
|
|
|
else
|
|
|
|
tree1[2] = tree3;
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
b = (void**)tree3[2];
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (b)
|
|
|
|
{
|
|
|
|
if (b[0] == tree3)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
b[0] = tree2;
|
|
|
|
tree2[2] = b;
|
|
|
|
tree3[2] = a;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
b[1] = tree2;
|
|
|
|
tree2[2] = b;
|
|
|
|
tree3[2] = a;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree1[2] = tree2;
|
|
|
|
tree2[2] = NULL;
|
|
|
|
tree3[2] = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_SwapTrees
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_SwapTrees(void **tree1, void **tree2)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **temp;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree1[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
tree1[3] = tree2[3];
|
|
|
|
tree2[3] = temp;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree1[4];
|
2004-08-21 01:25:48 +00:00
|
|
|
tree1[4] = tree2[4];
|
|
|
|
tree2[4] = temp;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree1[3] == tree1)
|
2004-08-21 01:25:48 +00:00
|
|
|
tree1[3] = tree2;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree2[3] == tree2)
|
2004-08-21 01:25:48 +00:00
|
|
|
tree2[3] = tree1;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree1[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (temp)
|
2004-08-21 01:25:48 +00:00
|
|
|
temp[4] = tree1;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree2[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (temp)
|
2004-08-21 01:25:48 +00:00
|
|
|
temp[4] = tree2;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree1[4];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (temp)
|
2004-08-21 01:25:48 +00:00
|
|
|
temp[3] = tree1;
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
temp = (void**)tree2[4];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (temp)
|
2004-08-21 01:25:48 +00:00
|
|
|
temp[3] = tree2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_DeleteNode
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_DeleteNode(void **tree1, void **tree2)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
tree2[0] = tree1[262];
|
|
|
|
tree1[262] = tree2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_IncrementFreq_r
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static void Huff_IncrementFreq_r(void **tree1, void **tree2)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **a, **b;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (!tree2)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a)
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)a[6];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a == tree2[6])
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
b = (void**)tree2[5];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (b[0] != tree2[2])
|
|
|
|
{
|
|
|
|
Huff_Swap(tree1, (void**)b[0], tree2);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_SwapTrees((void**)b[0], tree2);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[4];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a && a[6] == tree2[6])
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
b = (void**)tree2[5];
|
2004-08-21 01:25:48 +00:00
|
|
|
b[0] = a;
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[5];
|
2004-08-21 01:25:48 +00:00
|
|
|
a[0] = 0;
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_DeleteNode(tree1, (void**)tree2[5]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
VALUE(tree2[6])++;
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a && a[6] == tree2[6])
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
tree2[5] = a[5];
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
a = Huff_GetNode(tree1);
|
2004-08-21 01:25:48 +00:00
|
|
|
tree2[5] = a;
|
|
|
|
a[0] = tree2;
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree2[2])
|
|
|
|
{
|
|
|
|
Huff_IncrementFreq_r(tree1, (void**)tree2[2]);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree2[4] == tree2[2])
|
|
|
|
{
|
|
|
|
Huff_SwapTrees(tree2, (void**)tree2[2]);
|
2005-03-28 00:11:59 +00:00
|
|
|
a = (void**)tree2[5];
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a[0] == tree2)
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
a[0] = (void**)tree2[2];
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_AddReference
|
|
|
|
|
|
|
|
Insert 'ch' into the tree or increment it's frequency
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static void Huff_AddReference(void **tree, int ch)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **a, **b, **c, **d;
|
|
|
|
int value;
|
|
|
|
|
|
|
|
ch &= 255;
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree[ch + 5])
|
|
|
|
{
|
|
|
|
Huff_IncrementFreq_r(tree, (void**)tree[ch + 5]);
|
2004-08-21 01:25:48 +00:00
|
|
|
return; // already added
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
value = VALUE(tree[0])++;
|
2004-08-21 01:25:48 +00:00
|
|
|
b = &tree[value * 8 + 263];
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
value = VALUE(tree[0])++;
|
2004-08-21 01:25:48 +00:00
|
|
|
a = &tree[value * 8 + 263];
|
|
|
|
|
|
|
|
a[7] = NODE_NEXT;
|
|
|
|
a[6] = NODE_START;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
a[3] = d[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (a[3])
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)a[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
d[4] = a;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)a[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (d[6] == NODE_START)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
a[5] = d[5];
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d = Huff_GetNode(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
a[5] = d;
|
|
|
|
d[0] = a;
|
|
|
|
}
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d = Huff_GetNode(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
a[5] = d;
|
|
|
|
d[0] = a;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
d[3] = a;
|
2005-03-28 00:11:59 +00:00
|
|
|
a[4] = (void**)tree[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
b[7] = NODE(ch);
|
2004-08-21 01:25:48 +00:00
|
|
|
b[6] = NODE_START;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
b[3] = d[3];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (b[3])
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)b[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
d[4] = b;
|
2008-11-09 22:29:28 +00:00
|
|
|
if (d[6] == NODE_START)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
b[5] = d[5];
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d = Huff_GetNode(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
b[5] = d;
|
|
|
|
d[0] = a;
|
|
|
|
}
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d = Huff_GetNode(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
b[5] = d;
|
|
|
|
d[0] = b;
|
|
|
|
}
|
|
|
|
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
d[3] = b;
|
2005-03-28 00:11:59 +00:00
|
|
|
b[4] = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
b[1] = NULL;
|
|
|
|
b[0] = NULL;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
|
|
|
c = (void**)d[2];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (c)
|
|
|
|
{
|
|
|
|
if (c[0] == tree[3])
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
c[0] = a;
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
c[1] = a;
|
|
|
|
}
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
tree[2] = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
a[1] = b;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
a[0] = d;
|
|
|
|
a[2] = d[2];
|
|
|
|
b[2] = a;
|
2005-03-28 00:11:59 +00:00
|
|
|
d = (void**)tree[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
d[2] = a;
|
|
|
|
tree[ch + 5] = b;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_IncrementFreq_r(tree, (void**)a[2]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=======================================================================================
|
|
|
|
|
|
|
|
BITSTREAM I/O
|
|
|
|
|
|
|
|
=======================================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_EmitBit
|
|
|
|
|
|
|
|
Put one bit into buffer
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_EmitBit(int bit, qbyte *buffer)
|
|
|
|
{
|
|
|
|
if (!(huffBitPos & 7))
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
buffer[huffBitPos >> 3] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer[huffBitPos >> 3] |= bit << (huffBitPos & 7);
|
|
|
|
huffBitPos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_GetBit
|
|
|
|
|
|
|
|
Read one bit from buffer
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE int Huff_GetBit(qbyte *buffer)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
int bit;
|
|
|
|
|
|
|
|
bit = buffer[huffBitPos >> 3] >> (huffBitPos & 7);
|
|
|
|
huffBitPos++;
|
|
|
|
|
|
|
|
return (bit & 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_EmitPathToByte
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE void Huff_EmitPathToByte(void **tree, void **subtree, qbyte *buffer)
|
|
|
|
{
|
|
|
|
if (tree[2])
|
|
|
|
{
|
|
|
|
Huff_EmitPathToByte((void**)tree[2], tree, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (!subtree)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// emit tree walking control bits
|
|
|
|
//
|
2008-11-09 22:29:28 +00:00
|
|
|
if (tree[1] == subtree)
|
|
|
|
{
|
|
|
|
Huff_EmitBit(1, buffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Huff_EmitBit(0, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_GetByteFromTree
|
|
|
|
|
|
|
|
Get one qbyte using dynamic or static tree
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static ID_INLINE int Huff_GetByteFromTree(void **tree, qbyte *buffer)
|
|
|
|
{
|
|
|
|
if (!tree)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// walk through the tree until we get a value
|
|
|
|
//
|
2008-11-09 22:29:28 +00:00
|
|
|
while (tree[7] == NODE_NEXT)
|
|
|
|
{
|
|
|
|
if (!Huff_GetBit(buffer))
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
tree = (void**)tree[0];
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
tree = (void**)tree[1];
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (!tree)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
return VALUE(tree[7]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_EmitByteDynamic
|
|
|
|
|
|
|
|
Emit one qbyte using dynamic tree
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
static void Huff_EmitByteDynamic(void **tree, int value, qbyte *buffer)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
void **subtree;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
//
|
|
|
|
// if qbyte was already referenced, emit path to it
|
|
|
|
//
|
2005-03-28 00:11:59 +00:00
|
|
|
subtree = (void**)tree[value + 5];
|
2008-11-09 22:29:28 +00:00
|
|
|
if (subtree)
|
|
|
|
{
|
|
|
|
if (subtree[2])
|
|
|
|
{
|
|
|
|
Huff_EmitPathToByte((void**)subtree[2], subtree, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// qbyte was not referenced, just emit 8 bits
|
|
|
|
//
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_EmitByteDynamic(tree, NOT_REFERENCED, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
for (i = 7; i >= 0; i--)
|
|
|
|
{
|
|
|
|
Huff_EmitBit((value >> i) & 1, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=======================================================================================
|
|
|
|
|
|
|
|
PUBLIC INTERFACE
|
|
|
|
|
|
|
|
=======================================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_CompressPacket
|
|
|
|
|
|
|
|
Compress message using dynamic Huffman tree,
|
|
|
|
beginning from specified offset
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
void Huff_EncryptPacket(sizebuf_t *msg, int offset)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
tree_t tree;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
qbyte buffer[MAX_OVERALLMSGLEN];
|
2004-08-21 01:25:48 +00:00
|
|
|
qbyte *data;
|
|
|
|
int outLen;
|
|
|
|
int inLen;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
data = msg->data + offset;
|
2008-11-09 22:29:28 +00:00
|
|
|
inLen = msg->cursize - offset;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
|
2008-11-09 22:29:28 +00:00
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_PrepareTree(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
buffer[0] = inLen >> 8;
|
|
|
|
buffer[1] = inLen & 0xFF;
|
|
|
|
huffBitPos = 16;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
for (i = 0; i < inLen; i++)
|
|
|
|
{
|
|
|
|
Huff_EmitByteDynamic(tree, data[i], buffer);
|
|
|
|
Huff_AddReference(tree, data[i]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
outLen = (huffBitPos >> 3) + 1;
|
|
|
|
|
|
|
|
msg->cursize = offset + outLen;
|
2008-11-09 22:29:28 +00:00
|
|
|
memcpy(data, buffer, outLen);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_DecompressPacket
|
|
|
|
|
|
|
|
Decompress message using dynamic Huffman tree,
|
|
|
|
beginning from specified offset
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
void Huff_DecryptPacket(sizebuf_t *msg, int offset)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
tree_t tree;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
qbyte buffer[MAX_OVERALLMSGLEN];
|
2004-08-21 01:25:48 +00:00
|
|
|
qbyte *data;
|
|
|
|
int outLen;
|
|
|
|
int inLen;
|
|
|
|
int i, j;
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
data = msg->data + offset;
|
|
|
|
inLen = msg->cursize - offset;
|
2008-11-09 22:29:28 +00:00
|
|
|
if (inLen <= 0)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_PrepareTree(tree);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
outLen = (data[0] << 8) + data[1];
|
|
|
|
huffBitPos = 16;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (outLen > msg->maxsize - offset)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
outLen = msg->maxsize - offset;
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
for (i = 0; i < outLen; i++)
|
|
|
|
{
|
|
|
|
if ((huffBitPos >> 3) > inLen)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
buffer[i] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
ch = Huff_GetByteFromTree((void**)tree[2], data);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
if (ch == NOT_REFERENCED)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
ch = 0; // just read 8 bits
|
2008-11-09 22:29:28 +00:00
|
|
|
for (j = 0 ; j < 8 ; j++)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
ch <<= 1;
|
2008-11-09 22:29:28 +00:00
|
|
|
ch |= Huff_GetBit(data);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer[i] = ch;
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_AddReference(tree, ch);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
msg->cursize = offset + outLen;
|
2008-11-09 22:29:28 +00:00
|
|
|
memcpy(data, buffer, outLen);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_EmitByte
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
void Huff_EmitByte(int ch, qbyte *buffer, int *count)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
huffBitPos = *count;
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_EmitPathToByte((void**)huffTree[ch + 5], NULL, buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
*count = huffBitPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_GetByte
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
int Huff_GetByte(qbyte *buffer, int *count)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
int ch;
|
|
|
|
|
|
|
|
huffBitPos = *count;
|
2008-11-09 22:29:28 +00:00
|
|
|
ch = Huff_GetByteFromTree((void**)huffTree[2], buffer);
|
2004-08-21 01:25:48 +00:00
|
|
|
*count = huffBitPos;
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int madetable;
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_Init
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
void Huff_Init(int *huffCounts)
|
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if (!huffCounts)
|
|
|
|
huffCounts = q3huffCounts;
|
|
|
|
|
|
|
|
// build empty tree
|
2008-11-09 22:29:28 +00:00
|
|
|
Huff_PrepareTree(huffTree);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
// add all pre-defined qbyte references
|
2008-11-09 22:29:28 +00:00
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < huffCounts[i]; j++)
|
|
|
|
{
|
|
|
|
Huff_AddReference(huffTree, i);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
2006-04-16 01:48:40 +00:00
|
|
|
huffCounts[i] = LittleLong(huffCounts[i]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
2007-05-02 02:38:41 +00:00
|
|
|
madetable=Com_BlockChecksum(huffCounts, sizeof(*huffCounts)*256);
|
2006-04-16 01:48:40 +00:00
|
|
|
for(i=0;i<256;i++)
|
|
|
|
huffCounts[i] = LittleLong(huffCounts[i]);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Huff_LoadTable(char *filename)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int Huff_PreferedCompressionCRC (void)
|
|
|
|
{
|
|
|
|
if (!madetable)
|
|
|
|
Huff_Init(NULL);
|
|
|
|
return madetable;
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Huff_CompressionCRC(int crc)
|
|
|
|
{
|
|
|
|
if (!madetable)
|
|
|
|
Huff_Init(NULL);
|
2006-04-16 01:48:40 +00:00
|
|
|
if (crc != LittleLong(madetable))
|
2004-08-21 01:25:48 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_CompressPacket
|
|
|
|
|
|
|
|
Compress message using loaded Huffman tree,
|
|
|
|
beginning from specified offset
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void Huff_CompressPacket( sizebuf_t *msg, int offset )
|
|
|
|
{
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
qbyte buffer[MAX_OVERALLMSGLEN];
|
2004-08-21 01:25:48 +00:00
|
|
|
qbyte *data;
|
|
|
|
int outLen;
|
|
|
|
int inLen;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!madetable)
|
|
|
|
Huff_Init(NULL);
|
|
|
|
|
|
|
|
data = msg->data + offset;
|
|
|
|
inLen = msg->cursize - offset;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
|
2008-11-09 22:29:28 +00:00
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
outLen = 0;
|
2008-11-09 22:29:28 +00:00
|
|
|
for (i=0; i < inLen; i++)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (i == MAX_OVERALLMSGLEN)
|
2004-08-21 01:25:48 +00:00
|
|
|
Sys_Error("Compression became too large\n");
|
|
|
|
Huff_EmitByte(data[i], buffer, &outLen);
|
|
|
|
|
|
|
|
countinghuffCounts[data[i]]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
outLen = (huffBitPos >> 3) + 1;
|
|
|
|
|
|
|
|
if (outLen > inLen)
|
|
|
|
{
|
2008-11-09 22:29:28 +00:00
|
|
|
memmove(data+1, data, inLen);
|
2004-08-21 01:25:48 +00:00
|
|
|
data[0] = 0x80; //this would have grown the packet.
|
|
|
|
msg->cursize+=1;
|
|
|
|
return; //cap it at only 1 qbyte growth.
|
|
|
|
}
|
|
|
|
|
|
|
|
msg->cursize = offset + outLen;
|
|
|
|
{ //add the bitcount
|
|
|
|
data[0] = (outLen<<3) - huffBitPos;
|
|
|
|
data+=1;
|
|
|
|
msg->cursize+=1;
|
|
|
|
}
|
|
|
|
if (msg->cursize > msg->maxsize)
|
|
|
|
Sys_Error("Compression became too large\n");
|
2008-11-09 22:29:28 +00:00
|
|
|
memcpy(data, buffer, outLen);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Huff_DecompressPacket
|
|
|
|
|
|
|
|
Decompress message using loaded Huffman tree,
|
|
|
|
beginning from specified offset
|
|
|
|
============
|
|
|
|
*/
|
2008-11-09 22:29:28 +00:00
|
|
|
void Huff_DecompressPacket(sizebuf_t *msg, int offset)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
qbyte buffer[MAX_OVERALLMSGLEN];
|
2004-08-21 01:25:48 +00:00
|
|
|
qbyte *data;
|
|
|
|
int outLen;
|
|
|
|
int inLen;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!madetable)
|
|
|
|
Huff_Init(NULL);
|
|
|
|
|
|
|
|
data = msg->data + offset;
|
|
|
|
inLen = msg->cursize - offset;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
|
2008-11-09 22:29:28 +00:00
|
|
|
{
|
2004-08-21 01:25:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
inLen<<=3;
|
|
|
|
{ //add the bitcount
|
|
|
|
inLen = inLen-8-data[0];
|
|
|
|
if (data[0]&0x80)
|
|
|
|
{ //packet would have grown.
|
|
|
|
msg->cursize -= 1;
|
|
|
|
memmove(data, data+1, msg->cursize);
|
|
|
|
return; //this never happened, okay?
|
|
|
|
}
|
|
|
|
data+=1;
|
|
|
|
}
|
|
|
|
|
|
|
|
outLen = 0;
|
2008-11-09 22:29:28 +00:00
|
|
|
for(i=0; outLen < inLen; i++)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (i == MAX_OVERALLMSGLEN)
|
2004-08-21 01:25:48 +00:00
|
|
|
Sys_Error("Decompression became too large\n");
|
|
|
|
buffer[i] = Huff_GetByte(data, &outLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
msg->cursize = offset + i;
|
|
|
|
if (msg->cursize > msg->maxsize)
|
|
|
|
Sys_Error("Decompression became too large\n");
|
2008-11-09 22:29:28 +00:00
|
|
|
memcpy(msg->data + offset, buffer, i);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2008-11-09 22:29:28 +00:00
|
|
|
|