]> git.xonotic.org Git - xonotic/darkplaces.git/blob - sv_ents_nq.c
libcurl: Use the generic linked list
[xonotic/darkplaces.git] / sv_ents_nq.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 qbool EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates, const entity_state_t **states)
5 {
6         prvm_prog_t *prog = SVVM_prog;
7         const entity_state_t *s;
8         entity_state_t baseline;
9         int i, bits;
10         sizebuf_t buf;
11         unsigned char data[128];
12         qbool success = false;
13
14         // prepare the buffer
15         memset(&buf, 0, sizeof(buf));
16         buf.data = data;
17         buf.maxsize = sizeof(data);
18
19         for (i = 0;i < numstates;i++)
20         {
21                 s = states[i];
22                 if(PRVM_serveredictfunction((&prog->edicts[s->number]), SendEntity))
23                         continue;
24
25                 // prepare the buffer
26                 SZ_Clear(&buf);
27
28 // send an update
29                 bits = 0;
30                 if (s->number >= 256)
31                         bits |= U_LONGENTITY;
32                 if (s->flags & RENDER_STEP)
33                         bits |= U_STEP;
34                 if (s->flags & RENDER_VIEWMODEL)
35                         bits |= U_VIEWMODEL;
36                 if (s->flags & RENDER_GLOWTRAIL)
37                         bits |= U_GLOWTRAIL;
38                 if (s->flags & RENDER_EXTERIORMODEL)
39                         bits |= U_EXTERIORMODEL;
40
41                 // LadyHavoc: old stuff, but rewritten to have more exact tolerances
42                 baseline = prog->edicts[s->number].priv.server->baseline;
43                 if (baseline.origin[0] != s->origin[0])
44                         bits |= U_ORIGIN1;
45                 if (baseline.origin[1] != s->origin[1])
46                         bits |= U_ORIGIN2;
47                 if (baseline.origin[2] != s->origin[2])
48                         bits |= U_ORIGIN3;
49                 if (baseline.angles[0] != s->angles[0])
50                         bits |= U_ANGLE1;
51                 if (baseline.angles[1] != s->angles[1])
52                         bits |= U_ANGLE2;
53                 if (baseline.angles[2] != s->angles[2])
54                         bits |= U_ANGLE3;
55                 if (baseline.colormap != s->colormap)
56                         bits |= U_COLORMAP;
57                 if (baseline.skin != s->skin)
58                         bits |= U_SKIN;
59                 if (baseline.frame != s->frame)
60                 {
61                         bits |= U_FRAME;
62                         if (s->frame & 0xFF00)
63                                 bits |= U_FRAME2;
64                 }
65                 if (baseline.effects != s->effects)
66                 {
67                         bits |= U_EFFECTS;
68                         if (s->effects & 0xFF00)
69                                 bits |= U_EFFECTS2;
70                 }
71                 if (baseline.modelindex != s->modelindex)
72                 {
73                         bits |= U_MODEL;
74                         if ((s->modelindex & 0xFF00) && sv.protocol != PROTOCOL_NEHAHRABJP && sv.protocol != PROTOCOL_NEHAHRABJP2 && sv.protocol != PROTOCOL_NEHAHRABJP3)
75                                 bits |= U_MODEL2;
76                 }
77                 if (baseline.alpha != s->alpha)
78                         bits |= U_ALPHA;
79                 if (baseline.scale != s->scale)
80                         bits |= U_SCALE;
81                 if (baseline.glowsize != s->glowsize)
82                         bits |= U_GLOWSIZE;
83                 if (baseline.glowcolor != s->glowcolor)
84                         bits |= U_GLOWCOLOR;
85                 if (!VectorCompare(baseline.colormod, s->colormod))
86                         bits |= U_COLORMOD;
87
88                 // if extensions are disabled, clear the relevant update flags
89                 if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_NEHAHRAMOVIE)
90                         bits &= 0x7FFF;
91                 if (sv.protocol == PROTOCOL_NEHAHRAMOVIE)
92                         if (s->alpha != 255 || s->effects & EF_FULLBRIGHT)
93                                 bits |= U_EXTEND1;
94
95                 // write the message
96                 if (bits >= 16777216)
97                         bits |= U_EXTEND2;
98                 if (bits >= 65536)
99                         bits |= U_EXTEND1;
100                 if (bits >= 256)
101                         bits |= U_MOREBITS;
102                 bits |= U_SIGNAL;
103
104                 {
105                         ENTITYSIZEPROFILING_START(msg, states[i]->number, bits);
106
107                         MSG_WriteByte (&buf, bits);
108                         if (bits & U_MOREBITS)          MSG_WriteByte(&buf, bits>>8);
109                         if (sv.protocol != PROTOCOL_NEHAHRAMOVIE)
110                         {
111                                 if (bits & U_EXTEND1)   MSG_WriteByte(&buf, bits>>16);
112                                 if (bits & U_EXTEND2)   MSG_WriteByte(&buf, bits>>24);
113                         }
114                         if (bits & U_LONGENTITY)        MSG_WriteShort(&buf, s->number);
115                         else                                            MSG_WriteByte(&buf, s->number);
116
117                         if (bits & U_MODEL)
118                         {
119                                 if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
120                                         MSG_WriteShort(&buf, s->modelindex);
121                                 else
122                                         MSG_WriteByte(&buf, s->modelindex);
123                         }
124                         if (bits & U_FRAME)                     MSG_WriteByte(&buf, s->frame);
125                         if (bits & U_COLORMAP)          MSG_WriteByte(&buf, s->colormap);
126                         if (bits & U_SKIN)                      MSG_WriteByte(&buf, s->skin);
127                         if (bits & U_EFFECTS)           MSG_WriteByte(&buf, s->effects);
128                         if (bits & U_ORIGIN1)           MSG_WriteCoord(&buf, s->origin[0], sv.protocol);
129                         if (bits & U_ANGLE1)            MSG_WriteAngle(&buf, s->angles[0], sv.protocol);
130                         if (bits & U_ORIGIN2)           MSG_WriteCoord(&buf, s->origin[1], sv.protocol);
131                         if (bits & U_ANGLE2)            MSG_WriteAngle(&buf, s->angles[1], sv.protocol);
132                         if (bits & U_ORIGIN3)           MSG_WriteCoord(&buf, s->origin[2], sv.protocol);
133                         if (bits & U_ANGLE3)            MSG_WriteAngle(&buf, s->angles[2], sv.protocol);
134                         if (bits & U_ALPHA)                     MSG_WriteByte(&buf, s->alpha);
135                         if (bits & U_SCALE)                     MSG_WriteByte(&buf, s->scale);
136                         if (bits & U_EFFECTS2)          MSG_WriteByte(&buf, s->effects >> 8);
137                         if (bits & U_GLOWSIZE)          MSG_WriteByte(&buf, s->glowsize);
138                         if (bits & U_GLOWCOLOR)         MSG_WriteByte(&buf, s->glowcolor);
139                         if (bits & U_COLORMOD)          {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[1] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[2] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);}
140                         if (bits & U_FRAME2)            MSG_WriteByte(&buf, s->frame >> 8);
141                         if (bits & U_MODEL2)            MSG_WriteByte(&buf, s->modelindex >> 8);
142
143                         // the nasty protocol
144                         if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE)
145                         {
146                                 if (s->effects & EF_FULLBRIGHT)
147                                 {
148                                         MSG_WriteFloat(&buf, 2); // QSG protocol version
149                                         MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
150                                         MSG_WriteFloat(&buf, 1); // fullbright
151                                 }
152                                 else
153                                 {
154                                         MSG_WriteFloat(&buf, 1); // QSG protocol version
155                                         MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
156                                 }
157                         }
158
159                         // if the commit is full, we're done this frame
160                         if (msg->cursize + buf.cursize > maxsize)
161                         {
162                                 // next frame we will continue where we left off
163                                 break;
164                         }
165                         // write the message to the packet
166                         SZ_Write(msg, buf.data, buf.cursize);
167                         success = true;
168                         ENTITYSIZEPROFILING_END(msg, s->number, bits);
169                 }
170         }
171         return success;
172 }