1 
2 /***********************************************************
3 *                      K O U L E S                         *
4 *----------------------------------------------------------*
5 *  C1995 JAHUSOFT                                          *
6 *        Jan Hubicka                                       *
7 *        Dukelskych Bojovniku 1944                         *
8 *        390 03 Tabor                                      *
9 *        Czech Republic                                    *
10 *        Phone: 0041-361-32613                             *
11 *        eMail: hubicka@limax.paru.cas.cz                  *
12 *----------------------------------------------------------*
13 *   Copyright(c)1995,1996 by Jan Hubicka.See README for    *
14 *                    licence details.                      *
15 *----------------------------------------------------------*
16 *  objectsio.c reading/writing possitions of objects-for   *
17 *	       for network code....			   *
18 ***********************************************************/
19 #ifdef NETSUPPORT
20 #include "koules.h"
21 #include "net.h"
22 #include "client.h"
23 #include "server.h"
24 #include <string.h>
25 #include <math.h>
26 unsigned char   b[256];
27 unsigned char  *buffer;
28 /* This code is specially optimized to produce very compressed packets
29    Normal output for 1 frame=50 bytes.. game structure: 16*256=3KB
30    compression:98.88% :)) */
31 
32 /*I know...bithacket and ugly bit putting routines... */
33 #define PUTZERO() (c<<=1,c==256?(c=1,buffer++,*buffer=0):0)
34 #define GETZERO() (c<<=1,c==256?(c=1,buffer++):0)
35 #define PUTONE() (*buffer|=c,PUTZERO())
36 #define PUTBIT(b) (((b)?(*buffer|=c):0),PUTZERO())
37 #define PUTNUM(b,n) {int co=1; for(;co<(1<<n);co<<=1) PUTBIT(b&co);}
38 #define GETBIT() (*buffer&c?(GETZERO(),1):(GETZERO(),0))
39 #define GETNUM(b,n) {int co=1;b=0; for(;co<(1<<n);co<<=1) b|=(GETBIT())?co:0;}
40 
41 /*Debugging macros... */
42 /*#define DEBUG */
43 #ifdef DEBUG
44 #define Debug(text,num) printf(text,num),fflush(stdout);
45 #define Debug1(text) printf(text),fflush(stdout);
46 #else
47 #define Debug(text,num)
48 #define Debug1(text)
49 #endif
50 extern void     accel (int);
51 
52 /*bit counter */
53 static int      c = 1;
54 unsigned char  *
write_object(unsigned char * buffer,int i)55 write_object (unsigned char *buffer, int i)
56 {
57   unsigned long   x;
58 
59   PUTBIT (object[i].live);
60   Debug ("%i:", i);
61   Debug ("Live:%i ", object[i].live);
62   if (object[i].live)
63     {
64       PUTNUM (object[i].type, 4);
65       Debug ("Type:%i ", object[i].type);
66     }
67   if (i < 5)
68     {
69       if (object[i].live)
70 	{
71 	  PUTBIT (object[i].thief);
72 	  PUTBIT (acceled[i]);
73 	}
74       PUTNUM (object[i].score, 20);
75       PUTNUM (object[i].live1, 3);
76     }
77   if (object[i].live)
78     {
79       if (object[i].lineto == -1)
80 	{
81 	  PUTZERO ();
82 	}
83       else
84 	{
85 	  PUTONE ();
86 	  PUTNUM (object[i].lineto, 8);
87 	}
88       Debug ("lineto:%i ", object[i].lineto);
89       x = object[i].x;
90       PUTNUM (x, 10);
91       Debug ("x:%i ", (int) object[i].x);
92       Debug ("y:%i ", (int) object[i].x);
93       x = object[i].y;
94       PUTNUM (x, 9);
95     }
96   if (object[i].live && object[i].type == ROCKET)
97     {
98       while(object[i].rotation<0) object[i].rotation+=2*M_PI;
99       while(object[i].rotation>=2*M_PI) object[i].rotation-=2*M_PI;
100       x = (object[i].rotation * 16.0 / M_PI);
101       Debug ("Rotation:%i ", x);
102       PUTNUM (x, 6);
103     }
104   if (object[i].live && object[i].type == LBALL)
105     {
106       Debug ("Letter:%c ", object[i].letter);
107       switch (object[i].letter)
108 	{
109 	case L_ACCEL:
110 	  PUTNUM (1, 3);
111 	  break;
112 	case L_GUMM:
113 	  PUTNUM (2, 3);
114 	  break;
115 	case L_FINDER:
116 	  PUTNUM (3, 3);
117 	  break;
118 	case L_THIEF:
119 	  PUTNUM (4, 3);
120 	  break;
121 	case L_TTOOL:
122 	  PUTNUM (5, 3);
123 	  break;
124 	default:
125 	  printf ("Internal error:unknown letter type!\n");
126 	  PUTNUM (1, 3);
127 	  break;
128 	}
129     }
130   Debug1 ("\n");
131   return (buffer);
132 }
133 unsigned char  *
read_object(int i,unsigned char * buffer,int nodata)134 read_object (int i, unsigned char *buffer, int nodata)
135 {
136   unsigned long   x;
137   int             a = 0;
138   object[i].live = GETBIT ();
139   Debug ("%i:", i);
140   Debug ("Object:%i", object[i].live);
141   if (object[i].live)
142     {
143       GETNUM (object[i].type, 4);
144       Debug ("Type:%i", object[i].type);
145     }
146   if (i < 5)
147     {
148       if (object[i].live)
149 	{
150 	  object[i].thief = GETBIT ();
151 	  a = GETBIT ();
152 	}
153       GETNUM (object[i].score, 20);
154       GETNUM (object[i].live1, 3);
155     }
156   if (object[i].live)
157     {
158       if (GETBIT ())
159 	{
160 	  GETNUM (object[i].lineto, 8);
161 	}
162       else
163 	object[i].lineto = -1;
164       Debug ("Lineto:%i ", object[i].lineto);
165       GETNUM (x, 10);
166       object[i].x = x;
167       Debug ("x:%i ", (int) object[i].x);
168       GETNUM (x, 9);
169       object[i].y = x;
170       Debug ("y:%i ", (int) object[i].y);
171     }
172   if (object[i].live && object[i].type == ROCKET)
173     {
174       GETNUM (x, 6);
175       Debug ("Rotation:%i ", x);
176       object[i].rotation = (float) x *M_PI / 16.0;
177     }
178   if (object[i].live && object[i].type == LBALL)
179     {
180       GETNUM (x, 3);
181       switch (x)
182 	{
183 	case 1:
184 	  object[i].letter = L_ACCEL;
185 	  break;
186 	case 2:
187 	  object[i].letter = L_GUMM;
188 	  break;
189 	case 3:
190 	  object[i].letter = L_THIEF;
191 	  break;
192 	case 4:
193 	  object[i].letter = L_FINDER;
194 	  break;
195 	case 5:
196 	  object[i].letter = L_TTOOL;
197 	  break;
198 	default:
199 	  object[i].letter = ' ';
200 	  printf ("Internal error:unknown letter...maybe newer server than client?\n");
201 	  break;
202 	}
203       Debug ("Letter:%c", object[i].letter);
204     }
205   if (a)
206     {
207       int             n;
208       for (n = 0; n < nodata; n++)
209 	accel (i);
210     }
211   Debug1 ("\n");
212   return (buffer);
213 }
214 int
write_objects(unsigned char * buffer)215 write_objects (unsigned char *buffer)
216 {
217   int             i;
218   unsigned char  *buffer1 = buffer;
219   /*Initialize bit operation routines */
220   c = 1;
221   buffer[0] = 0;
222   /*Optimize number of objects */
223   nobjects--;
224   while (object[nobjects].live == 0 && object[nobjects].time == 0)
225     nobjects--;
226   nobjects++;
227   Debug ("%i\n", nobjects);
228   /*Put number of object at the beggining of packet */
229   PUTNUM (nobjects, 8);
230   /*Put all objects */
231   for (i = 0; i < nobjects; i++)
232     buffer = write_object (buffer, i);
233   if (c != 1)
234     buffer++;
235   return (buffer - buffer1);
236 }
237 int
read_objects(unsigned char * buffer,int nodata)238 read_objects (unsigned char *buffer, int nodata)
239 {
240   int             i;
241   unsigned char  *buffer1 = buffer;
242   c = 1;
243   GETNUM (nobjects, 8);
244   Debug ("%i\n", nobjects);
245   for (i = 0; i < nobjects; i++)
246     buffer = read_object (i, buffer, nodata);
247   for (; i < MAXOBJECT; i++)
248     object[i].live = 0;
249   return (buffer - buffer1);
250 }
251 #endif
252