/ source / blood / src / m32structures.cpp
m32structures.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 is all the crap for accessing the game's structs through the CON VM
 24  // I got a 3-4 fps gain by inlining these...
 25  
 26  #include "compat.h"
 27  #include "m32script.h"
 28  #include "m32def.h"
 29  #ifdef POLYMER
 30  # include "prlights.h"
 31  #endif
 32  
 33  // how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[])
 34  #define ACCESS_SET 1
 35  #define ACCESS_USEVARS 2
 36  
 37  
 38  /// This file is #included into other files, so don't define variables here!
 39  
 40  
 41  static int32_t __fastcall VM_AccessWall(int32_t how, int32_t lVar1, int32_t labelNum, int32_t lVar2)
 42  {
 43      int32_t lValue;
 44      int32_t i = (how&ACCESS_USEVARS) ? Gv_GetVar(lVar1) : lVar1;
 45  
 46      if (!m32_script_expertmode && (i<0 || i >= numwalls))
 47          goto badwall;
 48  
 49      if (how&ACCESS_SET)
 50      {
 51          if (!m32_script_expertmode && (WallLabels[labelNum].flags & 1))
 52              goto readonly;
 53  
 54          lValue = (how&ACCESS_USEVARS) ? Gv_GetVar(lVar2) : lVar2;
 55  
 56          asksave = 1;
 57  
 58          if (!m32_script_expertmode && (WallLabels[labelNum].min != 0 || WallLabels[labelNum].max != 0))
 59          {
 60              if (lValue < WallLabels[labelNum].min)
 61                  lValue = WallLabels[labelNum].min;
 62              if (lValue > WallLabels[labelNum].max)
 63                  lValue = WallLabels[labelNum].max;
 64          }
 65  
 66          switch (labelNum)
 67          {
 68          case WALL_X: wall[i].x=lValue; break;
 69          case WALL_Y: wall[i].y=lValue; break;
 70          case WALL_POINT2: wall[i].point2=lValue; break;
 71          case WALL_NEXTWALL: wall[i].nextwall=lValue; break;
 72          case WALL_NEXTSECTOR: wall[i].nextsector=lValue; break;
 73          case WALL_CSTAT:
 74  #ifdef YAX_ENABLE__COMPAT
 75              if (!m32_script_expertmode)
 76                  SET_PROTECT_BITS(wall[i].cstat, lValue, YAX_NEXTWALLBITS);
 77              else
 78  #endif
 79                  wall[i].cstat = lValue;
 80              break;
 81          case WALL_PICNUM: wall[i].picnum=lValue; break;
 82          case WALL_OVERPICNUM: wall[i].overpicnum=lValue; break;
 83          case WALL_SHADE: wall[i].shade=lValue; break;
 84          case WALL_PAL: wall[i].pal=lValue; break;
 85          case WALL_XREPEAT: wall[i].xrepeat=lValue; break;
 86          case WALL_YREPEAT: wall[i].yrepeat=lValue; break;
 87          case WALL_XPANNING: wall[i].xpanning=lValue; break;
 88          case WALL_YPANNING: wall[i].ypanning=lValue; break;
 89          case WALL_LOTAG:
 90  #ifdef YAX_ENABLE__COMPAT
 91              if (!m32_script_expertmode && numyaxbunches>0 && yax_getnextwall(i,YAX_CEILING)>=0)
 92                  goto yax_readonly;
 93  #endif
 94              wall[i].lotag=lValue;
 95              break;
 96          case WALL_HITAG: wall[i].hitag=lValue; break;
 97          case WALL_EXTRA:
 98  #ifdef YAX_ENABLE__COMPAT
 99              if (!m32_script_expertmode && numyaxbunches>0 && yax_getnextwall(i,YAX_FLOOR)>=0)
100                  goto yax_readonly;
101  #endif
102              wall[i].extra=lValue;
103              break;
104          default:
105              return -1;
106          }
107  
108          return 0;
109      }
110      else
111      {
112          switch (labelNum)
113          {
114          case WALL_X: lValue=wall[i].x; break;
115          case WALL_Y: lValue=wall[i].y; break;
116          case WALL_POINT2: lValue=wall[i].point2; break;
117          case WALL_NEXTWALL: lValue=wall[i].nextwall; break;
118          case WALL_NEXTSECTOR: lValue=wall[i].nextsector; break;
119          case WALL_CSTAT: lValue=wall[i].cstat; break;
120          case WALL_PICNUM: lValue=wall[i].picnum; break;
121          case WALL_OVERPICNUM: lValue=wall[i].overpicnum; break;
122          case WALL_SHADE: lValue=wall[i].shade; break;
123          case WALL_PAL: lValue=wall[i].pal; break;
124          case WALL_XREPEAT: lValue=wall[i].xrepeat; break;
125          case WALL_YREPEAT: lValue=wall[i].yrepeat; break;
126          case WALL_XPANNING: lValue=wall[i].xpanning; break;
127          case WALL_YPANNING: lValue=wall[i].ypanning; break;
128          case WALL_LOTAG: lValue=wall[i].lotag; break;
129          case WALL_HITAG: lValue=wall[i].hitag; break;
130          case WALL_EXTRA: lValue=wall[i].extra; break;
131          default:
132              return -1;
133          }
134  
135          if (how&ACCESS_USEVARS)
136              Gv_SetVar(lVar2, lValue);
137  
138          return lValue;
139      }
140  
141  badwall:
142      M32_ERROR("Invalid wall %d", i);
143      return -1;
144  readonly:
145      M32_ERROR("Wall structure member `%s' is read-only.", WallLabels[labelNum].name);
146      return -1;
147  #ifdef YAX_ENABLE__COMPAT
148  yax_readonly:
149      M32_ERROR("Wall structure member `%s' is read-only because it is used for TROR",
150                WallLabels[labelNum].name);
151      return -1;
152  #endif
153  }
154  
155  // how: bitfield: 1=set? 2=vars?
156  static int32_t __fastcall VM_AccessSector(int32_t how, int32_t lVar1, int32_t labelNum, int32_t lVar2)
157  {
158      int32_t lValue;
159      int32_t i = (how&ACCESS_USEVARS) ? sprite[vm.spriteNum].sectnum : lVar1;
160  
161      if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
162          i = Gv_GetVar(lVar1);
163  
164      if (!m32_script_expertmode && (i<0 || i >= numsectors))
165          goto badsector;
166  
167      if (how&ACCESS_SET)
168      {
169          if (!m32_script_expertmode && (SectorLabels[labelNum].flags & 1))
170              goto readonly;
171  
172          lValue = (how&ACCESS_USEVARS) ? Gv_GetVar(lVar2) : lVar2;
173  
174          asksave = 1;
175  
176          if (!m32_script_expertmode && (SectorLabels[labelNum].min != 0 || SectorLabels[labelNum].max != 0))
177          {
178              if (lValue < SectorLabels[labelNum].min)
179                  lValue = SectorLabels[labelNum].min;
180              if (lValue > SectorLabels[labelNum].max)
181                  lValue = SectorLabels[labelNum].max;
182          }
183  
184          switch (labelNum)
185          {
186          case SECTOR_WALLPTR: sector[i].wallptr=lValue; break;
187          case SECTOR_WALLNUM: sector[i].wallnum=lValue; break;
188          case SECTOR_CEILINGZ: sector[i].ceilingz=lValue; break;
189          case SECTOR_FLOORZ: sector[i].floorz=lValue; break;
190          case SECTOR_CEILINGSTAT:
191  #ifdef YAX_ENABLE__COMPAT
192              if (!m32_script_expertmode)
193                  SET_PROTECT_BITS(sector[i].ceilingstat, lValue, YAX_BIT);
194              else
195  #endif
196                  sector[i].ceilingstat = lValue;
197              break;
198          case SECTOR_FLOORSTAT:
199  #ifdef YAX_ENABLE__COMPAT
200              if (!m32_script_expertmode)
201                  SET_PROTECT_BITS(sector[i].floorstat, lValue, YAX_BIT);
202              else
203  #endif
204                  sector[i].floorstat = lValue;
205              break;
206          case SECTOR_CEILINGPICNUM: sector[i].ceilingpicnum=lValue; break;
207          case SECTOR_CEILINGSLOPE:
208              setslope(i, 0, lValue);
209              break;
210          case SECTOR_CEILINGSHADE: sector[i].ceilingshade=lValue; break;
211          case SECTOR_CEILINGPAL: sector[i].ceilingpal=lValue; break;
212          case SECTOR_CEILINGXPANNING: sector[i].ceilingxpanning=lValue; break;
213          case SECTOR_CEILINGYPANNING: sector[i].ceilingypanning=lValue; break;
214          case SECTOR_FLOORPICNUM: sector[i].floorpicnum=lValue; break;
215          case SECTOR_FLOORSLOPE:
216              setslope(i, 1, lValue);
217              break;
218          case SECTOR_FLOORSHADE: sector[i].floorshade=lValue; break;
219          case SECTOR_FLOORPAL: sector[i].floorpal=lValue; break;
220          case SECTOR_FLOORXPANNING: sector[i].floorxpanning=lValue; break;
221          case SECTOR_FLOORYPANNING: sector[i].floorypanning=lValue; break;
222          case SECTOR_VISIBILITY: sector[i].visibility=lValue; break;
223          case SECTOR_FOGPAL: sector[i].fogpal=lValue; break;
224          case SECTOR_LOTAG: sector[i].lotag=lValue; break;
225          case SECTOR_HITAG: sector[i].hitag=lValue; break;
226          case SECTOR_EXTRA: sector[i].extra=lValue; break;
227          default:
228              return -1;
229          }
230  
231          return 0;
232      }
233      else
234      {
235          switch (labelNum)
236          {
237          case SECTOR_WALLPTR: lValue=sector[i].wallptr; break;
238          case SECTOR_WALLNUM: lValue=sector[i].wallnum; break;
239          case SECTOR_CEILINGZ: lValue=sector[i].ceilingz; break;
240          case SECTOR_FLOORZ: lValue=sector[i].floorz; break;
241          case SECTOR_CEILINGSTAT: lValue=sector[i].ceilingstat; break;
242          case SECTOR_FLOORSTAT: lValue=sector[i].floorstat; break;
243          case SECTOR_CEILINGPICNUM: lValue=sector[i].ceilingpicnum; break;
244          case SECTOR_CEILINGSLOPE: lValue=sector[i].ceilingheinum; break;
245          case SECTOR_CEILINGSHADE: lValue=sector[i].ceilingshade; break;
246          case SECTOR_CEILINGPAL: lValue=sector[i].ceilingpal; break;
247          case SECTOR_CEILINGXPANNING: lValue=sector[i].ceilingxpanning; break;
248          case SECTOR_CEILINGYPANNING: lValue=sector[i].ceilingypanning; break;
249          case SECTOR_FLOORPICNUM: lValue=sector[i].floorpicnum; break;
250          case SECTOR_FLOORSLOPE: lValue=sector[i].floorheinum; break;
251          case SECTOR_FLOORSHADE: lValue=sector[i].floorshade; break;
252          case SECTOR_FLOORPAL: lValue=sector[i].floorpal; break;
253          case SECTOR_FLOORXPANNING: lValue=sector[i].floorxpanning; break;
254          case SECTOR_FLOORYPANNING: lValue=sector[i].floorypanning; break;
255          case SECTOR_VISIBILITY: lValue=sector[i].visibility; break;
256          case SECTOR_FOGPAL: lValue=sector[i].fogpal; break;
257          case SECTOR_LOTAG: lValue=sector[i].lotag; break;
258          case SECTOR_HITAG: lValue=sector[i].hitag; break;
259          case SECTOR_EXTRA: lValue=sector[i].extra; break;
260          default:
261              return -1;
262          }
263  
264          if (how&ACCESS_USEVARS)
265              Gv_SetVar(lVar2, lValue);
266  
267          return lValue;
268      }
269  
270  badsector:
271      M32_ERROR("Invalid sector %d", i);
272      return -1;
273  readonly:
274      M32_ERROR("Sector structure member `%s' is read-only.", SectorLabels[labelNum].name);
275      return -1;
276  }
277  
278  // how: bitfield: 1=set? 2=vars?
279  static int32_t __fastcall VM_AccessSprite(int32_t how, int32_t lVar1, int32_t labelNum, int32_t lVar2)
280  {
281      int32_t lValue;
282      int32_t i = (how&ACCESS_USEVARS) ? vm.spriteNum : lVar1;
283  
284      if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
285          i = Gv_GetVar(lVar1);
286  
287      if ((unsigned)i >= MAXSPRITES)
288          goto badsprite;
289  
290      if (how&ACCESS_SET)
291      {
292          if (!m32_script_expertmode && (SpriteLabels[labelNum].flags & 1))
293              goto readonly;
294  
295          lValue = (how&ACCESS_USEVARS) ? Gv_GetVar(lVar2) : lVar2;
296  
297          asksave = 1;
298  
299          if (!m32_script_expertmode && (SpriteLabels[labelNum].min != 0 || SpriteLabels[labelNum].max != 0))
300          {
301              if (lValue < SpriteLabels[labelNum].min)
302                  lValue = SpriteLabels[labelNum].min;
303              if (lValue > SpriteLabels[labelNum].max)
304                  lValue = SpriteLabels[labelNum].max;
305          }
306  
307          switch (labelNum)
308          {
309          case SPRITE_X: sprite[i].x=lValue; break;
310          case SPRITE_Y: sprite[i].y=lValue; break;
311          case SPRITE_Z: sprite[i].z=lValue; break;
312          case SPRITE_CSTAT: sprite[i].cstat = lValue; break;
313          case SPRITE_PICNUM: sprite[i].picnum=lValue; break;
314          case SPRITE_SHADE: sprite[i].shade=lValue; break;
315          case SPRITE_PAL: sprite[i].pal=lValue; break;
316          case SPRITE_CLIPDIST: sprite[i].clipdist=lValue; break;
317          case SPRITE_BLEND: sprite[i].blend=lValue; break;
318          case SPRITE_XREPEAT: sprite[i].xrepeat=lValue; break;
319          case SPRITE_YREPEAT: sprite[i].yrepeat=lValue; break;
320          case SPRITE_XOFFSET: sprite[i].xoffset=lValue; break;
321          case SPRITE_YOFFSET: sprite[i].yoffset=lValue; break;
322          case SPRITE_SECTNUM: changespritesect(i,lValue); break;
323          case SPRITE_STATNUM: changespritestat(i,lValue); break;
324          case SPRITE_ANG:
325              sprite[i].ang = lValue&2047;
326              break;
327          case SPRITE_OWNER: sprite[i].owner=lValue; break;
328          case SPRITE_XVEL: sprite[i].xvel=lValue; break;
329          case SPRITE_YVEL: sprite[i].yvel=lValue; break;
330          case SPRITE_ZVEL: sprite[i].zvel=lValue; break;
331          case SPRITE_LOTAG: sprite[i].lotag=lValue; break;
332          case SPRITE_HITAG: sprite[i].hitag=lValue; break;
333          case SPRITE_EXTRA: sprite[i].extra=lValue; break;
334          default:
335              return -1;
336          }
337  
338          return 0;
339      }
340      else
341      {
342          switch (labelNum)
343          {
344          case SPRITE_X: lValue=sprite[i].x; break;
345          case SPRITE_Y: lValue=sprite[i].y; break;
346          case SPRITE_Z: lValue=sprite[i].z; break;
347          case SPRITE_CSTAT: lValue=sprite[i].cstat; break;
348          case SPRITE_PICNUM: lValue=sprite[i].picnum; break;
349          case SPRITE_SHADE: lValue=sprite[i].shade; break;
350          case SPRITE_PAL: lValue=sprite[i].pal; break;
351          case SPRITE_CLIPDIST: lValue=sprite[i].clipdist; break;
352          case SPRITE_BLEND: lValue=sprite[i].blend; break;
353          case SPRITE_XREPEAT: lValue=sprite[i].xrepeat; break;
354          case SPRITE_YREPEAT: lValue=sprite[i].yrepeat; break;
355          case SPRITE_XOFFSET: lValue=sprite[i].xoffset; break;
356          case SPRITE_YOFFSET: lValue=sprite[i].yoffset; break;
357          case SPRITE_SECTNUM: lValue=sprite[i].sectnum; break;
358          case SPRITE_STATNUM: lValue=sprite[i].statnum; break;
359          case SPRITE_ANG: lValue=sprite[i].ang; break;
360          case SPRITE_OWNER: lValue=sprite[i].owner; break;
361          case SPRITE_XVEL: lValue=sprite[i].xvel; break;
362          case SPRITE_YVEL: lValue=sprite[i].yvel; break;
363          case SPRITE_ZVEL: lValue=sprite[i].zvel; break;
364          case SPRITE_LOTAG: lValue=sprite[i].lotag; break;
365          case SPRITE_HITAG: lValue=sprite[i].hitag; break;
366          case SPRITE_EXTRA: lValue=sprite[i].extra; break;
367          default:
368              return -1;
369          }
370  
371          if (how&ACCESS_USEVARS)
372              Gv_SetVar(lVar2, lValue);
373  
374          return lValue;
375      }
376  badsprite:
377      M32_ERROR("tried to set %s on invalid target sprite (%d)", SpriteLabels[labelNum].name, i);
378      return -1;
379  readonly:
380      M32_ERROR("sprite structure member `%s' is read-only.", SpriteLabels[labelNum].name);
381      return -1;
382  }
383  
384  // how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[])
385  static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t labelNum, int32_t lVar2)
386  {
387      int32_t lightp = (labelNum >= LIGHT_X);
388      int32_t i = (how&ACCESS_USEVARS) ? vm.spriteNum : lVar1;
389      tspriteptr_t datspr = nullptr;
390      const memberlabel_t *dalabel = lightp ? &LightLabels[labelNum-LIGHT_X] : &SpriteLabels[labelNum];
391  
392      if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
393          i = Gv_GetVar(lVar1);
394  
395      if (!lightp)
396      {
397          if (i<0 || i>=spritesortcnt)
398              goto badsprite;
399          datspr = &tsprite[i];
400      }
401      else
402      {
403          // access Polymer light
404  #ifndef POLYMER
405          M32_ERROR("Polymer not compiled in, accessing lights is invalid.");
406          return -1;
407  #else
408          if ((how&ACCESS_USEVARS) && lVar1 == M32_THISACTOR_VAR_ID)
409          {
410              if ((unsigned)i >= MAXSPRITES)
411                  goto badsprite;
412              M32_ERROR("Polymer light access via current sprite not implemented.");
413              return -1;
414          }
415          else
416          {
417  // check whether videoGetRenderMode() == REND_POLYMER ?
418              if ((unsigned)i >= PR_MAXLIGHTS)
419              {
420                  M32_ERROR("invalid light index (%d)", i);
421                  return -1;
422              }
423  
424              if (labelNum != LIGHT_ACTIVE && !prlights[i].flags.active)
425              {
426                  M32_ERROR("light with index %d is inactive!", i);
427                  return -1;
428              }
429          }
430  #endif
431      }
432  
433      if (how&ACCESS_SET)
434      {
435          int32_t lValue, damin, damax;
436  
437          if (!m32_script_expertmode && (dalabel->flags & 1))
438              goto readonly;
439  
440          lValue = (how&ACCESS_USEVARS) ? Gv_GetVar(lVar2) : lVar2;
441  
442          damin = dalabel->min;
443          damax = dalabel->max;
444  
445          if (!m32_script_expertmode && (damin|damax))
446          {
447              if (lValue < damin)
448                  lValue = damin;
449              if (lValue > damax)
450                  lValue = damax;
451          }
452  
453          switch (labelNum)
454          {
455          case SPRITE_X: datspr->x=lValue; break;
456          case SPRITE_Y: datspr->y=lValue; break;
457          case SPRITE_Z: datspr->z=lValue; break;
458          case SPRITE_CSTAT: datspr->cstat = lValue; break;
459          case SPRITE_PICNUM: datspr->picnum=lValue; break;
460          case SPRITE_SHADE: datspr->shade=lValue; break;
461          case SPRITE_PAL: datspr->pal=lValue; break;
462          case SPRITE_CLIPDIST: datspr->clipdist=lValue; break;
463          case SPRITE_BLEND: datspr->blend=lValue; break;
464          case SPRITE_XREPEAT: datspr->xrepeat=lValue; break;
465          case SPRITE_YREPEAT: datspr->yrepeat=lValue; break;
466          case SPRITE_XOFFSET: datspr->xoffset=lValue; break;
467          case SPRITE_YOFFSET: datspr->yoffset=lValue; break;
468          case SPRITE_SECTNUM: datspr->sectnum=lValue; break;
469          case SPRITE_STATNUM: datspr->statnum=lValue; break;
470          case SPRITE_ANG:
471              datspr->ang = lValue&2047;
472              break;
473          case SPRITE_OWNER: datspr->owner=lValue; break;
474          case SPRITE_XVEL: datspr->xvel=lValue; break;
475          case SPRITE_YVEL: datspr->yvel=lValue; break;
476          case SPRITE_ZVEL: datspr->zvel=lValue; break;
477          case SPRITE_LOTAG: datspr->lotag=lValue; break;
478          case SPRITE_HITAG: datspr->hitag=lValue; break;
479          case SPRITE_EXTRA: datspr->extra=lValue; break;
480  #ifdef POLYMER
481          // lights
482          case LIGHT_X: prlights[i].x = lValue; break;
483          case LIGHT_Y: prlights[i].y = lValue; break;
484          case LIGHT_Z: prlights[i].z = lValue; break;
485          case LIGHT_HORIZ: prlights[i].horiz = lValue; break;
486          case LIGHT_RANGE: prlights[i].range = lValue; break;
487          case LIGHT_ANGLE: prlights[i].angle = lValue; break;
488          case LIGHT_FADERADIUS: prlights[i].faderadius = lValue; break;
489          case LIGHT_RADIUS: prlights[i].radius = lValue; break;
490          case LIGHT_SECTOR: prlights[i].sector = lValue; break;
491          case LIGHT_R: prlights[i].color[0] = lValue; break;
492          case LIGHT_G: prlights[i].color[1] = lValue; break;
493          case LIGHT_B: prlights[i].color[2] = lValue; break;
494          case LIGHT_PRIORITY: prlights[i].priority = lValue; break;
495          case LIGHT_TILENUM: prlights[i].tilenum = lValue; break;
496          case LIGHT_MINSHADE: prlights[i].minshade = lValue; break;
497          case LIGHT_MAXSHADE: prlights[i].maxshade = lValue; break;
498  #endif
499          default:
500              return -1;
501          }
502  
503          return 0;
504      }
505      else
506      {
507          int32_t lValue;
508  
509          switch (labelNum)
510          {
511          case SPRITE_X: lValue=datspr->x; break;
512          case SPRITE_Y: lValue=datspr->y; break;
513          case SPRITE_Z: lValue=datspr->z; break;
514          case SPRITE_CSTAT: lValue=datspr->cstat; break;
515          case SPRITE_PICNUM: lValue=datspr->picnum; break;
516          case SPRITE_SHADE: lValue=datspr->shade; break;
517          case SPRITE_PAL: lValue=datspr->pal; break;
518          case SPRITE_CLIPDIST: lValue=datspr->clipdist; break;
519          case SPRITE_BLEND: lValue=datspr->blend; break;
520          case SPRITE_XREPEAT: lValue=datspr->xrepeat; break;
521          case SPRITE_YREPEAT: lValue=datspr->yrepeat; break;
522          case SPRITE_XOFFSET: lValue=datspr->xoffset; break;
523          case SPRITE_YOFFSET: lValue=datspr->yoffset; break;
524          case SPRITE_SECTNUM: lValue=datspr->sectnum; break;
525          case SPRITE_STATNUM: lValue=datspr->statnum; break;
526          case SPRITE_ANG: lValue=datspr->ang; break;
527          case SPRITE_OWNER: lValue=datspr->owner; break;
528          case SPRITE_XVEL: lValue=datspr->xvel; break;
529          case SPRITE_YVEL: lValue=datspr->yvel; break;
530          case SPRITE_ZVEL: lValue=datspr->zvel; break;
531          case SPRITE_LOTAG: lValue=datspr->lotag; break;
532          case SPRITE_HITAG: lValue=datspr->hitag; break;
533          case SPRITE_EXTRA: lValue=datspr->extra; break;
534  #ifdef POLYMER
535          // lights
536          case LIGHT_X: lValue = prlights[i].x; break;
537          case LIGHT_Y: lValue = prlights[i].y; break;
538          case LIGHT_Z: lValue = prlights[i].z; break;
539          case LIGHT_HORIZ: lValue = prlights[i].horiz; break;
540          case LIGHT_RANGE: lValue = prlights[i].range; break;
541          case LIGHT_ANGLE: lValue = prlights[i].angle; break;
542          case LIGHT_FADERADIUS: lValue = prlights[i].faderadius; break;
543          case LIGHT_RADIUS: lValue = prlights[i].radius; break;
544          case LIGHT_SECTOR: lValue = prlights[i].sector; break;
545          case LIGHT_R: lValue = prlights[i].color[0]; break;
546          case LIGHT_G: lValue = prlights[i].color[1]; break;
547          case LIGHT_B: lValue = prlights[i].color[2]; break;
548          case LIGHT_PRIORITY: lValue = prlights[i].priority; break;
549          case LIGHT_TILENUM: lValue = prlights[i].tilenum; break;
550          case LIGHT_MINSHADE: lValue = prlights[i].minshade; break;
551          case LIGHT_MAXSHADE: lValue = prlights[i].maxshade; break;
552          case LIGHT_ACTIVE: lValue = !!prlights[i].flags.active; break;
553  #endif
554          default:
555              return -1;
556          }
557  
558          if (how&ACCESS_USEVARS)
559              Gv_SetVar(lVar2, lValue);
560  
561          return lValue;
562      }
563  
564  badsprite:
565      M32_ERROR("invalid target sprite (%d)", i);
566      return -1;
567  readonly:
568      M32_ERROR("structure member `%s' is read-only.", dalabel->name);
569      return -1;
570  }
571  
572  #undef ACCESS_SET
573  #undef ACCESS_USEVARS