1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010 EDuke32 developers and contributors
4
5 This file is part of EDuke32.
6
7 EDuke32 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 //-------------------------------------------------------------------------
22
23 // This object is shared by the editors of *all* Build games!
24
25 #include "m32script.h"
26 #include "m32def.h"
27 #include "osd.h"
28 #include "keys.h"
29 #ifdef POLYMER
30 #include "polymer.h"
31 #endif
32
33 #define _m32vars_c_
34 #include "m32structures.cpp"
35
Gv_Clear(void)36 static void Gv_Clear(void)
37 {
38 // only call this function ONCE...
39 int32_t i=(MAXGAMEVARS-1);
40
41 //AddLog("Gv_Clear");
42
43 for (; i>=0; i--)
44 {
45 DO_FREE_AND_NULL(aGameVars[i].szLabel);
46
47 if (aGameVars[i].dwFlags & GAMEVAR_USER_MASK)
48 DO_FREE_AND_NULL(aGameVars[i].val.plValues);
49
50 aGameVars[i].val.lValue = 0;
51 aGameVars[i].dwFlags |= GAMEVAR_RESET;
52
53 if (i >= MAXGAMEARRAYS)
54 continue;
55
56 gamearray_t *const gar = &aGameArrays[i];
57
58 DO_FREE_AND_NULL(gar->szLabel);
59
60 if (gar->dwFlags & GAMEARRAY_NORMAL)
61 DO_FREE_AND_NULL(gar->vals);
62
63 gar->dwFlags |= GAMEARRAY_RESET;
64 }
65
66 g_gameVarCount = g_gameArrayCount = 0;
67
68 hash_init(&h_gamevars);
69 hash_init(&h_arrays);
70 }
71
72 #define ASSERT_IMPLIES(x, y) Bassert(!(x) || (y))
73
Gv_NewArray(const char * pszLabel,void * arrayptr,intptr_t asize,uint32_t dwFlags)74 void Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags)
75 {
76 ASSERT_IMPLIES(dwFlags&GAMEARRAY_VARSIZE, dwFlags&GAMEARRAY_READONLY);
77 ASSERT_IMPLIES(dwFlags&GAMEARRAY_STRIDE2, dwFlags&GAMEARRAY_READONLY);
78 ASSERT_IMPLIES(dwFlags&GAMEARRAY_TYPE_MASK,
79 g_gameArrayCount==0 || (dwFlags&(GAMEARRAY_READONLY|GAMEARRAY_WARN)));
80
81 if (g_gameArrayCount >= MAXGAMEARRAYS)
82 {
83 C_CUSTOMERROR("too many arrays! (max: %d)", MAXGAMEARRAYS);
84 return;
85 }
86
87 if (Bstrlen(pszLabel) > (MAXARRAYLABEL-1))
88 {
89 C_CUSTOMERROR("array name `%s' exceeds limit of %d characters.", pszLabel, MAXARRAYLABEL);
90 return;
91 }
92
93 const int32_t i = hash_find(&h_arrays, pszLabel);
94
95 if (i>=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET))
96 {
97 // found it it's a duplicate in error
98
99 if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK)
100 C_CUSTOMWARNING("ignored redefining system array `%s'.", pszLabel);
101
102 // C_ReportError(WARNING_DUPLICATEDEFINITION);
103 return;
104 }
105
106 if (!(dwFlags&GAMEARRAY_VARSIZE) && !(dwFlags&GAMEARRAY_TYPE_MASK) && (asize<=0 || asize>65536))
107 {
108 // the dummy array with index 0 sets the size to 0 so that accidental accesses as array
109 // will complain.
110 C_CUSTOMERROR("invalid array size %d. Must be between 1 and 65536", (int)asize);
111 return;
112 }
113
114 gamearray_t *const gar = &aGameArrays[g_gameArrayCount];
115
116 if (gar->szLabel == NULL)
117 gar->szLabel = (char *)Xcalloc(MAXARRAYLABEL, sizeof(char));
118 if (gar->szLabel != pszLabel)
119 Bstrcpy(gar->szLabel, pszLabel);
120
121 if (!(dwFlags & GAMEARRAY_TYPE_MASK))
122 gar->vals = (int32_t *)Xcalloc(asize, sizeof(int32_t));
123 else
124 gar->vals = arrayptr;
125
126 gar->size = asize;
127 gar->dwFlags = dwFlags & ~GAMEARRAY_RESET;
128
129 hash_add(&h_arrays, gar->szLabel, g_gameArrayCount, 1);
130 g_gameArrayCount++;
131 }
132
Gv_NewVar(const char * pszLabel,intptr_t lValue,uint32_t dwFlags)133 void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
134 {
135 int32_t i, j;
136
137 //Bsprintf(g_szBuf,"Gv_NewVar(%s, %d, %X)",pszLabel, lValue, dwFlags);
138 //AddLog(g_szBuf);
139
140 if (g_gameVarCount >= MAXGAMEVARS)
141 {
142 C_CUSTOMERROR("too many gamevars! (max: %d)", MAXGAMEVARS);
143 return;
144 }
145
146 if (Bstrlen(pszLabel) > (MAXVARLABEL-1))
147 {
148 C_CUSTOMERROR("variable name `%s' exceeds limit of %d characters.", pszLabel, MAXVARLABEL);
149 return;
150 }
151
152 i = hash_find(&h_gamevars,pszLabel);
153
154 if (i >= 0 && !(aGameVars[i].dwFlags & GAMEVAR_RESET))
155 {
156 // found it...
157 if (aGameVars[i].dwFlags & GAMEVAR_PTR_MASK)
158 {
159 C_ReportError(-1);
160 initprintf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
161 return;
162 }
163 else if (!(aGameVars[i].dwFlags & GAMEVAR_SYSTEM))
164 {
165 // it's a duplicate in error
166 // g_numCompilerWarnings++;
167 // C_ReportError(WARNING_DUPLICATEDEFINITION);
168 return;
169 }
170 }
171
172 if (i == -1)
173 i = g_gameVarCount;
174
175 // Set values
176 if ((aGameVars[i].dwFlags & GAMEVAR_SYSTEM) == 0)
177 {
178 if (aGameVars[i].szLabel == NULL)
179 aGameVars[i].szLabel = (char *)Xcalloc(MAXVARLABEL, sizeof(uint8_t));
180 if (aGameVars[i].szLabel != pszLabel)
181 Bstrcpy(aGameVars[i].szLabel,pszLabel);
182 aGameVars[i].dwFlags = dwFlags;
183
184 if (aGameVars[i].dwFlags & GAMEVAR_USER_MASK)
185 {
186 // only free if not system
187 DO_FREE_AND_NULL(aGameVars[i].val.plValues);
188 }
189 }
190
191 // if existing is system, they only get to change default value....
192 aGameVars[i].lDefault = lValue;
193 aGameVars[i].dwFlags &= ~GAMEVAR_RESET;
194
195 if (i == g_gameVarCount)
196 {
197 // we're adding a new one.
198 hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0);
199 }
200
201 if (aGameVars[i].dwFlags & GAMEVAR_PERBLOCK)
202 {
203 if (!aGameVars[i].val.plValues)
204 aGameVars[i].val.plValues = (int32_t *)Xcalloc(1+MAXEVENTS+g_stateCount, sizeof(int32_t));
205 for (j=0; j<1+MAXEVENTS+g_stateCount; j++)
206 aGameVars[i].val.plValues[j] = lValue;
207 }
208 else aGameVars[i].val.lValue = lValue;
209 }
210
Gv_GetVarN(int32_t id)211 int32_t __fastcall Gv_GetVarN(int32_t id) // 'N' for "no side-effects"... vars and locals only!
212 {
213 if (id == M32_THISACTOR_VAR_ID)
214 return vm.spriteNum;
215
216 switch (id&M32_VARTYPE_MASK)
217 {
218 case M32_FLAG_VAR:
219 id &= (MAXGAMEVARS-1);
220
221 switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
222 {
223 case 0:
224 return aGameVars[id].val.lValue;
225 case GAMEVAR_PERBLOCK:
226 return aGameVars[id].val.plValues[vm.g_st];
227 case GAMEVAR_FLOATPTR:
228 case GAMEVAR_INTPTR:
229 return *((int32_t *)aGameVars[id].val.lValue);
230 case GAMEVAR_SHORTPTR:
231 return *((int16_t *)aGameVars[id].val.lValue);
232 case GAMEVAR_CHARPTR:
233 return *((uint8_t *)aGameVars[id].val.lValue);
234 default:
235 M32_ERROR("Gv_GetVarN(): WTF??");
236 return -1;
237 }
238
239 case M32_FLAG_LOCAL:
240 {
241 int32_t index = id&(MAXGAMEVARS-1);
242 // no bounds checking since it's done at script compilation time
243 return ((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index];
244 }
245
246 default:
247 M32_ERROR("Gv_GetVarN(): invalid var code %0x08x", id);
248 return -1;
249 }
250 }
251
Gv_GetVarX(int32_t id)252 int32_t __fastcall Gv_GetVarX(int32_t id)
253 {
254 int32_t negateResult = !!(id&M32_FLAG_NEGATE);
255
256 if (id == M32_THISACTOR_VAR_ID)
257 return vm.spriteNum;
258
259 id &= ~M32_FLAG_NEGATE;
260
261 if ((id & M32_BITS_MASK) == M32_FLAG_CONSTANT)
262 {
263 switch (id&3)
264 {
265 case 0:
266 return ((int16_t)(id>>16));
267 case 1:
268 return constants[(id>>16)&0xffff];
269 case 2:
270 return (labelval[(id>>16)&0xffff] ^ -negateResult) + negateResult;
271 default:
272 M32_ERROR("Gv_GetVarX() (constant): WTF??");
273 return -1;
274 }
275 }
276
277
278 switch (id&M32_VARTYPE_MASK)
279 {
280 case M32_FLAG_ARRAY:
281 {
282 int32_t index;
283
284 index = (int32_t)((id>>16)&0xffff);
285 if (!(id&M32_FLAG_CONSTANTINDEX))
286 index = Gv_GetVarN(index);
287
288 id &= (MAXGAMEARRAYS-1);
289
290 const int32_t siz = Gv_GetArraySize(id);
291 const gamearray_t *const gar = &aGameArrays[id];
292
293 if (index < 0 || index >= siz)
294 {
295 M32_ERROR("Gv_GetVarX(): invalid array index (%s[%d])", gar->szLabel, index);
296 return -1;
297 }
298
299 if (gar->dwFlags & GAMEARRAY_STRIDE2)
300 index <<= 1;
301
302 switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
303 {
304 case 0:
305 case GAMEARRAY_INT32:
306 return (((int32_t *)gar->vals)[index] ^ -negateResult) + negateResult;
307 case GAMEARRAY_INT16:
308 return (((int16_t *)gar->vals)[index] ^ -negateResult) + negateResult;
309 case GAMEARRAY_UINT8:
310 return (((uint8_t *)gar->vals)[index] ^ -negateResult) + negateResult;
311 default:
312 M32_ERROR("Gv_GetVarX() (array): WTF??");
313 return -1;
314 }
315 }
316 case M32_FLAG_STRUCT:
317 {
318 int32_t index, memberid;
319
320 index = (id>>16)&0x7fff;
321 if (!(id&M32_FLAG_CONSTANTINDEX))
322 index = Gv_GetVarN(index);
323
324 memberid = (id>>2)&63;
325
326 switch (id&3)
327 {
328 case M32_SPRITE_VAR_ID:
329 return (VM_AccessSprite(0, index, memberid, 0) ^ -negateResult) + negateResult;
330 case M32_SECTOR_VAR_ID:
331 return (VM_AccessSector(0, index, memberid, 0) ^ -negateResult) + negateResult;
332 case M32_WALL_VAR_ID:
333 return (VM_AccessWall(0, index, memberid, 0) ^ -negateResult) + negateResult;
334 case M32_TSPRITE_VAR_ID:
335 return (VM_AccessTsprite(0, index, memberid, 0) ^ -negateResult) + negateResult;
336 default:
337 M32_ERROR("Gv_GetVarX(): WTF??");
338 return -1;
339 }
340 }
341 case M32_FLAG_VAR:
342 {
343 id &= (MAXGAMEVARS-1);
344
345 switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
346 {
347 case 0:
348 return (aGameVars[id].val.lValue ^ -negateResult) + negateResult;
349 case GAMEVAR_PERBLOCK:
350 return (aGameVars[id].val.plValues[vm.g_st] ^ -negateResult) + negateResult;
351 case GAMEVAR_FLOATPTR:
352 {
353 float fval = *(float *)aGameVars[id].val.lValue;
354 if (negateResult)
355 fval *= -1;
356 return *(int32_t *)&fval;
357 }
358 case GAMEVAR_INTPTR:
359 return (*((int32_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
360 case GAMEVAR_SHORTPTR:
361 return (*((int16_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
362 case GAMEVAR_CHARPTR:
363 return (*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
364 default:
365 M32_ERROR("Gv_GetVarX(): WTF??");
366 return -1;
367 }
368 }
369 case M32_FLAG_LOCAL:
370 {
371 int32_t index = id&(MAXGAMEVARS-1);
372 // no bounds checking since it's done at script compilation time
373 return (((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] ^ -negateResult) + negateResult;
374 }
375 } // switch (id&M32_VARTYPE_MASK)
376
377 return 0; // never reached
378 }
379
380
Gv_SetVarX(int32_t id,int32_t lValue)381 void __fastcall Gv_SetVarX(int32_t id, int32_t lValue)
382 {
383 switch (id&M32_VARTYPE_MASK)
384 {
385 case M32_FLAG_ARRAY:
386 {
387 int32_t index;
388
389 index = (id>>16)&0xffff;
390 if (!(id&M32_FLAG_CONSTANTINDEX))
391 index = Gv_GetVarN(index);
392
393 id &= (MAXGAMEARRAYS-1);
394
395 const int32_t siz = Gv_GetArraySize(id);
396 gamearray_t *const gar = &aGameArrays[id];
397
398 if (index < 0 || index >= siz)
399 {
400 M32_ERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", gar->szLabel, index, siz);
401 return;
402 }
403
404 // NOTE: GAMEARRAY_READONLY arrays can be modified in expert mode.
405 Bassert((gar->dwFlags & GAMEARRAY_STRIDE2) == 0);
406
407 switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
408 {
409 case 0:
410 case GAMEARRAY_INT32:
411 ((int32_t *)gar->vals)[index] = lValue;
412 return;
413 case GAMEARRAY_INT16:
414 ((int16_t *)gar->vals)[index] = (int16_t)lValue;
415 return;
416 case GAMEARRAY_UINT8:
417 ((uint8_t *)gar->vals)[index] = (uint8_t)lValue;
418 return;
419 default:
420 M32_ERROR("Gv_SetVarX() (array): WTF??");
421 return;
422 }
423 return;
424 }
425 case M32_FLAG_STRUCT:
426 {
427 int32_t index, memberid;
428
429 index = (id>>16)&0x7fff;
430 if (!(id&M32_FLAG_CONSTANTINDEX))
431 index = Gv_GetVarN(index);
432
433 memberid = (id>>2)&63;
434
435 switch (id&3)
436 {
437 case M32_SPRITE_VAR_ID:
438 VM_AccessSprite(1, index, memberid, lValue);
439 return;
440 case M32_SECTOR_VAR_ID:
441 VM_AccessSector(1, index, memberid, lValue);
442 return;
443 case M32_WALL_VAR_ID:
444 VM_AccessWall(1, index, memberid, lValue);
445 return;
446 case M32_TSPRITE_VAR_ID:
447 VM_AccessTsprite(1, index, memberid, lValue);
448 return;
449 default:
450 M32_ERROR("Gv_SetVarX(): WTF??");
451 return;
452 }
453 }
454 case M32_FLAG_VAR:
455 {
456 id &= (MAXGAMEVARS-1);
457
458 switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
459 {
460 case 0:
461 aGameVars[id].val.lValue=lValue;
462 return;
463 case GAMEVAR_PERBLOCK:
464 aGameVars[id].val.plValues[vm.g_st] = lValue;
465 return;
466 case GAMEVAR_FLOATPTR:
467 {
468 int32_t ival = lValue;
469 float fval = *(float *)&ival;
470 if (fval!=fval || fval<-3.4e38 || fval > 3.4e38)
471 {
472 M32_ERROR("Gv_SetVarX(): tried to set float var to NaN or infinity");
473 return;
474 }
475 }
476 fallthrough__;
477 case GAMEVAR_INTPTR:
478 *((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
479 return;
480 case GAMEVAR_SHORTPTR:
481 *((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
482 return;
483 case GAMEVAR_CHARPTR:
484 *((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
485 return;
486 default:
487 M32_ERROR("Gv_SetVarX(): WTF??");
488 return;
489 }
490 }
491 case M32_FLAG_LOCAL:
492 {
493 int32_t index = id&(MAXGAMEVARS-1);
494 ((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] = lValue;
495 return;
496 }
497 }
498 }
499
500 static uint8_t alphakeys[] =
501 {
502 KEYSC_SPACE,
503
504 KEYSC_A, KEYSC_B, KEYSC_C, KEYSC_D, KEYSC_E, KEYSC_F, KEYSC_G, KEYSC_H,
505 KEYSC_I, KEYSC_J, KEYSC_K, KEYSC_L, KEYSC_M, KEYSC_N, KEYSC_O, KEYSC_P,
506 KEYSC_Q, KEYSC_R, KEYSC_S, KEYSC_T, KEYSC_U, KEYSC_V, KEYSC_W, KEYSC_X,
507 KEYSC_Y, KEYSC_Z,
508 };
509
510 static uint8_t numberkeys[] =
511 {
512 KEYSC_0, KEYSC_1, KEYSC_2, KEYSC_3, KEYSC_4, KEYSC_5, KEYSC_6, KEYSC_7,
513 KEYSC_8, KEYSC_9,
514 };
515
Gv_AddSystemVars(void)516 static void Gv_AddSystemVars(void)
517 {
518 // only call ONCE
519 int32_t hlcnt_id, hlscnt_id;
520
521 // special vars for struct access
522 // MUST be at top and in this order!!!
523 Gv_NewVar("sprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
524 Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
525 Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
526 Gv_NewVar("tsprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
527 Gv_NewVar("light", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
528
529 // these too have to be in here and in order!
530 // keep in sync with m32script.h: IDs of special vars
531
532 Gv_NewVar("I", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM); // THISACTOR
533 Gv_NewVar("RETURN", (intptr_t)&g_iReturnVar, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
534 Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM);
535 Gv_NewVar("HITAG", 0, GAMEVAR_SYSTEM);
536 Gv_NewVar("TEXTURE", 0, GAMEVAR_SYSTEM);
537 Gv_NewVar("DOSCRSHOT", (intptr_t)&g_doScreenShot, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
538
539 Gv_NewVar("xdim",(intptr_t)&xdim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
540 Gv_NewVar("ydim",(intptr_t)&ydim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
541 Gv_NewVar("windowx1",(intptr_t)&windowxy1.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
542 Gv_NewVar("windowx2",(intptr_t)&windowxy2.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
543 Gv_NewVar("windowy1",(intptr_t)&windowxy1.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
544 Gv_NewVar("windowy2",(intptr_t)&windowxy2.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
545 Gv_NewVar("totalclock",(intptr_t)&totalclock, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
546
547 Gv_NewVar("viewingrange",(intptr_t)&viewingrange, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
548 Gv_NewVar("yxaspect",(intptr_t)&yxaspect, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
549
550 /// Gv_NewVar("framerate",(intptr_t)&g_frameRate, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
551 /// Gv_NewVar("display_mirror",(intptr_t)&display_mirror, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
552
553 Gv_NewVar("randomseed",(intptr_t)&randomseed, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
554
555 Gv_NewVar("numwalls",(intptr_t)&numwalls, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
556 Gv_NewVar("numsectors",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
557 Gv_NewVar("numsprites",(intptr_t)&Numsprites, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
558 {
559 static int32_t numtiles;
560 Gv_NewVar("numtiles",(intptr_t)&numtiles, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
561 }
562 #ifdef YAX_ENABLE
563 Gv_NewVar("numbunches",(intptr_t)&numyaxbunches, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
564 #endif
565
566 #ifdef USE_OPENGL
567 Gv_NewVar("rendmode",(intptr_t)&rendmode, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
568 #endif
569
570 // current position
571 Gv_NewVar("posx",(intptr_t)&pos.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
572 Gv_NewVar("posy",(intptr_t)&pos.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
573 Gv_NewVar("posz",(intptr_t)&pos.z, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
574 Gv_NewVar("ang",(intptr_t)&ang, GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
575 Gv_NewVar("horiz",(intptr_t)&horiz, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
576 Gv_NewVar("cursectnum",(intptr_t)&cursectnum, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
577 Gv_NewVar("hardcoded_movement",(intptr_t)&g_doHardcodedMovement, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
578
579 Gv_NewVar("searchx",(intptr_t)&searchx, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
580 Gv_NewVar("searchy",(intptr_t)&searchy, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
581 Gv_NewVar("searchstat",(intptr_t)&searchstat, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
582 Gv_NewVar("searchwall",(intptr_t)&searchwall, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
583 Gv_NewVar("searchsector",(intptr_t)&searchsector, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
584 Gv_NewVar("searchbottomwall",(intptr_t)&searchbottomwall, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
585
586 Gv_NewVar("pointhighlight",(intptr_t)&pointhighlight, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
587 Gv_NewVar("linehighlight",(intptr_t)&linehighlight, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
588
589 hlcnt_id = g_gameVarCount;
590 Gv_NewVar("highlightcnt",(intptr_t)&highlightcnt, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
591 hlscnt_id = g_gameVarCount;
592 Gv_NewVar("highlightsectorcnt",(intptr_t)&highlightsectorcnt, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
593
594 // clipboard contents
595 Gv_NewVar("temppicnum",(intptr_t)&temppicnum, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
596 Gv_NewVar("tempcstat",(intptr_t)&tempcstat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
597 Gv_NewVar("templotag",(intptr_t)&templotag, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
598 Gv_NewVar("temphitag",(intptr_t)&temphitag, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
599 Gv_NewVar("tempextra",(intptr_t)&tempextra, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
600 Gv_NewVar("tempshade",(intptr_t)&tempshade, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
601 Gv_NewVar("temppal",(intptr_t)&temppal, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
602 Gv_NewVar("tempvis",(intptr_t)&tempvis, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
603 Gv_NewVar("tempxrepeat",(intptr_t)&tempxrepeat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
604 Gv_NewVar("tempyrepeat",(intptr_t)&tempyrepeat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
605
606 // starting position
607 Gv_NewVar("startposx",(intptr_t)&startpos.x, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
608 Gv_NewVar("startposy",(intptr_t)&startpos.y, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
609 Gv_NewVar("startposz",(intptr_t)&startpos.z, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
610 Gv_NewVar("startang",(intptr_t)&startang, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
611 Gv_NewVar("startsectnum",(intptr_t)&startsectnum, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
612
613 Gv_NewVar("mousxplc",(intptr_t)&mousxplc, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
614 Gv_NewVar("mousyplc",(intptr_t)&mousyplc, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
615
616 Gv_NewVar("zoom",(intptr_t)&zoom, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
617 Gv_NewVar("drawlinepat",(intptr_t)&m32_drawlinepat, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
618 Gv_NewVar("halfxdim16", (intptr_t)&halfxdim16, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
619 Gv_NewVar("midydim16", (intptr_t)&midydim16, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
620 Gv_NewVar("ydim16",(intptr_t)&ydim16, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
621 Gv_NewVar("m32_sideview",(intptr_t)&m32_sideview, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
622
623 Gv_NewVar("SV1",(intptr_t)&m32_sortvar1, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
624 Gv_NewVar("SV2",(intptr_t)&m32_sortvar2, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
625 Gv_NewVar("spritesortcnt",(intptr_t)&spritesortcnt, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
626
627 #ifdef POLYMER
628 Gv_NewVar("pr_overrideparallax",(intptr_t)&pr_overrideparallax, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
629 Gv_NewVar("pr_parallaxscale",(intptr_t)&pr_parallaxscale, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
630 Gv_NewVar("pr_parallaxbias",(intptr_t)&pr_parallaxbias, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
631 Gv_NewVar("pr_overridespecular",(intptr_t)&pr_overridespecular, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
632 Gv_NewVar("pr_specularpower",(intptr_t)&pr_specularpower, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
633 Gv_NewVar("pr_specularfactor",(intptr_t)&pr_specularfactor, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
634 #else
635 {
636 // dummy Polymer variables for non-Polymer builds
637 static int32_t pr_overrideparallax = 0;
638 static float pr_parallaxscale = 0.1f;
639 static float pr_parallaxbias = 0.0f;
640 static int32_t pr_overridespecular = 0;
641 static float pr_specularpower = 15.0f;
642 static float pr_specularfactor = 1.0f;
643
644 Gv_NewVar("pr_overrideparallax",(intptr_t)&pr_overrideparallax, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
645 Gv_NewVar("pr_parallaxscale",(intptr_t)&pr_parallaxscale, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
646 Gv_NewVar("pr_parallaxbias",(intptr_t)&pr_parallaxbias, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
647 Gv_NewVar("pr_overridespecular",(intptr_t)&pr_overridespecular, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
648 Gv_NewVar("pr_specularpower",(intptr_t)&pr_specularpower, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
649 Gv_NewVar("pr_specularfactor",(intptr_t)&pr_specularfactor, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
650 }
651 #endif
652
653 g_systemVarCount = g_gameVarCount;
654
655 // must be first!
656 Gv_NewArray(".LOCALS_BASE", NULL, 0, GAMEARRAY_INT32);
657
658 Gv_NewArray("highlight", (void *)highlight, hlcnt_id,
659 GAMEARRAY_READONLY|GAMEARRAY_INT16|GAMEARRAY_VARSIZE);
660 Gv_NewArray("highlightsector", (void *)highlightsector, hlscnt_id,
661 GAMEARRAY_READONLY|GAMEARRAY_INT16|GAMEARRAY_VARSIZE);
662
663 Gv_NewArray("hsect", (void *)headspritesect, MAXSECTORS+1, GAMEARRAY_READONLY|GAMEARRAY_INT16);
664 Gv_NewArray("psect", (void *)prevspritesect, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
665 Gv_NewArray("nsect", (void *)nextspritesect, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
666 Gv_NewArray("hstat", (void *)headspritestat, MAXSTATUS+1, GAMEARRAY_READONLY|GAMEARRAY_INT16);
667 Gv_NewArray("pstat", (void *)prevspritestat, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
668 Gv_NewArray("nstat", (void *)nextspritestat, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
669 #ifdef YAX_ENABLE
670 Gv_NewArray("headsectbunchc", (void *)headsectbunch[0], YAX_MAXBUNCHES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
671 Gv_NewArray("nextsectbunchc", (void *)nextsectbunch[0], MAXSECTORS, GAMEARRAY_READONLY|GAMEARRAY_INT16);
672 Gv_NewArray("headsectbunchf", (void *)headsectbunch[1], YAX_MAXBUNCHES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
673 Gv_NewArray("nextsectbunchf", (void *)nextsectbunch[1], MAXSECTORS, GAMEARRAY_READONLY|GAMEARRAY_INT16);
674 #endif
675 Gv_NewArray("editorcolors", (void *)editorcolors, 256, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
676 Gv_NewArray("tilesizx", (void *)&tilesiz[0].x, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_INT16);
677 Gv_NewArray("tilesizy", (void *)&tilesiz[0].y, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_INT16);
678 // Gv_NewArray("picsiz", (void *)picsiz, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFCHAR);
679 Gv_NewArray("picanm", (void *)picanm, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_INT32);
680
681 Gv_NewArray("show2dsector", (void *)show2dsector, (MAXSECTORS+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
682 Gv_NewArray("show2dwall", (void *)show2dwall, (MAXWALLS+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
683 Gv_NewArray("show2dsprite", (void *)show2dsprite, (MAXSPRITES+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
684
685 Gv_NewArray("keystatus", (void *)keystatus, 256, GAMEARRAY_WARN|GAMEARRAY_UINT8);
686 Gv_NewArray("alphakeys", (void *)alphakeys, sizeof(alphakeys), GAMEARRAY_READONLY|GAMEARRAY_UINT8);
687 Gv_NewArray("numberkeys", (void *)numberkeys, sizeof(numberkeys), GAMEARRAY_READONLY|GAMEARRAY_UINT8);
688
689 g_systemArrayCount = g_gameArrayCount;
690 }
691
Gv_Init(void)692 void Gv_Init(void)
693 {
694 // only call ONCE
695
696 Gv_Clear();
697 Gv_AddSystemVars();
698 }
699