1 /*
2 bi_msgbuf.c
3
4 CSQC message buffer builtins
5
6 Copyright (C) 2012 Bill Currie <bill:taniwha.org>
7
8 Author: Bill Currie <bill:taniwha.org>
9 Date: 2012/2/6
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20 See the GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to:
24
25 Free Software Foundation, Inc.
26 59 Temple Place - Suite 330
27 Boston, MA 02111-1307, USA
28
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdlib.h>
35 #ifdef HAVE_STRING_H
36 # include <string.h>
37 #endif
38 #ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 #endif
41
42 #include "QF/msg.h"
43 #include "QF/progs.h"
44
45 #include "rua_internal.h"
46
47 typedef struct msgbuf_s {
48 struct msgbuf_s *next;
49 struct msgbuf_s **prev;
50 qmsg_t msg;
51 sizebuf_t sizebuf;
52 } msgbuf_t;
53
54 typedef struct {
55 PR_RESMAP (msgbuf_t) msgbuf_map;
56 } msgbuf_resources_t;
57
58 static msgbuf_t *
msgbuf_new(msgbuf_resources_t * res)59 msgbuf_new (msgbuf_resources_t *res)
60 {
61 PR_RESNEW (msgbuf_t, res->msgbuf_map);
62 }
63
64 static void
msgbuf_free(progs_t * pr,msgbuf_resources_t * res,msgbuf_t * msgbuf)65 msgbuf_free (progs_t *pr, msgbuf_resources_t *res, msgbuf_t *msgbuf)
66 {
67 PR_Zone_Free (pr, msgbuf->sizebuf.data);
68 PR_RESFREE (msgbuf_t, res->msgbuf_map, msgbuf);
69 }
70
71 static void
msgbuf_reset(msgbuf_resources_t * res)72 msgbuf_reset (msgbuf_resources_t *res)
73 {
74 PR_RESRESET (msgbuf_t, res->msgbuf_map);
75 }
76
77 static inline msgbuf_t *
msgbuf_get(msgbuf_resources_t * res,int index)78 msgbuf_get (msgbuf_resources_t *res, int index)
79 {
80 PR_RESGET(res->msgbuf_map, index);
81 }
82
83 static inline int
msgbuf_index(msgbuf_resources_t * res,msgbuf_t * msgbuf)84 msgbuf_index (msgbuf_resources_t *res, msgbuf_t *msgbuf)
85 {
86 PR_RESINDEX(res->msgbuf_map, msgbuf);
87 }
88
89 static void
bi_msgbuf_clear(progs_t * pr,void * data)90 bi_msgbuf_clear (progs_t *pr, void *data)
91 {
92 msgbuf_resources_t *res = (msgbuf_resources_t *) data;
93
94 msgbuf_reset (res);
95 }
96
97 static int
alloc_msgbuf(msgbuf_resources_t * res,byte * buf,int size)98 alloc_msgbuf (msgbuf_resources_t *res, byte *buf, int size)
99 {
100 msgbuf_t *msgbuf = msgbuf_new (res);
101
102 if (!msgbuf)
103 return 0;
104
105 memset (&msgbuf->msg, 0, sizeof (msgbuf->msg));
106 msgbuf->msg.message = &msgbuf->sizebuf;
107 memset (&msgbuf->sizebuf, 0, sizeof (msgbuf->sizebuf));
108 msgbuf->sizebuf.data = buf;
109 msgbuf->sizebuf.maxsize = size;
110 return msgbuf_index (res, msgbuf);
111 }
112
113 static msgbuf_t *
get_msgbuf(progs_t * pr,const char * name,int msgbuf)114 get_msgbuf (progs_t *pr, const char *name, int msgbuf)
115 {
116 msgbuf_resources_t *res = PR_Resources_Find (pr, "MsgBuf");
117 msgbuf_t *mb = msgbuf_get (res, msgbuf);
118
119 if (!mb)
120 PR_RunError (pr, "invalid msgbuf handle passed to %s", name + 3);
121 return mb;
122 }
123
124 static void
bi_MsgBuf_New(progs_t * pr)125 bi_MsgBuf_New (progs_t *pr)
126 {
127 msgbuf_resources_t *res = PR_Resources_Find (pr, "MsgBuf");
128 int size = P_INT (pr, 0);
129 byte *buf;
130
131 buf = PR_Zone_Malloc (pr, size);
132 R_INT (pr) = alloc_msgbuf (res, buf, size);
133 }
134
135 static void
bi_MsgBuf_Delete(progs_t * pr)136 bi_MsgBuf_Delete (progs_t *pr)
137 {
138 msgbuf_resources_t *res = PR_Resources_Find (pr, "MsgBuf");
139 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
140 msgbuf_free (pr, res, mb);
141 }
142
143 static void
bi_MsgBuf_FromFile(progs_t * pr)144 bi_MsgBuf_FromFile (progs_t *pr)
145 {
146 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
147 QFile *file = QFile_GetFile (pr, P_INT (pr, 1));
148 int bytes;
149
150 SZ_Clear (&mb->sizebuf);
151 bytes = Qread (file, mb->sizebuf.data, mb->sizebuf.maxsize);
152 mb->sizebuf.cursize = bytes;
153 MSG_BeginReading (&mb->msg);
154 }
155
156 static void
bi_MsgBuf_MaxSize(progs_t * pr)157 bi_MsgBuf_MaxSize (progs_t *pr)
158 {
159 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
160 R_INT (pr) = mb->sizebuf.maxsize;
161 }
162
163 static void
bi_MsgBuf_CurSize(progs_t * pr)164 bi_MsgBuf_CurSize (progs_t *pr)
165 {
166 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
167 R_INT (pr) = mb->sizebuf.cursize;
168 }
169
170 static void
bi_MsgBuf_ReadCount(progs_t * pr)171 bi_MsgBuf_ReadCount (progs_t *pr)
172 {
173 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
174 R_INT (pr) = mb->msg.readcount;
175 }
176
177 static void
bi_MsgBuf_DataPtr(progs_t * pr)178 bi_MsgBuf_DataPtr (progs_t *pr)
179 {
180 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
181 byte *ptr = mb->sizebuf.data + mb->msg.readcount;
182 R_INT (pr) = ptr - (byte *) pr->pr_strings;
183 }
184
185 static void
bi_MsgBuf_Clear(progs_t * pr)186 bi_MsgBuf_Clear (progs_t *pr)
187 {
188 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
189 SZ_Clear (&mb->sizebuf);
190 }
191
192 static void
bi_MsgBuf_WriteByte(progs_t * pr)193 bi_MsgBuf_WriteByte (progs_t *pr)
194 {
195 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
196 MSG_WriteByte (&mb->sizebuf, P_INT (pr, 1));
197 }
198
199 static void
bi_MsgBuf_WriteShort(progs_t * pr)200 bi_MsgBuf_WriteShort (progs_t *pr)
201 {
202 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
203 MSG_WriteShort (&mb->sizebuf, P_INT (pr, 1));
204 }
205
206 static void
bi_MsgBuf_WriteLong(progs_t * pr)207 bi_MsgBuf_WriteLong (progs_t *pr)
208 {
209 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
210 MSG_WriteLong (&mb->sizebuf, P_INT (pr, 1));
211 }
212
213 static void
bi_MsgBuf_WriteFloat(progs_t * pr)214 bi_MsgBuf_WriteFloat (progs_t *pr)
215 {
216 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
217 MSG_WriteFloat (&mb->sizebuf, P_FLOAT (pr, 1));
218 }
219
220 static void
bi_MsgBuf_WriteString(progs_t * pr)221 bi_MsgBuf_WriteString (progs_t *pr)
222 {
223 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
224 MSG_WriteString (&mb->sizebuf, P_GSTRING (pr, 1));
225 }
226 #if 0
227 static void
228 bi_MsgBuf_WriteBytes (progs_t *pr)
229 {
230 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
231 MSG_WriteBytes (&mb->sizebuf, P_INT (pr, 1));
232 }
233 #endif
234 static void
bi_MsgBuf_WriteCoord(progs_t * pr)235 bi_MsgBuf_WriteCoord (progs_t *pr)
236 {
237 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
238 MSG_WriteCoord (&mb->sizebuf, P_FLOAT (pr, 1));
239 }
240
241 static void
bi_MsgBuf_WriteCoordV(progs_t * pr)242 bi_MsgBuf_WriteCoordV (progs_t *pr)
243 {
244 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
245 MSG_WriteCoordV (&mb->sizebuf, P_VECTOR (pr, 1));
246 }
247
248 static void
bi_MsgBuf_WriteCoordAngleV(progs_t * pr)249 bi_MsgBuf_WriteCoordAngleV (progs_t *pr)
250 {
251 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
252 MSG_WriteCoordAngleV (&mb->sizebuf,
253 P_VECTOR (pr, 1), P_VECTOR (pr, 2));
254 }
255
256 static void
bi_MsgBuf_WriteAngle(progs_t * pr)257 bi_MsgBuf_WriteAngle (progs_t *pr)
258 {
259 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
260 MSG_WriteAngle (&mb->sizebuf, P_FLOAT (pr, 1));
261 }
262
263 static void
bi_MsgBuf_WriteAngleV(progs_t * pr)264 bi_MsgBuf_WriteAngleV (progs_t *pr)
265 {
266 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
267 MSG_WriteAngleV (&mb->sizebuf, P_VECTOR (pr, 1));
268 }
269
270 static void
bi_MsgBuf_WriteAngle16(progs_t * pr)271 bi_MsgBuf_WriteAngle16 (progs_t *pr)
272 {
273 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
274 MSG_WriteAngle16 (&mb->sizebuf, P_FLOAT (pr, 1));
275 }
276
277 static void
bi_MsgBuf_WriteAngle16V(progs_t * pr)278 bi_MsgBuf_WriteAngle16V (progs_t *pr)
279 {
280 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
281 MSG_WriteAngle16V (&mb->sizebuf, P_VECTOR (pr, 1));
282 }
283
284 static void
bi_MsgBuf_WriteUTF8(progs_t * pr)285 bi_MsgBuf_WriteUTF8 (progs_t *pr)
286 {
287 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
288 MSG_WriteUTF8 (&mb->sizebuf, P_INT (pr, 1));
289 }
290
291 static void
bi_MsgBuf_BeginReading(progs_t * pr)292 bi_MsgBuf_BeginReading (progs_t *pr)
293 {
294 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
295 MSG_BeginReading (&mb->msg);
296 }
297
298 static void
bi_MsgBuf_ReadByte(progs_t * pr)299 bi_MsgBuf_ReadByte (progs_t *pr)
300 {
301 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
302 R_INT (pr) = MSG_ReadByte (&mb->msg);
303 }
304
305 static void
bi_MsgBuf_ReadShort(progs_t * pr)306 bi_MsgBuf_ReadShort (progs_t *pr)
307 {
308 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
309 R_INT (pr) = MSG_ReadShort (&mb->msg);
310 }
311
312 static void
bi_MsgBuf_ReadLong(progs_t * pr)313 bi_MsgBuf_ReadLong (progs_t *pr)
314 {
315 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
316 R_INT (pr) = MSG_ReadLong (&mb->msg);
317 }
318
319 static void
bi_MsgBuf_ReadFloat(progs_t * pr)320 bi_MsgBuf_ReadFloat (progs_t *pr)
321 {
322 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
323 R_FLOAT (pr) = MSG_ReadFloat (&mb->msg);
324 }
325
326 static void
bi_MsgBuf_ReadString(progs_t * pr)327 bi_MsgBuf_ReadString (progs_t *pr)
328 {
329 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
330 const char *str;
331
332 str = MSG_ReadString (&mb->msg);
333 RETURN_STRING (pr, str);
334 }
335 #if 0
336 static void
337 bi_MsgBuf_ReadBytes (progs_t *pr)
338 {
339 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
340 MSG_ReadBytes (&mb->msg);
341 }
342 #endif
343 static void
bi_MsgBuf_ReadCoord(progs_t * pr)344 bi_MsgBuf_ReadCoord (progs_t *pr)
345 {
346 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
347 R_FLOAT (pr) = MSG_ReadCoord (&mb->msg);
348 }
349
350 static void
bi_MsgBuf_ReadCoordV(progs_t * pr)351 bi_MsgBuf_ReadCoordV (progs_t *pr)
352 {
353 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
354 MSG_ReadCoordV (&mb->msg, R_VECTOR (pr));
355 }
356
357 static void
bi_MsgBuf_ReadCoordAngleV(progs_t * pr)358 bi_MsgBuf_ReadCoordAngleV (progs_t *pr)
359 {
360 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
361 MSG_ReadCoordAngleV (&mb->msg, P_GPOINTER (pr, 1)->vector_var,
362 P_GPOINTER (pr, 2)->vector_var);
363 }
364
365 static void
bi_MsgBuf_ReadAngle(progs_t * pr)366 bi_MsgBuf_ReadAngle (progs_t *pr)
367 {
368 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
369 R_FLOAT (pr) = MSG_ReadAngle (&mb->msg);
370 }
371
372 static void
bi_MsgBuf_ReadAngleV(progs_t * pr)373 bi_MsgBuf_ReadAngleV (progs_t *pr)
374 {
375 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
376 MSG_ReadAngleV (&mb->msg, R_VECTOR (pr));
377 }
378
379 static void
bi_MsgBuf_ReadAngle16(progs_t * pr)380 bi_MsgBuf_ReadAngle16 (progs_t *pr)
381 {
382 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
383 R_FLOAT (pr) = MSG_ReadAngle16 (&mb->msg);
384 }
385
386 static void
bi_MsgBuf_ReadAngle16V(progs_t * pr)387 bi_MsgBuf_ReadAngle16V (progs_t *pr)
388 {
389 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
390 MSG_ReadAngle16V (&mb->msg, R_VECTOR (pr));
391 }
392
393 static void
bi_MsgBuf_ReadUTF8(progs_t * pr)394 bi_MsgBuf_ReadUTF8 (progs_t *pr)
395 {
396 msgbuf_t *mb = get_msgbuf (pr, __FUNCTION__, P_INT (pr, 0));
397 R_INT (pr) = MSG_ReadUTF8 (&mb->msg);
398 }
399
400 static builtin_t builtins[] = {
401 {"MsgBuf_New", bi_MsgBuf_New, -1},
402 {"MsgBuf_Delete", bi_MsgBuf_Delete, -1},
403 {"MsgBuf_FromFile", bi_MsgBuf_FromFile, -1},
404 {"MsgBuf_MaxSize", bi_MsgBuf_MaxSize, -1},
405 {"MsgBuf_CurSize", bi_MsgBuf_CurSize, -1},
406 {"MsgBuf_ReadCount", bi_MsgBuf_ReadCount, -1},
407 {"MsgBuf_DataPtr", bi_MsgBuf_DataPtr, -1},
408
409 {"MsgBuf_Clear", bi_MsgBuf_Clear, -1},
410 {"MsgBuf_WriteByte", bi_MsgBuf_WriteByte, -1},
411 {"MsgBuf_WriteShort", bi_MsgBuf_WriteShort, -1},
412 {"MsgBuf_WriteLong", bi_MsgBuf_WriteLong, -1},
413 {"MsgBuf_WriteFloat", bi_MsgBuf_WriteFloat, -1},
414 {"MsgBuf_WriteString", bi_MsgBuf_WriteString, -1},
415 // {"MsgBuf_WriteBytes", bi_MsgBuf_WriteBytes, -1},
416 {"MsgBuf_WriteCoord", bi_MsgBuf_WriteCoord, -1},
417 {"MsgBuf_WriteCoordV", bi_MsgBuf_WriteCoordV, -1},
418 {"MsgBuf_WriteCoordAngleV", bi_MsgBuf_WriteCoordAngleV, -1},
419 {"MsgBuf_WriteAngle", bi_MsgBuf_WriteAngle, -1},
420 {"MsgBuf_WriteAngleV", bi_MsgBuf_WriteAngleV, -1},
421 {"MsgBuf_WriteAngle16", bi_MsgBuf_WriteAngle16, -1},
422 {"MsgBuf_WriteAngle16V", bi_MsgBuf_WriteAngle16V, -1},
423 {"MsgBuf_WriteUTF8", bi_MsgBuf_WriteUTF8, -1},
424
425 {"MsgBuf_BeginReading", bi_MsgBuf_BeginReading, -1},
426 {"MsgBuf_ReadByte", bi_MsgBuf_ReadByte, -1},
427 {"MsgBuf_ReadShort", bi_MsgBuf_ReadShort, -1},
428 {"MsgBuf_ReadLong", bi_MsgBuf_ReadLong, -1},
429 {"MsgBuf_ReadFloat", bi_MsgBuf_ReadFloat, -1},
430 {"MsgBuf_ReadString", bi_MsgBuf_ReadString, -1},
431 // {"MsgBuf_ReadBytes", bi_MsgBuf_ReadBytes, -1},
432 {"MsgBuf_ReadCoord", bi_MsgBuf_ReadCoord, -1},
433 {"MsgBuf_ReadCoordV", bi_MsgBuf_ReadCoordV, -1},
434 {"MsgBuf_ReadCoordAngleV", bi_MsgBuf_ReadCoordAngleV, -1},
435 {"MsgBuf_ReadAngle", bi_MsgBuf_ReadAngle, -1},
436 {"MsgBuf_ReadAngleV", bi_MsgBuf_ReadAngleV, -1},
437 {"MsgBuf_ReadAngle16", bi_MsgBuf_ReadAngle16, -1},
438 {"MsgBuf_ReadAngle16V", bi_MsgBuf_ReadAngle16V, -1},
439 {"MsgBuf_ReadUTF8", bi_MsgBuf_ReadUTF8, -1},
440 {0}
441 };
442
443 void
RUA_MsgBuf_Init(progs_t * pr,int secure)444 RUA_MsgBuf_Init (progs_t *pr, int secure)
445 {
446 msgbuf_resources_t *res = calloc (sizeof (msgbuf_resources_t), 1);
447
448 PR_Resources_Register (pr, "MsgBuf", res, bi_msgbuf_clear);
449 PR_RegisterBuiltins (pr, builtins);
450 }
451