]> git.xonotic.org Git - xonotic/darkplaces.git/blob - sv_ents_nq.c
Added NOSTREAM 1 tag for ogg files
[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                 if (baseline.solid != s->solid)
88                         bits |= U_SOLID;
89
90                 // if extensions are disabled, clear the relevant update flags
91                 if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_NEHAHRAMOVIE)
92                         bits &= 0x7FFF;
93                 if (sv.protocol == PROTOCOL_NEHAHRAMOVIE)
94                         if (s->alpha != 255 || s->effects & EF_FULLBRIGHT)
95                                 bits |= U_EXTEND1;
96
97                 // write the message
98                 if (bits >= 16777216)
99                         bits |= U_EXTEND2;
100                 if (bits >= 65536)
101                         bits |= U_EXTEND1;
102                 if (bits >= 256)
103                         bits |= U_MOREBITS;
104                 bits |= U_SIGNAL;
105
106                 {
107                         ENTITYSIZEPROFILING_START(msg, states[i]->number, bits);
108
109                         MSG_WriteByte (&buf, bits);
110                         if (bits & U_MOREBITS)          MSG_WriteByte(&buf, bits>>8);
111                         if (sv.protocol != PROTOCOL_NEHAHRAMOVIE)
112                         {
113                                 if (bits & U_EXTEND1)   MSG_WriteByte(&buf, bits>>16);
114                                 if (bits & U_EXTEND2)   MSG_WriteByte(&buf, bits>>24);
115                         }
116                         if (bits & U_LONGENTITY)        MSG_WriteShort(&buf, s->number);
117                         else                                            MSG_WriteByte(&buf, s->number);
118
119                         if (bits & U_MODEL)
120                         {
121                                 if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
122                                         MSG_WriteShort(&buf, s->modelindex);
123                                 else
124                                         MSG_WriteByte(&buf, s->modelindex);
125                         }
126                         if (bits & U_FRAME)                     MSG_WriteByte(&buf, s->frame);
127                         if (bits & U_COLORMAP)          MSG_WriteByte(&buf, s->colormap);
128                         if (bits & U_SKIN)                      MSG_WriteByte(&buf, s->skin);
129                         if (bits & U_EFFECTS)           MSG_WriteByte(&buf, s->effects);
130                         if (bits & U_ORIGIN1)           MSG_WriteCoord(&buf, s->origin[0], sv.protocol);
131                         if (bits & U_ANGLE1)            MSG_WriteAngle(&buf, s->angles[0], sv.protocol);
132                         if (bits & U_ORIGIN2)           MSG_WriteCoord(&buf, s->origin[1], sv.protocol);
133                         if (bits & U_ANGLE2)            MSG_WriteAngle(&buf, s->angles[1], sv.protocol);
134                         if (bits & U_ORIGIN3)           MSG_WriteCoord(&buf, s->origin[2], sv.protocol);
135                         if (bits & U_ANGLE3)            MSG_WriteAngle(&buf, s->angles[2], sv.protocol);
136                         if (bits & U_ALPHA)                     MSG_WriteByte(&buf, s->alpha);
137                         if (bits & U_SCALE)                     MSG_WriteByte(&buf, s->scale);
138                         if (bits & U_EFFECTS2)          MSG_WriteByte(&buf, s->effects >> 8);
139                         if (bits & U_GLOWSIZE)          MSG_WriteByte(&buf, s->glowsize);
140                         if (bits & U_GLOWCOLOR)         MSG_WriteByte(&buf, s->glowcolor);
141                         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);}
142                         if (bits & U_FRAME2)            MSG_WriteByte(&buf, s->frame >> 8);
143                         if (bits & U_MODEL2)            MSG_WriteByte(&buf, s->modelindex >> 8);
144                         if (bits & U_SOLID)                     MSG_WriteByte(&buf, s->solid);
145                         
146                         // the nasty protocol
147                         if ((bits & U_EXTEND1) && sv.protocol == PROTOCOL_NEHAHRAMOVIE)
148                         {
149                                 if (s->effects & EF_FULLBRIGHT)
150                                 {
151                                         MSG_WriteFloat(&buf, 2); // QSG protocol version
152                                         MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
153                                         MSG_WriteFloat(&buf, 1); // fullbright
154                                 }
155                                 else
156                                 {
157                                         MSG_WriteFloat(&buf, 1); // QSG protocol version
158                                         MSG_WriteFloat(&buf, s->alpha <= 0 ? 0 : (s->alpha >= 255 ? 1 : s->alpha * (1.0f / 255.0f))); // alpha
159                                 }
160                         }
161
162                         // if the commit is full, we're done this frame
163                         if (msg->cursize + buf.cursize > maxsize)
164                         {
165                                 // next frame we will continue where we left off
166                                 break;
167                         }
168                         // write the message to the packet
169                         SZ_Write(msg, buf.data, buf.cursize);
170                         success = true;
171                         ENTITYSIZEPROFILING_END(msg, s->number, bits);
172                 }
173         }
174         return success;
175 }