about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-05-24 10:57:18 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-05-24 10:57:18 +0000
commitea3922117076b01f10f19fdc10e6d9f2bfb54e0a (patch)
tree228624c52b0a6b69431ac0153c9fd817ef70b03a /src
parentf7dcca0af4810c4520e4efbe1c968198d39d0bd3 (diff)
downloadzcatch-ea3922117076b01f10f19fdc10e6d9f2bfb54e0a.tar.gz
zcatch-ea3922117076b01f10f19fdc10e6d9f2bfb54e0a.zip
fixed some compression stuff
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp157
-rw-r--r--src/lzw.cpp82
-rw-r--r--src/packet.h84
-rw-r--r--src/server.cpp26
-rw-r--r--src/trackinggenerator/main.cpp109
5 files changed, 340 insertions, 118 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 8954decc..2f231117 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -5,6 +5,7 @@
 #include <baselib/stream/file.h>
 
 #include <string.h>
+#include <stdarg.h>
 #include <math.h>
 #include "interface.h"
 
@@ -93,8 +94,11 @@ void inp_update()
 // --- input snapping ---
 static int input_data[MAX_INPUT_SIZE];
 static int input_data_size;
+static int input_is_changed = 1;
 void snap_input(void *data, int size)
 {
+	if(input_data_size != size || memcmp(input_data, data, size))
+		input_is_changed = 1;
 	mem_copy(input_data, data, size);
 	input_data_size = size;
 }
@@ -167,6 +171,103 @@ float client_frametime()
 	return frametime;
 }
 
+void unpack(const char *src, const char *fmt, ...)
+{
+}
+
+/*int modc_onmsg(int msg)
+{
+	msg_get("iis")
+}*/
+
+/*
+	i = int (int i)
+	s = string (const char *str)
+	r = raw data (int size, void *data)
+*/
+
+/*
+class packet2
+{
+private:
+	// packet data
+	struct header
+	{
+		unsigned msg;
+		unsigned ack;
+		unsigned seq;
+	};
+	
+	unsigned char packet_data[MAX_PACKET_SIZE];
+	unsigned char *current;
+	
+	enum
+	{
+		MAX_PACKET_SIZE = 1024,
+	};
+	
+public:
+	packet2()
+	{
+		current = packet_data;
+		current += sizeof(header);
+	}
+
+	int pack(char *dst, const char *fmt, ...)
+	{
+		va_list arg_list;
+		va_start(arg_list, fmt);
+		while(*fmt)
+		{
+			if(*fmt == 's')
+			{
+				// pack string
+				const char *s = va_arg(arg_list, const char*);
+				*dst++ = 2;
+				while(*s)
+				{
+					*dst = *s;
+					dst++;
+					s++;
+				}
+				*dst = 0; // null terminate
+				dst++;
+				fmt++;
+			}
+			else if(*fmt == 'i')
+			{
+				// pack int
+				int i = va_arg(arg_list, int);
+				*dst++ = 1;
+				*dst++ = (i>>24)&0xff;
+				*dst++ = (i>>16)&0xff;
+				*dst++ = (i>>8)&0xff;
+				*dst++ = i&0xff;
+				fmt++;
+			}
+			else
+			{
+				dbg_break(); // error
+				break;
+			}
+		}
+		va_end(arg_list);	
+	}	
+};
+*/
+/*
+int msg_get(const char *fmt)
+{
+	
+}
+
+int client_msg_send(int msg, const char *fmt, ...)
+
+int server_msg_send(int msg, const char *fmt, ...)
+{
+
+}*/
+
 // --- client ---
 class client
 {
@@ -221,12 +322,21 @@ public:
 	{
 		recived_snapshots = 0;
 		
+		/*
+		pack(NETMSG_CLIENT_CONNECT, "sssss",
+			TEEWARS_NETVERSION,
+			name,
+			"no clan",
+			"password",
+			"myskin");
+		*/
+		
 		packet p(NETMSG_CLIENT_CONNECT);
-		p.write_str(TEEWARS_NETVERSION, 32); // payload
-		p.write_str(name,MAX_NAME_LENGTH);
-		p.write_str("no clan", MAX_CLANNAME_LENGTH);
-		p.write_str("password", 32);
-		p.write_str("myskin", 32);
+		p.write_str(TEEWARS_NETVERSION); // payload
+		p.write_str(name);
+		p.write_str("no clan");
+		p.write_str("password");
+		p.write_str("myskin");
 		send_packet(&p);
 	}
 
@@ -238,8 +348,11 @@ public:
 
 	void send_error(const char *error)
 	{
+		/*
+			pack(NETMSG_CLIENT_ERROR, "s", error);
+		*/
 		packet p(NETMSG_CLIENT_ERROR);
-		p.write_str(error, 128);
+		p.write_str(error);
 		send_packet(&p);
 		//send_packet(&p);
 		//send_packet(&p);
@@ -247,8 +360,10 @@ public:
 
 	void send_input()
 	{
+		/*
+			pack(NETMSG_CLIENT_ERROR, "s", error);
+		*/
 		packet p(NETMSG_CLIENT_INPUT);
-		
 		p.write_int(input_data_size);
 		for(int i = 0; i < input_data_size/4; i++)
 			p.write_int(input_data[i]);
@@ -365,7 +480,7 @@ public:
 		int64 inputs_per_second = 50;
 		int64 time_per_input = time_freq()/inputs_per_second;
 		int64 game_starttime = time_get();
-		int64 lastinput = game_starttime;
+		int64 last_input = game_starttime;
 		
 		int64 reporttime = time_get();
 		int64 reportinterval = time_freq()*1;
@@ -377,12 +492,16 @@ public:
 		{	
 			frames++;
 			int64 frame_start_time = time_get();
-			
-			if(time_get()-lastinput > time_per_input)
+
+			// send input
+			if(get_state() == STATE_ONLINE)
 			{
-				if(get_state() == STATE_ONLINE)
+				if(input_is_changed || time_get() > last_input+time_freq())
+				{
 					send_input();
-				lastinput += time_per_input;
+					input_is_changed = 0;
+					last_input = time_get();
+				}
 			}
 			
 			// update input
@@ -449,8 +568,8 @@ public:
 	{
 		if(p->msg() == NETMSG_SERVER_ACCEPT)
 		{
-			char map[32];
-			p->read_str(map, 32);
+			const char *map;
+			map = p->read_str();
 			
 			if(p->is_good())
 			{
@@ -482,7 +601,8 @@ public:
 			{
 				if(snapshot_part == part)
 				{
-					p->read_raw((char*)snapshots[SNAP_INCOMMING] + part*MAX_SNAPSHOT_PACKSIZE, part_size);
+					const char *d = p->read_raw(part_size);
+					mem_copy((char*)snapshots[SNAP_INCOMMING] + part*MAX_SNAPSHOT_PACKSIZE, d, part_size);
 					snapshot_part++;
 				
 					if(snapshot_part == num_parts)
@@ -495,13 +615,6 @@ public:
 						lzw_decompress(snapshots[SNAP_INCOMMING], snapshots[SNAP_CURRENT]);
 						
 						// apply snapshot, cycle pointers
-						/*
-						snapshot *tmp = snapshots[SNAP_PREV];
-						snapshots[SNAP_PREV] = snapshots[SNAP_CURRENT];
-						snapshots[SNAP_CURRENT] = snapshots[SNAP_INCOMMING];
-						snapshots[SNAP_INCOMMING] = tmp;
-						*/
-						
 						recived_snapshots++;
 						snapshot_start_time = time_get();
 						
diff --git a/src/lzw.cpp b/src/lzw.cpp
index 52ca569d..80dd1c22 100644
--- a/src/lzw.cpp
+++ b/src/lzw.cpp
@@ -3,7 +3,7 @@
 // LZW Compressor
 struct SYM
 {
-	unsigned char data[1024*2];
+	unsigned char *data;
 	int size;
 	int next;
 };
@@ -21,21 +21,6 @@ static SYMBOLS symbols;
 inline int sym_size(int i) { return symbols.syms[i].size; }
 inline unsigned char *sym_data(int i) { return symbols.syms[i].data; }
 
-static void sym_init()
-{
-	for(int i = 0; i < 256; i++)
-	{
-		symbols.syms[i].data[0] = (unsigned char)i;
-		symbols.syms[i].size = 1;
-		symbols.jumptable[i] = -1;
-	}
-
-	for(int i = 0; i < 512; i++)
-		symbols.syms[i].next = -1;
-
-	symbols.currentsym = 0;
-}
-
 static void sym_index(int sym)
 {
 	int table = symbols.syms[sym].data[0];
@@ -68,10 +53,9 @@ static void sym_unindex(int sym)
 static int sym_add(unsigned char *sym, long len)
 {
 	int i = 256+symbols.currentsym;
-
-	memcpy(symbols.syms[i].data, sym, len);
+	symbols.syms[i].data = sym;
 	symbols.syms[i].size = len;
-	symbols.currentsym = (i+1)%255;
+	symbols.currentsym = (symbols.currentsym+1)%255;
 	return i;
 }
 
@@ -84,13 +68,40 @@ static int sym_add_and_index(unsigned char *sym, long len)
 	return s;
 }
 
-static void sym_append(int sym, unsigned char extra)
+static void sym_init()
 {
-	symbols.syms[sym].data[symbols.syms[sym].size] = extra;
-	symbols.syms[sym].size++;
+	static unsigned char table[256];
+	for(int i = 0; i < 256; i++)
+	{
+		table[i] = i;
+		symbols.syms[i].data = &table[i];
+		symbols.syms[i].size = 1;
+		symbols.jumptable[i] = -1;
+	}
+
+	for(int i = 0; i < 512; i++)
+		symbols.syms[i].next = -1;
+
+	/*
+	// insert some symbols to start with
+	static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
+	//static unsigned char one1[4] = {0,0,0,1};
+	//static unsigned char one2[4] = {1,0,0,0};
+	sym_add_and_index(zeros, 2);
+	sym_add_and_index(zeros, 3);
+	sym_add_and_index(zeros, 4);
+	sym_add_and_index(zeros, 5);
+	sym_add_and_index(zeros, 6);
+	sym_add_and_index(zeros, 7);
+	sym_add_and_index(zeros, 8);
+	
+	//sym_add_and_index(one1, 4);
+	//sym_add_and_index(one2, 4);*/
+
+	symbols.currentsym = 0;
 }
 
-static int sym_find(unsigned char *data, int size)
+static int sym_find(unsigned char *data, int size, int avoid)
 {
 	int best = data[0];
 	int bestlen = 1;
@@ -98,7 +109,7 @@ static int sym_find(unsigned char *data, int size)
 
 	while(current != -1)
 	{
-		if(symbols.syms[current].size <= size && memcmp(data, symbols.syms[current].data, symbols.syms[current].size) == 0)
+		if(current != avoid && symbols.syms[current].size <= size && memcmp(data, symbols.syms[current].data, symbols.syms[current].size) == 0)
 		{
 			if(bestlen < symbols.syms[current].size)
 			{
@@ -122,6 +133,7 @@ long lzw_compress(const void *src_, int size, void *dst_)
 	unsigned char *end = (unsigned char *)src_+size;
 	unsigned char *dst = (unsigned char *)dst_;
 	long left = (end-src);
+	int lastsym = -1;
 
 	// init symboltable
 	sym_init();
@@ -146,7 +158,7 @@ long lzw_compress(const void *src_, int size, void *dst_)
 				break;
 			}
 
- 			int sym = sym_find( src, left);
+ 			int sym = sym_find(src, left, lastsym);
 			int symsize = sym_size( sym);
 
 			if(sym&0x100)
@@ -155,7 +167,7 @@ long lzw_compress(const void *src_, int size, void *dst_)
 			*dst++ = sym&0xff; // set symbol
 
 			if(left > symsize+1) // create new symbol
-				sym_add_and_index( src, symsize+1);
+				lastsym = sym_add_and_index(src, symsize+1);
 			
 			src += symsize; // advance src
 			left -= symsize;
@@ -175,7 +187,8 @@ long lzw_decompress(const void *src_, void *dst_)
 {
 	unsigned char *src = (unsigned char *)src_;
 	unsigned char *dst = (unsigned char *)dst_;
-	int previtem = -1; // 0-255 = raw byte, 256+ = symbol
+	unsigned char *prevdst = 0;
+	int prevsize = -1;
 	int item;
 
 	sym_init();
@@ -195,16 +208,13 @@ long lzw_decompress(const void *src_, void *dst_)
 			if(item == 0x1ff) // EOF symbol
 				return (dst-(unsigned char *)dst_);
 
-			if(previtem != -1) // this one could be removed
-			{
-				// the previous item can 
-				int s = sym_add( sym_data( previtem), sym_size( previtem));
-				sym_append(s, sym_data( item)[0]);
-			}
+			if(prevdst) // this one could be removed
+				sym_add(prevdst, prevsize+1);
 				
-			memcpy(dst, sym_data( item), sym_size( item));
-			dst += sym_size( item);
-			previtem = item;
+			memcpy(dst, sym_data(item), sym_size(item));
+			prevdst = dst;
+			prevsize = sym_size(item);
+			dst += sym_size(item);
 		}
 
 	}
diff --git a/src/packet.h b/src/packet.h
index 62784044..ebc5e41e 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -18,7 +18,7 @@ protected:
 		unsigned seq;
 	};
 	
-	unsigned char packet_data[MAX_PACKET_SIZE-sizeof(header)];
+	unsigned char packet_data[MAX_PACKET_SIZE];
 	unsigned char *current;
 	
 	// these are used to prepend data in the packet
@@ -26,8 +26,6 @@ protected:
 	// pack and unpack the same way
 	enum
 	{
-		DEBUG_TYPE_SHIFT=24,
-		DEBUG_SIZE_MASK=0xffff,
 		DEBUG_TYPE_INT=0x1,
 		DEBUG_TYPE_STR=0x2,
 		DEBUG_TYPE_RAW=0x3,
@@ -36,19 +34,29 @@ protected:
 	// writes an int to the packet
 	void write_int_raw(int i)
 	{
-		// TODO: byteorder fix, should make sure that it writes big endian
 		// TODO: check for overflow
 		*(int*)current = i;
 		current += sizeof(int);
 	}
 
 	// reads an int from the packet
-	void read_int_raw(int *i)
+	int read_int_raw()
 	{
-		// TODO: byteorder fix, should make sure that it reads big endian
 		// TODO: check for overflow
-		*i = *(int*)current;
+		int i = *(int*)current;
 		current += sizeof(int);
+		return i;
+	}
+	
+	void debug_insert_mark(int type, int size)
+	{
+		write_int_raw((type<<16)|size);
+	}
+	
+	void debug_verify_mark(int type, int size)
+	{
+		if(read_int_raw() == ((type<<16) | size))
+			dbg_assert(0, "error during packet disassembly");
 	}
 	
 public:
@@ -68,69 +76,52 @@ public:
 	// writes an int to the packet
 	void write_int(int i)
 	{
-		write_int_raw((DEBUG_TYPE_INT<<DEBUG_TYPE_SHIFT) | 4);
+		debug_insert_mark(DEBUG_TYPE_INT, 4);
 		write_int_raw(i);
 	}
 
 	void write_raw(const char *raw, int size)
 	{
-		write_int_raw((DEBUG_TYPE_RAW<<DEBUG_TYPE_SHIFT) | size);
+		debug_insert_mark(DEBUG_TYPE_RAW, size);
 		while(size--)
 			*current++ = *raw++;
 	}
 
 	// writes a string to the packet
-	void write_str(const char *str, int storagesize)
+	void write_str(const char *str)
 	{
-		write_int_raw((DEBUG_TYPE_STR<<DEBUG_TYPE_SHIFT) | storagesize);
-		
-		while(storagesize-1) // make sure to zero terminate
-		{
-			if(!*str)
-				break;
-			
+		debug_insert_mark(DEBUG_TYPE_STR, 0);
+		int s = strlen(str)+1;
+		write_int_raw(s);
+		for(;*str; current++, str++)
 			*current = *str;
-			current++;
-			str++;
-			storagesize--;
-		}
-		
-		while(storagesize)
-		{
-			*current = 0;
-			current++;
-			storagesize--;
-		}
+		*current = 0;
+		current++;
 	}
 	
 	// reads an int from the packet
 	int read_int()
 	{
-		int t;
-		read_int_raw(&t);
-		dbg_assert(t == ((DEBUG_TYPE_INT<<DEBUG_TYPE_SHIFT) | 4), "error during packet disassembly");
-		read_int_raw(&t);
-		return t;
+		debug_verify_mark(DEBUG_TYPE_INT, 4);
+		return read_int_raw();
 	}
 	
 	// reads a string from the packet
-	void read_str(char *str, int storagesize)
+	const char *read_str()
 	{
-		int t;
-		read_int_raw(&t);
-		dbg_assert(t == ((DEBUG_TYPE_STR<<DEBUG_TYPE_SHIFT) | storagesize), "error during packet disassembly.");
-		mem_copy(str, current, storagesize);
-		current += storagesize;
-		dbg_assert(str[storagesize-1] == 0, "string should be zero-terminated.");
+		debug_verify_mark(DEBUG_TYPE_STR, 0);
+		const char *s = (const char *)current;
+		int size = read_int_raw();
+		current += size;
+		return s;
 	}
 	
-	void read_raw(char *data, int size)
+	const char *read_raw(int size)
 	{
-		int t;
-		read_int_raw(&t);
-		dbg_assert(t == ((DEBUG_TYPE_RAW<<DEBUG_TYPE_SHIFT) | size), "error during packet disassembly.");
-		while(size--)
-			*data++ = *current++;
+		debug_verify_mark(DEBUG_TYPE_RAW, size);
+		const char *d = (const char *)current;
+		current += size;
+		return d;
 	}
 	
 	// TODO: impelement this
@@ -190,7 +181,6 @@ public:
 			// TODO: save packet, we might need to retransmit
 		}
 		
-		//dbg_msg("network/connection", "sending packet. msg=%x size=%x seq=%x ", p->msg(), p->size(), seq);
 		p->set_header(ack, seq);
 		socket->send(&address(), p->data(), p->size());
 		counter_sent_bytes += p->size();
diff --git a/src/server.cpp b/src/server.cpp
index 0d4a293c..1de5839b 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -392,7 +392,7 @@ public:
 	void send_accept(client *client, const char *map)
 	{
 		packet p(NETMSG_SERVER_ACCEPT);
-		p.write_str(map, 32);
+		p.write_str(map);
 		client->conn.send(&p);
 	}
 	
@@ -440,8 +440,7 @@ public:
 		}
 		else if(p->msg() == NETMSG_CLIENT_ERROR)
 		{
-			char reason[128];
-			p->read_str(reason, 128);
+			const char *reason = p->read_str();
 			if(p->is_good())
 				dbg_msg("network/server", "client error. cid=%x reason='%s'", cid, reason);
 			else
@@ -460,17 +459,17 @@ public:
 		if(p->msg() == NETMSG_CLIENT_CONNECT)
 		{
 			// we got no state for this client yet
-			char version[32];
-			char name[MAX_NAME_LENGTH];
-			char clan[MAX_CLANNAME_LENGTH];
-			char password[32];
-			char skin[32];
+			const char *version;
+			const char *name;
+			const char *clan;
+			const char *password;
+			const char *skin;
 			
-			p->read_str(version, 32);
-			p->read_str(name, MAX_NAME_LENGTH);
-			p->read_str(clan, MAX_CLANNAME_LENGTH);
-			p->read_str(password, 32);
-			p->read_str(skin, 32);
+			version = p->read_str();
+			name = p->read_str();
+			clan = p->read_str();
+			password = p->read_str();
+			skin = p->read_str();
 			
 			if(p->is_good())
 			{
@@ -493,6 +492,7 @@ public:
 				if(id != -1)
 				{
 					// slot found
+					// TODO: perform correct copy here
 					mem_copy(clients[id].name, name, MAX_NAME_LENGTH);
 					mem_copy(clients[id].clan, clan, MAX_CLANNAME_LENGTH);
 					clients[id].state = client::STATE_CONNECTING;
diff --git a/src/trackinggenerator/main.cpp b/src/trackinggenerator/main.cpp
new file mode 100644
index 00000000..e63f9ce4
--- /dev/null
+++ b/src/trackinggenerator/main.cpp
@@ -0,0 +1,109 @@
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+	if (argc != 2)
+	{
+		cout << "Usage: bla <infile.tga>" << endl;
+		return -1;
+	}
+
+	ifstream file(argv[1]);
+
+	if (!file)
+	{
+		cout << "No such file..." << endl;
+		return -1;
+	}
+
+	unsigned short headers[9];
+
+	file.read((char *)headers, 18);
+
+	int width = headers[6];
+	int height = headers[7];
+
+	const int charsx = 16;
+	const int charsy = 16;
+	const int charWidth = width / charsx;
+	const int charHeight = height / charsy;
+
+	char *data = new char[width * height * 4];
+
+	file.read(data, width * height * 4);
+	
+    int startTable[256] = {0};
+	int endTable[256] = {0};
+
+    for (int i = 0; i < charsy; i++)
+        for (int j = 0; j < charsx; j++)
+        {
+            bool done = false;
+
+            for (int x = 0; x < charWidth && !done; ++x)
+                for (int y = charHeight - 1; y >= 0; --y)
+                {   
+                    // check if alpha is != 0 
+                    int tempX = j * charWidth + x;
+                    int tempY = i * charHeight + y;
+                    
+                    int coordIndex = tempX + tempY * width;
+                    
+                    if (data[4 * coordIndex + 3] != 0)
+                    {   
+                        // if it is, save the x-coord to table and go to next character
+                        startTable[j + i * charsx] = x;
+                        done = true;
+                    }
+                }
+
+
+			done = false;
+            for (int x = charWidth - 1; x >= 0 && !done; --x)
+                for (int y = charHeight - 1; y >= 0; --y)
+                {
+                    // check if alpha is != 0
+                    int tempX = j * charWidth + x;
+                    int tempY = i * charHeight + y;
+
+                    int coordIndex = tempX + tempY * width;
+
+                    if (data[4 * coordIndex + 3] != 0)
+                    {
+                        // if it is, save the x-coord to table and go to next character
+                        endTable[j + i * charsx] = x;
+                        done = true;
+                    }
+                }
+        }
+
+    delete[] data;
+
+    cout << "float CharStartTable[] =" << endl << '{' << endl << '\t';
+
+    for (int i = 0; i < 256; i++)
+    {
+        cout << startTable[i] / float(charWidth) << ", ";
+        if (!((i + 1) % 16))
+            cout << endl << '\t';
+    }
+
+    cout << endl << "};" << endl;
+
+    cout << "float CharEndTable[] =" << endl << '{' << endl << '\t';
+
+    for (int i = 0; i < 256; i++)
+    {
+        cout << endTable[i] / float(charWidth) << ", ";
+        if (!((i + 1) % 16))
+            cout << endl << '\t';
+    }
+
+    cout << endl << "};" << endl;
+
+        
+    cout << charWidth << 'x' << charHeight << endl;
+}