summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/pr_edict.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-02-11 15:34:30 -0500
committerFranklin Wei <git@fwei.tk>2019-07-19 22:37:40 -0400
commit5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4 (patch)
tree84406e21639529a185556a33e5de7f43cffc277b /apps/plugins/sdl/progs/quake/pr_edict.c
parentb70fecf21ddc21877ec1ae7888d9c18a979e37ad (diff)
downloadrockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.tar.gz
rockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.zip
Quake!
This ports id Software's Quake to run on the SDL plugin runtime. The source code originated from id under the GPLv2 license. I used https://github.com/ahefner/sdlquake as the base of my port. Performance is, unsurprisingly, not on par with what you're probably used to on PC. I average about 10FPS on ipod6g, but it's still playable. Sound works well enough, but in-game music is not supported. I've written ARM assembly routines for the inner sound loop. Make sure you turn the "brightness" all the way down, or colors will look funky. To run, extract Quake's data files to /.rockbox/quake. Have fun! Change-Id: I4285036e967d7f0722802d43cf2096c808ca5799
Diffstat (limited to 'apps/plugins/sdl/progs/quake/pr_edict.c')
-rw-r--r--apps/plugins/sdl/progs/quake/pr_edict.c1113
1 files changed, 1113 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/pr_edict.c b/apps/plugins/sdl/progs/quake/pr_edict.c
new file mode 100644
index 0000000000..2f0e8eccb3
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/pr_edict.c
@@ -0,0 +1,1113 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// sv_edict.c -- entity dictionary
21
22#include "quakedef.h"
23
24dprograms_t *progs;
25dfunction_t *pr_functions;
26char *pr_strings;
27ddef_t *pr_fielddefs;
28ddef_t *pr_globaldefs;
29dstatement_t *pr_statements;
30globalvars_t *pr_global_struct;
31float *pr_globals; // same as pr_global_struct
32int pr_edict_size; // in bytes
33
34unsigned short pr_crc;
35
36int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
37
38ddef_t *ED_FieldAtOfs (int ofs);
39qboolean ED_ParseEpair (void *base, ddef_t *key, char *s);
40
41cvar_t nomonsters = {"nomonsters", "0"};
42cvar_t gamecfg = {"gamecfg", "0"};
43cvar_t scratch1 = {"scratch1", "0"};
44cvar_t scratch2 = {"scratch2", "0"};
45cvar_t scratch3 = {"scratch3", "0"};
46cvar_t scratch4 = {"scratch4", "0"};
47cvar_t savedgamecfg = {"savedgamecfg", "0", true};
48cvar_t saved1 = {"saved1", "0", true};
49cvar_t saved2 = {"saved2", "0", true};
50cvar_t saved3 = {"saved3", "0", true};
51cvar_t saved4 = {"saved4", "0", true};
52
53#define MAX_FIELD_LEN 64
54#define GEFV_CACHESIZE 2
55
56typedef struct {
57 ddef_t *pcache;
58 char field[MAX_FIELD_LEN];
59} gefv_cache;
60
61static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
62
63/*
64=================
65ED_ClearEdict
66
67Sets everything to NULL
68=================
69*/
70void ED_ClearEdict (edict_t *e)
71{
72 memset (&e->v, 0, progs->entityfields * 4);
73 e->free = false;
74}
75
76/*
77=================
78ED_Alloc
79
80Either finds a free edict, or allocates a new one.
81Try to avoid reusing an entity that was recently freed, because it
82can cause the client to think the entity morphed into something else
83instead of being removed and recreated, which can cause interpolated
84angles and bad trails.
85=================
86*/
87edict_t *ED_Alloc (void)
88{
89 int i;
90 edict_t *e;
91
92 for ( i=svs.maxclients+1 ; i<sv.num_edicts ; i++)
93 {
94 e = EDICT_NUM(i);
95 // the first couple seconds of server time can involve a lot of
96 // freeing and allocating, so relax the replacement policy
97 if (e->free && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) )
98 {
99 ED_ClearEdict (e);
100 return e;
101 }
102 }
103
104 if (i == MAX_EDICTS)
105 Sys_Error ("ED_Alloc: no free edicts");
106
107 sv.num_edicts++;
108 e = EDICT_NUM(i);
109 ED_ClearEdict (e);
110
111 return e;
112}
113
114/*
115=================
116ED_Free
117
118Marks the edict as free
119FIXME: walk all entities and NULL out references to this entity
120=================
121*/
122void ED_Free (edict_t *ed)
123{
124 SV_UnlinkEdict (ed); // unlink from world bsp
125
126 ed->free = true;
127 ed->v.model = 0;
128 ed->v.takedamage = 0;
129 ed->v.modelindex = 0;
130 ed->v.colormap = 0;
131 ed->v.skin = 0;
132 ed->v.frame = 0;
133 VectorCopy (vec3_origin, ed->v.origin);
134 VectorCopy (vec3_origin, ed->v.angles);
135 ed->v.nextthink = -1;
136 ed->v.solid = 0;
137
138 ed->freetime = sv.time;
139}
140
141//===========================================================================
142
143/*
144============
145ED_GlobalAtOfs
146============
147*/
148ddef_t *ED_GlobalAtOfs (int ofs)
149{
150 ddef_t *def;
151 int i;
152
153 for (i=0 ; i<progs->numglobaldefs ; i++)
154 {
155 def = &pr_globaldefs[i];
156 if (def->ofs == ofs)
157 return def;
158 }
159 return NULL;
160}
161
162/*
163============
164ED_FieldAtOfs
165============
166*/
167ddef_t *ED_FieldAtOfs (int ofs)
168{
169 ddef_t *def;
170 int i;
171
172 for (i=0 ; i<progs->numfielddefs ; i++)
173 {
174 def = &pr_fielddefs[i];
175 if (def->ofs == ofs)
176 return def;
177 }
178 return NULL;
179}
180
181/*
182============
183ED_FindField
184============
185*/
186ddef_t *ED_FindField (char *name)
187{
188 ddef_t *def;
189 int i;
190
191 for (i=0 ; i<progs->numfielddefs ; i++)
192 {
193 def = &pr_fielddefs[i];
194 if (!strcmp(pr_strings + def->s_name,name) )
195 return def;
196 }
197 return NULL;
198}
199
200
201/*
202============
203ED_FindGlobal
204============
205*/
206ddef_t *ED_FindGlobal (char *name)
207{
208 ddef_t *def;
209 int i;
210
211 for (i=0 ; i<progs->numglobaldefs ; i++)
212 {
213 def = &pr_globaldefs[i];
214 if (!strcmp(pr_strings + def->s_name,name) )
215 return def;
216 }
217 return NULL;
218}
219
220
221/*
222============
223ED_FindFunction
224============
225*/
226dfunction_t *ED_FindFunction (char *name)
227{
228 dfunction_t *func;
229 int i;
230
231 for (i=0 ; i<progs->numfunctions ; i++)
232 {
233 func = &pr_functions[i];
234 if (!strcmp(pr_strings + func->s_name,name) )
235 return func;
236 }
237 return NULL;
238}
239
240
241eval_t *GetEdictFieldValue(edict_t *ed, char *field)
242{
243 ddef_t *def = NULL;
244 int i;
245 static int rep = 0;
246
247 for (i=0 ; i<GEFV_CACHESIZE ; i++)
248 {
249 if (!strcmp(field, gefvCache[i].field))
250 {
251 def = gefvCache[i].pcache;
252 goto Done;
253 }
254 }
255
256 def = ED_FindField (field);
257
258 if (strlen(field) < MAX_FIELD_LEN)
259 {
260 gefvCache[rep].pcache = def;
261 strcpy (gefvCache[rep].field, field);
262 rep ^= 1;
263 }
264
265Done:
266 if (!def)
267 return NULL;
268
269 return (eval_t *)((char *)&ed->v + def->ofs*4);
270}
271
272
273/*
274============
275PR_ValueString
276
277Returns a string describing *data in a type specific manner
278=============
279*/
280char *PR_ValueString (etype_t type, eval_t *val)
281{
282 static char line[256];
283 ddef_t *def;
284 dfunction_t *f;
285
286 type &= ~DEF_SAVEGLOBAL;
287
288 switch (type)
289 {
290 case ev_string:
291 sprintf (line, "%s", pr_strings + val->string);
292 break;
293 case ev_entity:
294 sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
295 break;
296 case ev_function:
297 f = pr_functions + val->function;
298 sprintf (line, "%s()", pr_strings + f->s_name);
299 break;
300 case ev_field:
301 def = ED_FieldAtOfs ( val->_int );
302 sprintf (line, ".%s", pr_strings + def->s_name);
303 break;
304 case ev_void:
305 sprintf (line, "void");
306 break;
307 case ev_float:
308 sprintf (line, "%5.1f", val->_float);
309 break;
310 case ev_vector:
311 sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
312 break;
313 case ev_pointer:
314 sprintf (line, "pointer");
315 break;
316 default:
317 sprintf (line, "bad type %i", type);
318 break;
319 }
320
321 return line;
322}
323
324/*
325============
326PR_UglyValueString
327
328Returns a string describing *data in a type specific manner
329Easier to parse than PR_ValueString
330=============
331*/
332char *PR_UglyValueString (etype_t type, eval_t *val)
333{
334 static char line[256];
335 ddef_t *def;
336 dfunction_t *f;
337
338 type &= ~DEF_SAVEGLOBAL;
339
340 switch (type)
341 {
342 case ev_string:
343 sprintf (line, "%s", pr_strings + val->string);
344 break;
345 case ev_entity:
346 sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
347 break;
348 case ev_function:
349 f = pr_functions + val->function;
350 sprintf (line, "%s", pr_strings + f->s_name);
351 break;
352 case ev_field:
353 def = ED_FieldAtOfs ( val->_int );
354 sprintf (line, "%s", pr_strings + def->s_name);
355 break;
356 case ev_void:
357 sprintf (line, "void");
358 break;
359 case ev_float:
360 sprintf (line, "%f", val->_float);
361 break;
362 case ev_vector:
363 sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
364 break;
365 default:
366 sprintf (line, "bad type %i", type);
367 break;
368 }
369
370 return line;
371}
372
373/*
374============
375PR_GlobalString
376
377Returns a string with a description and the contents of a global,
378padded to 20 field width
379============
380*/
381char *PR_GlobalString (int ofs)
382{
383 char *s;
384 int i;
385 ddef_t *def;
386 void *val;
387 static char line[128];
388
389 val = (void *)&pr_globals[ofs];
390 def = ED_GlobalAtOfs(ofs);
391 if (!def)
392 sprintf (line,"%i(???)", ofs);
393 else
394 {
395 s = PR_ValueString (def->type, val);
396 sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
397 }
398
399 i = strlen(line);
400 for ( ; i<20 ; i++)
401 strcat (line," ");
402 strcat (line," ");
403
404 return line;
405}
406
407char *PR_GlobalStringNoContents (int ofs)
408{
409 int i;
410 ddef_t *def;
411 static char line[128];
412
413 def = ED_GlobalAtOfs(ofs);
414 if (!def)
415 sprintf (line,"%i(???)", ofs);
416 else
417 sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
418
419 i = strlen(line);
420 for ( ; i<20 ; i++)
421 strcat (line," ");
422 strcat (line," ");
423
424 return line;
425}
426
427
428/*
429=============
430ED_Print
431
432For debugging
433=============
434*/
435void ED_Print (edict_t *ed)
436{
437 int l;
438 ddef_t *d;
439 int *v;
440 int i, j;
441 char *name;
442 int type;
443
444 if (ed->free)
445 {
446 Con_Printf ("FREE\n");
447 return;
448 }
449
450 Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed));
451 for (i=1 ; i<progs->numfielddefs ; i++)
452 {
453 d = &pr_fielddefs[i];
454 name = pr_strings + d->s_name;
455 if (name[strlen(name)-2] == '_')
456 continue; // skip _x, _y, _z vars
457
458 v = (int *)((char *)&ed->v + d->ofs*4);
459
460 // if the value is still all 0, skip the field
461 type = d->type & ~DEF_SAVEGLOBAL;
462
463 for (j=0 ; j<type_size[type] ; j++)
464 if (v[j])
465 break;
466 if (j == type_size[type])
467 continue;
468
469 Con_Printf ("%s",name);
470 l = strlen (name);
471 while (l++ < 15)
472 Con_Printf (" ");
473
474 Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v));
475 }
476}
477
478/*
479=============
480ED_Write
481
482For savegames
483=============
484*/
485void ED_Write (FILE *f, edict_t *ed)
486{
487 ddef_t *d;
488 int *v;
489 int i, j;
490 char *name;
491 int type;
492
493 fprintf (f, "{\n");
494
495 if (ed->free)
496 {
497 fprintf (f, "}\n");
498 return;
499 }
500
501 for (i=1 ; i<progs->numfielddefs ; i++)
502 {
503 d = &pr_fielddefs[i];
504 name = pr_strings + d->s_name;
505 if (name[strlen(name)-2] == '_')
506 continue; // skip _x, _y, _z vars
507
508 v = (int *)((char *)&ed->v + d->ofs*4);
509
510 // if the value is still all 0, skip the field
511 type = d->type & ~DEF_SAVEGLOBAL;
512 for (j=0 ; j<type_size[type] ; j++)
513 if (v[j])
514 break;
515 if (j == type_size[type])
516 continue;
517
518 fprintf (f,"\"%s\" ",name);
519 fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
520 }
521
522 fprintf (f, "}\n");
523}
524
525void ED_PrintNum (int ent)
526{
527 ED_Print (EDICT_NUM(ent));
528}
529
530/*
531=============
532ED_PrintEdicts
533
534For debugging, prints all the entities in the current server
535=============
536*/
537void ED_PrintEdicts (void)
538{
539 int i;
540
541 Con_Printf ("%i entities\n", sv.num_edicts);
542 for (i=0 ; i<sv.num_edicts ; i++)
543 ED_PrintNum (i);
544}
545
546/*
547=============
548ED_PrintEdict_f
549
550For debugging, prints a single edicy
551=============
552*/
553void ED_PrintEdict_f (void)
554{
555 int i;
556
557 i = Q_atoi (Cmd_Argv(1));
558 if (i >= sv.num_edicts)
559 {
560 Con_Printf("Bad edict number\n");
561 return;
562 }
563 ED_PrintNum (i);
564}
565
566/*
567=============
568ED_Count
569
570For debugging
571=============
572*/
573void ED_Count (void)
574{
575 int i;
576 edict_t *ent;
577 int active, models, solid, step;
578
579 active = models = solid = step = 0;
580 for (i=0 ; i<sv.num_edicts ; i++)
581 {
582 ent = EDICT_NUM(i);
583 if (ent->free)
584 continue;
585 active++;
586 if (ent->v.solid)
587 solid++;
588 if (ent->v.model)
589 models++;
590 if (ent->v.movetype == MOVETYPE_STEP)
591 step++;
592 }
593
594 Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
595 Con_Printf ("active :%3i\n", active);
596 Con_Printf ("view :%3i\n", models);
597 Con_Printf ("touch :%3i\n", solid);
598 Con_Printf ("step :%3i\n", step);
599
600}
601
602/*
603==============================================================================
604
605 ARCHIVING GLOBALS
606
607FIXME: need to tag constants, doesn't really work
608==============================================================================
609*/
610
611/*
612=============
613ED_WriteGlobals
614=============
615*/
616void ED_WriteGlobals (FILE *f)
617{
618 ddef_t *def;
619 int i;
620 char *name;
621 int type;
622
623 fprintf (f,"{\n");
624 for (i=0 ; i<progs->numglobaldefs ; i++)
625 {
626 def = &pr_globaldefs[i];
627 type = def->type;
628 if ( !(def->type & DEF_SAVEGLOBAL) )
629 continue;
630 type &= ~DEF_SAVEGLOBAL;
631
632 if (type != ev_string
633 && type != ev_float
634 && type != ev_entity)
635 continue;
636
637 name = pr_strings + def->s_name;
638 fprintf (f,"\"%s\" ", name);
639 fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
640 }
641 fprintf (f,"}\n");
642}
643
644/*
645=============
646ED_ParseGlobals
647=============
648*/
649void ED_ParseGlobals (char *data)
650{
651 char keyname[64];
652 ddef_t *key;
653
654 while (1)
655 {
656 // parse key
657 data = COM_Parse (data);
658 if (com_token[0] == '}')
659 break;
660 if (!data)
661 Sys_Error ("ED_ParseEntity: EOF without closing brace");
662
663 strcpy (keyname, com_token);
664
665 // parse value
666 data = COM_Parse (data);
667 if (!data)
668 Sys_Error ("ED_ParseEntity: EOF without closing brace");
669
670 if (com_token[0] == '}')
671 Sys_Error ("ED_ParseEntity: closing brace without data");
672
673 key = ED_FindGlobal (keyname);
674 if (!key)
675 {
676 Con_Printf ("'%s' is not a global\n", keyname);
677 continue;
678 }
679
680 if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
681 Host_Error ("ED_ParseGlobals: parse error");
682 }
683}
684
685//============================================================================
686
687
688/*
689=============
690ED_NewString
691=============
692*/
693char *ED_NewString (char *string)
694{
695 char *new, *new_p;
696 int i,l;
697
698 l = strlen(string) + 1;
699 new = Hunk_Alloc (l);
700 new_p = new;
701
702 for (i=0 ; i< l ; i++)
703 {
704 if (string[i] == '\\' && i < l-1)
705 {
706 i++;
707 if (string[i] == 'n')
708 *new_p++ = '\n';
709 else
710 *new_p++ = '\\';
711 }
712 else
713 *new_p++ = string[i];
714 }
715
716 return new;
717}
718
719
720/*
721=============
722ED_ParseEval
723
724Can parse either fields or globals
725returns false if error
726=============
727*/
728qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
729{
730 int i;
731 char string[128];
732 ddef_t *def;
733 char *v, *w;
734 void *d;
735 dfunction_t *func;
736
737 d = (void *)((int *)base + key->ofs);
738
739 switch (key->type & ~DEF_SAVEGLOBAL)
740 {
741 case ev_string:
742 *(string_t *)d = ED_NewString (s) - pr_strings;
743 break;
744
745 case ev_float:
746 *(float *)d = Q_atof (s);
747 break;
748
749 case ev_vector:
750 strcpy (string, s);
751 v = string;
752 w = string;
753 for (i=0 ; i<3 ; i++)
754 {
755 while (*v && *v != ' ')
756 v++;
757 *v = 0;
758 ((float *)d)[i] = Q_atof (w);
759 w = v = v+1;
760 }
761 break;
762
763 case ev_entity:
764 *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
765 break;
766
767 case ev_field:
768 def = ED_FindField (s);
769 if (!def)
770 {
771 Con_Printf ("Can't find field %s\n", s);
772 return false;
773 }
774 *(int *)d = G_INT(def->ofs);
775 break;
776
777 case ev_function:
778 func = ED_FindFunction (s);
779 if (!func)
780 {
781 Con_Printf ("Can't find function %s\n", s);
782 return false;
783 }
784 *(func_t *)d = func - pr_functions;
785 break;
786
787 default:
788 break;
789 }
790 return true;
791}
792
793/*
794====================
795ED_ParseEdict
796
797Parses an edict out of the given string, returning the new position
798ed should be a properly initialized empty edict.
799Used for initial level load and for savegames.
800====================
801*/
802char *ED_ParseEdict (char *data, edict_t *ent)
803{
804 ddef_t *key;
805 qboolean anglehack;
806 qboolean init;
807 char keyname[256];
808 int n;
809
810 init = false;
811
812// clear it
813 if (ent != sv.edicts) // hack
814 memset (&ent->v, 0, progs->entityfields * 4);
815
816// go through all the dictionary pairs
817 while (1)
818 {
819 // parse key
820 data = COM_Parse (data);
821 if (com_token[0] == '}')
822 break;
823 if (!data)
824 Sys_Error ("ED_ParseEntity: EOF without closing brace");
825
826// anglehack is to allow QuakeEd to write single scalar angles
827// and allow them to be turned into vectors. (FIXME...)
828if (!strcmp(com_token, "angle"))
829{
830 strcpy (com_token, "angles");
831 anglehack = true;
832}
833else
834 anglehack = false;
835
836// FIXME: change light to _light to get rid of this hack
837if (!strcmp(com_token, "light"))
838 strcpy (com_token, "light_lev"); // hack for single light def
839
840 strcpy (keyname, com_token);
841
842 // another hack to fix heynames with trailing spaces
843 n = strlen(keyname);
844 while (n && keyname[n-1] == ' ')
845 {
846 keyname[n-1] = 0;
847 n--;
848 }
849
850 // parse value
851 data = COM_Parse (data);
852 if (!data)
853 Sys_Error ("ED_ParseEntity: EOF without closing brace");
854
855 if (com_token[0] == '}')
856 Sys_Error ("ED_ParseEntity: closing brace without data");
857
858 init = true;
859
860// keynames with a leading underscore are used for utility comments,
861// and are immediately discarded by quake
862 if (keyname[0] == '_')
863 continue;
864
865 key = ED_FindField (keyname);
866 if (!key)
867 {
868 Con_Printf ("'%s' is not a field\n", keyname);
869 continue;
870 }
871
872if (anglehack)
873{
874char temp[32];
875strcpy (temp, com_token);
876sprintf (com_token, "0 %s 0", temp);
877}
878
879 if (!ED_ParseEpair ((void *)&ent->v, key, com_token))
880 Host_Error ("ED_ParseEdict: parse error");
881 }
882
883 if (!init)
884 ent->free = true;
885
886 return data;
887}
888
889
890/*
891================
892ED_LoadFromFile
893
894The entities are directly placed in the array, rather than allocated with
895ED_Alloc, because otherwise an error loading the map would have entity
896number references out of order.
897
898Creates a server's entity / program execution context by
899parsing textual entity definitions out of an ent file.
900
901Used for both fresh maps and savegame loads. A fresh map would also need
902to call ED_CallSpawnFunctions () to let the objects initialize themselves.
903================
904*/
905void ED_LoadFromFile (char *data)
906{
907 edict_t *ent;
908 int inhibit;
909 dfunction_t *func;
910
911 ent = NULL;
912 inhibit = 0;
913 pr_global_struct->time = sv.time;
914
915// parse ents
916 while (1)
917 {
918// parse the opening brace
919 data = COM_Parse (data);
920 if (!data)
921 break;
922 if (com_token[0] != '{')
923 Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
924
925 if (!ent)
926 ent = EDICT_NUM(0);
927 else
928 ent = ED_Alloc ();
929 data = ED_ParseEdict (data, ent);
930
931// remove things from different skill levels or deathmatch
932 if (deathmatch.value)
933 {
934 if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
935 {
936 ED_Free (ent);
937 inhibit++;
938 continue;
939 }
940 }
941 else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
942 || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
943 || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
944 {
945 ED_Free (ent);
946 inhibit++;
947 continue;
948 }
949
950//
951// immediately call spawn function
952//
953 if (!ent->v.classname)
954 {
955 Con_Printf ("No classname for:\n");
956 ED_Print (ent);
957 ED_Free (ent);
958 continue;
959 }
960
961 // look for the spawn function
962 func = ED_FindFunction ( pr_strings + ent->v.classname );
963
964 if (!func)
965 {
966 Con_Printf ("No spawn function for:\n");
967 ED_Print (ent);
968 ED_Free (ent);
969 continue;
970 }
971
972 pr_global_struct->self = EDICT_TO_PROG(ent);
973 PR_ExecuteProgram (func - pr_functions);
974 }
975
976 Con_DPrintf ("%i entities inhibited\n", inhibit);
977}
978
979
980/*
981===============
982PR_LoadProgs
983===============
984*/
985void PR_LoadProgs (void)
986{
987 int i;
988
989// flush the non-C variable lookup cache
990 for (i=0 ; i<GEFV_CACHESIZE ; i++)
991 gefvCache[i].field[0] = 0;
992
993 CRC_Init (&pr_crc);
994
995 //printf("loadprogs 1");
996
997 progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
998 //printf("loadprogs 2");
999
1000 if (!progs)
1001 Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
1002 Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
1003 //printf("loadprogs 3");
1004
1005 for (i=0 ; i<com_filesize ; i++)
1006 CRC_ProcessByte (&pr_crc, ((byte *)progs)[i]);
1007
1008 //printf("loadprogs 4");
1009// byte swap the header
1010 for (i=0 ; i<sizeof(*progs)/4 ; i++)
1011 ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
1012
1013 if (progs->version != PROG_VERSION)
1014 Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
1015 if (progs->crc != PROGHEADER_CRC)
1016 Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
1017 //printf("loadprogs 5");
1018
1019 pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
1020 pr_strings = (char *)progs + progs->ofs_strings;
1021 pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
1022 pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
1023 pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
1024
1025 pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
1026 pr_globals = (float *)pr_global_struct;
1027
1028 pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
1029
1030// byte swap the lumps
1031 for (i=0 ; i<progs->numstatements ; i++)
1032 {
1033 pr_statements[i].op = LittleShort(pr_statements[i].op);
1034 pr_statements[i].a = LittleShort(pr_statements[i].a);
1035 pr_statements[i].b = LittleShort(pr_statements[i].b);
1036 pr_statements[i].c = LittleShort(pr_statements[i].c);
1037 }
1038
1039 for (i=0 ; i<progs->numfunctions; i++)
1040 {
1041 pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
1042 pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
1043 pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
1044 pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
1045 pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
1046 pr_functions[i].locals = LittleLong (pr_functions[i].locals);
1047 }
1048
1049 for (i=0 ; i<progs->numglobaldefs ; i++)
1050 {
1051 pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
1052 pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
1053 pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
1054 }
1055
1056 for (i=0 ; i<progs->numfielddefs ; i++)
1057 {
1058 pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
1059 if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
1060 Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
1061 pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
1062 pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
1063 }
1064
1065 for (i=0 ; i<progs->numglobals ; i++)
1066 ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
1067}
1068
1069
1070/*
1071===============
1072PR_Init
1073===============
1074*/
1075void PR_Init (void)
1076{
1077 Cmd_AddCommand ("edict", ED_PrintEdict_f);
1078 Cmd_AddCommand ("edicts", ED_PrintEdicts);
1079 Cmd_AddCommand ("edictcount", ED_Count);
1080 Cmd_AddCommand ("profile", PR_Profile_f);
1081 Cvar_RegisterVariable (&nomonsters);
1082 Cvar_RegisterVariable (&gamecfg);
1083 Cvar_RegisterVariable (&scratch1);
1084 Cvar_RegisterVariable (&scratch2);
1085 Cvar_RegisterVariable (&scratch3);
1086 Cvar_RegisterVariable (&scratch4);
1087 Cvar_RegisterVariable (&savedgamecfg);
1088 Cvar_RegisterVariable (&saved1);
1089 Cvar_RegisterVariable (&saved2);
1090 Cvar_RegisterVariable (&saved3);
1091 Cvar_RegisterVariable (&saved4);
1092}
1093
1094
1095
1096edict_t *EDICT_NUM(int n)
1097{
1098 if (n < 0 || n >= sv.max_edicts)
1099 Sys_Error ("EDICT_NUM: bad number %i", n);
1100 return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size);
1101}
1102
1103int NUM_FOR_EDICT(edict_t *e)
1104{
1105 int b;
1106
1107 b = (byte *)e - (byte *)sv.edicts;
1108 b = b / pr_edict_size;
1109
1110 if (b < 0 || b >= sv.num_edicts)
1111 Sys_Error ("NUM_FOR_EDICT: bad pointer");
1112 return b;
1113}