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_GetVar(int32_t id)252 int32_t __fastcall Gv_GetVar(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 union { int32_t ival; float fval; };
354
355 fval = *(float *)aGameVars[id].val.plValues;
356 if (negateResult)
357 fval *= -1;
358 return ival;
359 }
360 case GAMEVAR_INTPTR:
361 return (*((int32_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
362 case GAMEVAR_SHORTPTR:
363 return (*((int16_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
364 case GAMEVAR_CHARPTR:
365 return (*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
366 default:
367 M32_ERROR("Gv_GetVarX(): WTF??");
368 return -1;
369 }
370 }
371 case M32_FLAG_LOCAL:
372 {
373 int32_t index = id&(MAXGAMEVARS-1);
374 // no bounds checking since it's done at script compilation time
375 return (((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] ^ -negateResult) + negateResult;
376 }
377 } // switch (id&M32_VARTYPE_MASK)
378
379 return 0; // never reached
380 }
381
382
Gv_SetVar(int32_t id,int32_t lValue)383 void __fastcall Gv_SetVar(int32_t id, int32_t lValue)
384 {
385 switch (id&M32_VARTYPE_MASK)
386 {
387 case M32_FLAG_ARRAY:
388 {
389 int32_t index;
390
391 index = (id>>16)&0xffff;
392 if (!(id&M32_FLAG_CONSTANTINDEX))
393 index = Gv_GetVarN(index);
394
395 id &= (MAXGAMEARRAYS-1);
396
397 const int32_t siz = Gv_GetArraySize(id);
398 gamearray_t *const gar = &aGameArrays[id];
399
400 if (index < 0 || index >= siz)
401 {
402 M32_ERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", gar->szLabel, index, siz);
403 return;
404 }
405
406 // NOTE: GAMEARRAY_READONLY arrays can be modified in expert mode.
407 Bassert((gar->dwFlags & GAMEARRAY_STRIDE2) == 0);
408
409 switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
410 {
411 case 0:
412 case GAMEARRAY_INT32:
413 ((int32_t *)gar->vals)[index] = lValue;
414 return;
415 case GAMEARRAY_INT16:
416 ((int16_t *)gar->vals)[index] = (int16_t)lValue;
417 return;
418 case GAMEARRAY_UINT8:
419 ((uint8_t *)gar->vals)[index] = (uint8_t)lValue;
420 return;
421 default:
422 M32_ERROR("Gv_SetVarX() (array): WTF??");
423 return;
424 }
425 return;
426 }
427 case M32_FLAG_STRUCT:
428 {
429 int32_t index, memberid;
430
431 index = (id>>16)&0x7fff;
432 if (!(id&M32_FLAG_CONSTANTINDEX))
433 index = Gv_GetVarN(index);
434
435 memberid = (id>>2)&63;
436
437 switch (id&3)
438 {
439 case M32_SPRITE_VAR_ID:
440 VM_AccessSprite(1, index, memberid, lValue);
441 return;
442 case M32_SECTOR_VAR_ID:
443 VM_AccessSector(1, index, memberid, lValue);
444 return;
445 case M32_WALL_VAR_ID:
446 VM_AccessWall(1, index, memberid, lValue);
447 return;
448 case M32_TSPRITE_VAR_ID:
449 VM_AccessTsprite(1, index, memberid, lValue);
450 return;
451 default:
452 M32_ERROR("Gv_SetVarX(): WTF??");
453 return;
454 }
455 }
456 case M32_FLAG_VAR:
457 {
458 id &= (MAXGAMEVARS-1);
459
460 switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK))
461 {
462 case 0:
463 aGameVars[id].val.lValue=lValue;
464 return;
465 case GAMEVAR_PERBLOCK:
466 aGameVars[id].val.plValues[vm.g_st] = lValue;
467 return;
468 case GAMEVAR_FLOATPTR:
469 {
470 union { int32_t ival; float fval; };
471 ival = lValue;
472
473 if (fval!=fval || fval<-3.4e38 || fval > 3.4e38)
474 {
475 M32_ERROR("Gv_SetVarX(): tried to set float var to NaN or infinity");
476 return;
477 }
478 }
479 fallthrough__;
480 case GAMEVAR_INTPTR:
481 *((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
482 return;
483 case GAMEVAR_SHORTPTR:
484 *((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
485 return;
486 case GAMEVAR_CHARPTR:
487 *((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
488 return;
489 default:
490 M32_ERROR("Gv_SetVarX(): WTF??");
491 return;
492 }
493 }
494 case M32_FLAG_LOCAL:
495 {
496 int32_t index = id&(MAXGAMEVARS-1);
497 ((int32_t *)aGameArrays[M32_LOCAL_ARRAY_ID].vals)[index] = lValue;
498 return;
499 }
500 }
501 }
502
503 static uint8_t alphakeys[] =
504 {
505 KEYSC_SPACE,
506
507 KEYSC_A, KEYSC_B, KEYSC_C, KEYSC_D, KEYSC_E, KEYSC_F, KEYSC_G, KEYSC_H,
508 KEYSC_I, KEYSC_J, KEYSC_K, KEYSC_L, KEYSC_M, KEYSC_N, KEYSC_O, KEYSC_P,
509 KEYSC_Q, KEYSC_R, KEYSC_S, KEYSC_T, KEYSC_U, KEYSC_V, KEYSC_W, KEYSC_X,
510 KEYSC_Y, KEYSC_Z,
511 };
512
513 static uint8_t numberkeys[] =
514 {
515 KEYSC_0, KEYSC_1, KEYSC_2, KEYSC_3, KEYSC_4, KEYSC_5, KEYSC_6, KEYSC_7,
516 KEYSC_8, KEYSC_9,
517 };
518
Gv_AddSystemVars(void)519 static void Gv_AddSystemVars(void)
520 {
521 // only call ONCE
522 int32_t hlcnt_id, hlscnt_id;
523
524 // special vars for struct access
525 // MUST be at top and in this order!!!
526 Gv_NewVar("sprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
527 Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
528 Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
529 Gv_NewVar("tsprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
530 Gv_NewVar("light", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
531
532 // these too have to be in here and in order!
533 // keep in sync with m32script.h: IDs of special vars
534
535 Gv_NewVar("I", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM); // THISACTOR
536 Gv_NewVar("RETURN", (intptr_t)&g_iReturnVar, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
537 Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM);
538 Gv_NewVar("HITAG", 0, GAMEVAR_SYSTEM);
539 Gv_NewVar("TEXTURE", 0, GAMEVAR_SYSTEM);
540 Gv_NewVar("DOSCRSHOT", (intptr_t)&g_doScreenShot, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
541
542 Gv_NewVar("xdim",(intptr_t)&xdim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
543 Gv_NewVar("ydim",(intptr_t)&ydim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
544 Gv_NewVar("windowx1",(intptr_t)&windowxy1.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
545 Gv_NewVar("windowx2",(intptr_t)&windowxy2.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
546 Gv_NewVar("windowy1",(intptr_t)&windowxy1.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
547 Gv_NewVar("windowy2",(intptr_t)&windowxy2.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
548 Gv_NewVar("totalclock",(intptr_t)&totalclock, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
549
550 Gv_NewVar("viewingrange",(intptr_t)&viewingrange, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
551 Gv_NewVar("yxaspect",(intptr_t)&yxaspect, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
552
553 /// Gv_NewVar("framerate",(intptr_t)&g_frameRate, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
554 /// Gv_NewVar("display_mirror",(intptr_t)&display_mirror, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
555
556 Gv_NewVar("randomseed",(intptr_t)&randomseed, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
557
558 Gv_NewVar("numwalls",(intptr_t)&numwalls, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
559 Gv_NewVar("numsectors",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
560 Gv_NewVar("numsprites",(intptr_t)&Numsprites, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
561 {
562 static int32_t numtiles;
563 Gv_NewVar("numtiles",(intptr_t)&numtiles, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
564 }
565 #ifdef YAX_ENABLE
566 Gv_NewVar("numbunches",(intptr_t)&numyaxbunches, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
567 #endif
568
569 #ifdef USE_OPENGL
570 Gv_NewVar("rendmode",(intptr_t)&rendmode, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
571 #endif
572
573 // current position
574 Gv_NewVar("posx",(intptr_t)&pos.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
575 Gv_NewVar("posy",(intptr_t)&pos.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
576 Gv_NewVar("posz",(intptr_t)&pos.z, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
577 Gv_NewVar("ang",(intptr_t)&ang, GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
578 Gv_NewVar("horiz",(intptr_t)&horiz, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
579 Gv_NewVar("cursectnum",(intptr_t)&cursectnum, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
580 Gv_NewVar("hardcoded_movement",(intptr_t)&g_doHardcodedMovement, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
581
582 Gv_NewVar("searchx",(intptr_t)&searchx, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
583 Gv_NewVar("searchy",(intptr_t)&searchy, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
584 Gv_NewVar("searchstat",(intptr_t)&searchstat, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
585 Gv_NewVar("searchwall",(intptr_t)&searchwall, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
586 Gv_NewVar("searchsector",(intptr_t)&searchsector, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
587 Gv_NewVar("searchbottomwall",(intptr_t)&searchbottomwall, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
588
589 Gv_NewVar("pointhighlight",(intptr_t)&pointhighlight, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
590 Gv_NewVar("linehighlight",(intptr_t)&linehighlight, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
591
592 hlcnt_id = g_gameVarCount;
593 Gv_NewVar("highlightcnt",(intptr_t)&highlightcnt, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
594 hlscnt_id = g_gameVarCount;
595 Gv_NewVar("highlightsectorcnt",(intptr_t)&highlightsectorcnt, GAMEVAR_SHORTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
596
597 // clipboard contents
598 Gv_NewVar("temppicnum",(intptr_t)&temppicnum, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
599 Gv_NewVar("tempcstat",(intptr_t)&tempcstat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
600 Gv_NewVar("templotag",(intptr_t)&templotag, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
601 Gv_NewVar("temphitag",(intptr_t)&temphitag, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
602 Gv_NewVar("tempextra",(intptr_t)&tempextra, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
603 Gv_NewVar("tempshade",(intptr_t)&tempshade, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
604 Gv_NewVar("temppal",(intptr_t)&temppal, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
605 Gv_NewVar("tempvis",(intptr_t)&tempvis, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
606 Gv_NewVar("tempxrepeat",(intptr_t)&tempxrepeat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
607 Gv_NewVar("tempyrepeat",(intptr_t)&tempyrepeat, GAMEVAR_INTPTR|GAMEVAR_SYSTEM|GAMEVAR_READONLY);
608
609 // starting position
610 Gv_NewVar("startposx",(intptr_t)&startpos.x, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
611 Gv_NewVar("startposy",(intptr_t)&startpos.y, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
612 Gv_NewVar("startposz",(intptr_t)&startpos.z, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
613 Gv_NewVar("startang",(intptr_t)&startang, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
614 Gv_NewVar("startsectnum",(intptr_t)&startsectnum, GAMEVAR_READONLY | GAMEVAR_SHORTPTR | GAMEVAR_SYSTEM);
615
616 Gv_NewVar("mousxplc",(intptr_t)&mousxplc, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
617 Gv_NewVar("mousyplc",(intptr_t)&mousyplc, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
618 Gv_NewVar("mousebits",(intptr_t)&g_mouseBits, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
619
620 Gv_NewVar("zoom",(intptr_t)&zoom, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
621 Gv_NewVar("drawlinepat",(intptr_t)&m32_drawlinepat, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
622 Gv_NewVar("halfxdim16", (intptr_t)&halfxdim16, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
623 Gv_NewVar("midydim16", (intptr_t)&midydim16, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
624 Gv_NewVar("ydim16",(intptr_t)&ydim16, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
625 Gv_NewVar("m32_sideview",(intptr_t)&m32_sideview, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
626
627 Gv_NewVar("SV1",(intptr_t)&m32_sortvar1, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
628 Gv_NewVar("SV2",(intptr_t)&m32_sortvar2, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
629 Gv_NewVar("spritesortcnt",(intptr_t)&spritesortcnt, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
630
631 #ifdef POLYMER
632 Gv_NewVar("pr_overrideparallax",(intptr_t)&pr_overrideparallax, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
633 Gv_NewVar("pr_parallaxscale",(intptr_t)&pr_parallaxscale, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
634 Gv_NewVar("pr_parallaxbias",(intptr_t)&pr_parallaxbias, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
635 Gv_NewVar("pr_overridespecular",(intptr_t)&pr_overridespecular, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
636 Gv_NewVar("pr_specularpower",(intptr_t)&pr_specularpower, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
637 Gv_NewVar("pr_specularfactor",(intptr_t)&pr_specularfactor, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
638 #else
639 {
640 // dummy Polymer variables for non-Polymer builds
641 static int32_t pr_overrideparallax = 0;
642 static float pr_parallaxscale = 0.1f;
643 static float pr_parallaxbias = 0.0f;
644 static int32_t pr_overridespecular = 0;
645 static float pr_specularpower = 15.0f;
646 static float pr_specularfactor = 1.0f;
647
648 Gv_NewVar("pr_overrideparallax",(intptr_t)&pr_overrideparallax, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
649 Gv_NewVar("pr_parallaxscale",(intptr_t)&pr_parallaxscale, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
650 Gv_NewVar("pr_parallaxbias",(intptr_t)&pr_parallaxbias, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
651 Gv_NewVar("pr_overridespecular",(intptr_t)&pr_overridespecular, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
652 Gv_NewVar("pr_specularpower",(intptr_t)&pr_specularpower, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
653 Gv_NewVar("pr_specularfactor",(intptr_t)&pr_specularfactor, GAMEVAR_FLOATPTR | GAMEVAR_SYSTEM);
654 }
655 #endif
656
657 g_systemVarCount = g_gameVarCount;
658
659 // must be first!
660 Gv_NewArray(".LOCALS_BASE", NULL, 0, GAMEARRAY_INT32);
661
662 Gv_NewArray("highlight", (void *)highlight, hlcnt_id,
663 GAMEARRAY_READONLY|GAMEARRAY_INT16|GAMEARRAY_VARSIZE);
664 Gv_NewArray("highlightsector", (void *)highlightsector, hlscnt_id,
665 GAMEARRAY_READONLY|GAMEARRAY_INT16|GAMEARRAY_VARSIZE);
666
667 Gv_NewArray("hsect", (void *)headspritesect, MAXSECTORS+1, GAMEARRAY_READONLY|GAMEARRAY_INT16);
668 Gv_NewArray("psect", (void *)prevspritesect, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
669 Gv_NewArray("nsect", (void *)nextspritesect, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
670 Gv_NewArray("hstat", (void *)headspritestat, MAXSTATUS+1, GAMEARRAY_READONLY|GAMEARRAY_INT16);
671 Gv_NewArray("pstat", (void *)prevspritestat, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
672 Gv_NewArray("nstat", (void *)nextspritestat, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
673 #ifdef YAX_ENABLE
674 Gv_NewArray("headsectbunchc", (void *)headsectbunch[0], YAX_MAXBUNCHES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
675 Gv_NewArray("nextsectbunchc", (void *)nextsectbunch[0], MAXSECTORS, GAMEARRAY_READONLY|GAMEARRAY_INT16);
676 Gv_NewArray("headsectbunchf", (void *)headsectbunch[1], YAX_MAXBUNCHES, GAMEARRAY_READONLY|GAMEARRAY_INT16);
677 Gv_NewArray("nextsectbunchf", (void *)nextsectbunch[1], MAXSECTORS, GAMEARRAY_READONLY|GAMEARRAY_INT16);
678 #endif
679 Gv_NewArray("editorcolors", (void *)editorcolors, 256, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
680 Gv_NewArray("tilesizx", (void *)&tilesiz[0].x, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_INT16);
681 Gv_NewArray("tilesizy", (void *)&tilesiz[0].y, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_INT16);
682 // Gv_NewArray("picsiz", (void *)picsiz, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFCHAR);
683 Gv_NewArray("picanm", (void *)picanm, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_INT32);
684
685 Gv_NewArray("show2dsector", (void *)show2dsector, (MAXSECTORS+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
686 Gv_NewArray("show2dwall", (void *)show2dwall, (MAXWALLS+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
687 Gv_NewArray("show2dsprite", (void *)show2dsprite, (MAXSPRITES+7)>>3, GAMEARRAY_READONLY|GAMEARRAY_UINT8);
688
689 Gv_NewArray("keystatus", (void *)keystatus, 256, GAMEARRAY_WARN|GAMEARRAY_UINT8);
690 Gv_NewArray("alphakeys", (void *)alphakeys, sizeof(alphakeys), GAMEARRAY_READONLY|GAMEARRAY_UINT8);
691 Gv_NewArray("numberkeys", (void *)numberkeys, sizeof(numberkeys), GAMEARRAY_READONLY|GAMEARRAY_UINT8);
692
693 g_systemArrayCount = g_gameArrayCount;
694 }
695
Gv_Init(void)696 void Gv_Init(void)
697 {
698 // only call ONCE
699
700 Gv_Clear();
701 Gv_AddSystemVars();
702 }
703