m32vars.cpp
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 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 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 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 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 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 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 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, bitmap_size(MAXSECTORS), GAMEARRAY_READONLY|GAMEARRAY_UINT8); 686 Gv_NewArray("show2dwall", (void *)show2dwall, bitmap_size(MAXWALLS), GAMEARRAY_READONLY|GAMEARRAY_UINT8); 687 Gv_NewArray("show2dsprite", (void *)show2dsprite, bitmap_size(MAXSPRITES), 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 696 void Gv_Init(void) 697 { 698 // only call ONCE 699 700 Gv_Clear(); 701 Gv_AddSystemVars(); 702 }