//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "duke3d.h"
#include "namesdyn.h"
#include "gamedef.h"
#include "gameexec.h"
#include "savegame.h"
#include "common.h"
#include "common_game.h"
#include "osd.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#endif
#define NUMKEYWORDS (int32_t)ARRAY_SIZE(keyw)
int32_t g_scriptVersion
= 13; // 13 = 1.3D-style CON files, 14 = 1.4/1.5 style CON files
uint32_t g_scriptDateVersion
= 99999999; // YYYYMMDD
#if !defined LUNATIC
static uint32_t g_scriptLastKeyword
; // = NUMKEYWORDS-1;
#define NUMKEYWDATES (int32_t)ARRAY_SIZE(g_keywdate)
// { keyw, date } means that at the date, all keywords up to keyw inclusive are available
static struct { uint32_t keyw
; uint32_t date
; } g_keywdate
[] =
{
// beginning of eduke32 svn
{ CON_CANSEE
, 20060423 },
{ CON_CANSEESPR
, 20060424 },
// some stuff here not representable this way
{ CON_FINDNEARSPRITEZVAR
, 20060516 },
{ CON_EZSHOOT
, 20060701 },
{ CON_EZSHOOTVAR
, 20060822 },
{ CON_JUMP
, 20060828 },
{ CON_QSTRLEN
, 20060930 },
{ CON_QUAKE
, 20070105 },
{ CON_SHOWVIEW
, 20070208 },
{ CON_NEXTSPRITESECT
, 20070819 },
{ CON_GETKEYNAME
, 20071024 }, // keyw numbers have been
{ CON_SPRITENOPAL
, 20071220 }, // shuffled around here
{ CON_HITRADIUSVAR
, 20080216 },
{ CON_ROTATESPRITE16
, 20080314 },
{ CON_SETARRAY
, 20080401 },
{ CON_READARRAYFROMFILE
, 20080405 },
{ CON_STARTTRACKVAR
, 20080510 },
{ CON_QGETSYSSTR
, 20080709 },
{ CON_GETTICKS
, 20080711 },
{ CON_SETTSPR
, 20080713 },
{ CON_CLEARMAPSTATE
, 20080716 },
{ CON_SCRIPTSIZE
, 20080720 },
{ CON_SETGAMENAME
, 20080722 },
{ CON_CMENU
, 20080725 },
{ CON_GETTIMEDATE
, 20080809 },
{ CON_ACTIVATECHEAT
, 20080810 },
{ CON_SETGAMEPALETTE
, 20080816 },
{ CON_SETCFGNAME
, 20080817 },
{ CON_IFVARVAREITHER
, 20080907 },
{ CON_SAVENN
, 20080915 },
{ CON_COPY
, 20090219 },
// { CON_INV, 20090619 },
{ CON_QSTRNCAT
, 20090712 },
{ CON_STOPACTORSOUND
, 20090715 },
{ CON_IFSERVER
, 20100722 },
{ CON_CALCHYPOTENUSE
, 20100927 },
{ CON_CLIPMOVENOSLIDE
, 20101009 },
{ CON_INCLUDEDEFAULT
, 20110615 },
{ CON_SETACTORSOUNDPITCH
, 20111102 },
{ CON_ECHO
, 20120304 },
{ CON_SHOWVIEWUNBIASED
, 20120331 },
{ CON_ROTATESPRITEA
, 20130324 },
{ CON_ACTIVATE
, 20130522 },
{ CON_SCREENTEXT
, 20130529 },
{ CON_DYNAMICSOUNDREMAP
, 20130530 },
{ CON_SCREENSOUND
, 20130628 },
{ CON_SETMUSICPOSITION
, 20150116 },
{ CON_UNDEFINELEVEL
, 20150208 },
{ CON_IFCUTSCENE
, 20150210 },
{ CON_DEFINEVOLUMEFLAGS
, 20150222 },
{ CON_RESETPLAYERFLAGS
, 20150303 },
};
#endif
char g_szScriptFileName
[BMAX_PATH
] = "(none)"; // file we're currently compiling
int32_t g_totalLines
,g_lineNumber
;
char g_szBuf
[1024];
#if !defined LUNATIC
static char g_szCurrentBlockName
[256] = "(none)", g_szLastBlockName
[256] = "NULL";
static int32_t g_checkingIfElse
, g_processingState
, g_lastKeyword
= -1;
// The pointer to the start of the case table in a switch statement.
// First entry is 'default' code.
static intptr_t *g_caseScriptPtr
=NULL
;
static intptr_t *previous_event
=NULL
;
static int32_t g_numCases
= 0;
static int32_t g_checkingSwitch
= 0, g_currentEvent
= -1;
static int32_t g_labelsOnly
= 0, g_skipKeywordCheck
= 0, g_dynamicTileMapping
= 0, g_dynamicSoundMapping
= 0;
static int32_t g_numBraces
= 0;
static int32_t C_ParseCommand
(int32_t loop
);
static int32_t C_SetScriptSize
(int32_t size
);
#endif
int32_t g_numQuoteRedefinitions
= 0;
#ifdef LUNATIC
weapondata_t g_playerWeapon
[MAXPLAYERS
][MAX_WEAPONS
];
#endif
#if !defined LUNATIC
static intptr_t *g_parsingEventPtr
=NULL
;
static char *textptr
;
#endif
int32_t g_numCompilerErrors
,g_numCompilerWarnings
;
extern int32_t g_maxSoundPos
;
enum
{
LABEL_ANY
= -1,
LABEL_DEFINE
= 1,
LABEL_STATE
= 2,
LABEL_ACTOR
= 4,
LABEL_ACTION
= 8,
LABEL_AI
= 16,
LABEL_MOVE
= 32,
};
#if !defined LUNATIC
static const char *C_GetLabelType
(int32_t type
)
{
int32_t i
;
char x
[64];
const char *LabelTypeText
[] =
{
"define",
"state",
"actor",
"action",
"ai",
"move"
};
x
[0] = 0;
for (i
=0; i
<6; i
++)
{
if (!(type
& (1<<i
))) continue;
if (x
[0]) Bstrcat
(x
, " or ");
Bstrcat
(x
, LabelTypeText
[i
]);
}
return Xstrdup
(x
);
}
const char *keyw
[] =
{
"definelevelname", // 0 defines level name
"actor", // 1 defines an actor
"addammo", // 2 adds ammo to a weapon
"ifrnd", // 3 checks against a randomizer
"enda", // 4 ends an actor definition
"ifcansee", // 5 checks if the player can see an object
"ifhitweapon", // 6 checks if an object was hit by a weapon
"action", // 7 defines an action if used outside a state or actor, otherwise triggers actor to perform action
"ifpdistl", // 8 checks if player distance is less than value
"ifpdistg", // 9 checks if player distance is more than value
"else", // 10 used with if checks
"strength", // 11 sets health
"break", // 12 stops processing
"shoot", // 13 shoots a projectile
"palfrom", // 14 used for player screen shading effect, sets p->pals
"sound", // 15 plays a sound that was defined with definesound
"fall", // 16 causes actor to fall to sector floor height
"state", // 17 begins defining a state if used outside a state or actor, otherwise calls a state
"ends", // 18 ends defining a state
"define", // 19 defines a value
"return", // 20
"ifai", // 21 checks if actor is currently performing a specific ai function
"killit", // 22 kills an actor
"addweapon", // 23 adds a weapon to the closest player
"ai", // 24 sets an ai function to be used by an actor
"addphealth", // 25 adds health to the player
"ifdead", // 26 checks if actor is dead
"ifsquished", // 27 checks if actor has been squished
"sizeto", // 28 gradually increases actor size until it matches parameters given
"{", // 29 used to indicate segments of code
"}", // 30 used to indicate segments of code
"spawn", // 31 spawns an actor
"move", // 32
"ifwasweapon", // 33
"ifaction", // 34
"ifactioncount", // 35
"resetactioncount", // 36
"debris", // 37
"pstomp", // 38
"<null>", // 39 was previously used to define the start of a comment block
"cstat", // 40
"ifmove", // 41
"resetplayer", // 42
"ifonwater", // 43
"ifinwater", // 44
"ifcanshoottarget", // 45
"ifcount", // 46
"resetcount", // 47
"addinventory", // 48
"ifactornotstayput", // 49
"hitradius", // 50
"ifp", // 51
"count", // 52
"ifactor", // 53
"music", // 54
"include", // 55
"ifstrength", // 56
"definesound", // 57
"guts", // 58
"ifspawnedby", // 59
"gamestartup", // 60
"wackplayer", // 61
"ifgapzl", // 62
"ifhitspace", // 63
"ifoutside", // 64
"ifmultiplayer", // 65
"operate", // 66
"ifinspace", // 67
"debug", // 68
"endofgame", // 69
"ifbulletnear", // 70
"ifrespawn", // 71
"iffloordistl", // 72
"ifceilingdistl", // 73
"spritepal", // 74
"ifpinventory", // 75
"betaname", // 76
"cactor", // 77
"ifphealthl", // 78
"definequote", // 79
"quote", // 80
"ifinouterspace", // 81
"ifnotmoving", // 82
"respawnhitag", // 83
"tip", // 84
"ifspritepal", // 85
"money", // 86
"soundonce", // 87
"addkills", // 88
"stopsound", // 89
"ifawayfromwall", // 90
"ifcanseetarget", // 91
"globalsound", // 92
"lotsofglass", // 93
"ifgotweaponce", // 94
"getlastpal", // 95
"pkick", // 96
"mikesnd", // 97
"useractor", // 98
"sizeat", // 99
"addstrength", // 100 [#]
"cstator", // 101
"mail", // 102
"paper", // 103
"tossweapon", // 104
"sleeptime", // 105
"nullop", // 106
"definevolumename", // 107
"defineskillname", // 108
"ifnosounds", // 109
"clipdist", // 110
"ifangdiffl", // 111 Last Duke3D 1.5 CON command
"gamevar", // 112
"ifvarl", // 113
"ifvarg", // 114
"setvarvar", // 115
"setvar", // 116
"addvarvar", // 117
"addvar", // 118
"ifvarvarl", // 119
"ifvarvarg", // 120
"addlogvar", // 121
"addlog", // 122
"onevent", // 123
"endevent", // 124
"ifvare", // 125
"ifvarvare", // 126
"spgetlotag", // 127
"spgethitag", // 128
"sectgetlotag", // 129
"sectgethitag", // 130
"ifsound", // 131
"gettexturefloor", // 132
"gettextureceiling", // 133
"inittimer", // 134
"starttrack", // 135
"randvar", // 136
"enhanced", // 137
"getangletotarget", // 138
"getactorangle", // 139
"setactorangle", // 140
"mulvar", // 141
"mulvarvar", // 142
"divvar", // 143
"divvarvar", // 144
"modvar", // 145
"modvarvar", // 146
"andvar", // 147
"andvarvar", // 148
"orvar", // 149
"orvarvar", // 150
"getplayerangle", // 151
"setplayerangle", // 152
"lockplayer", // 153
"setsector", // 154
"getsector", // 155
"setactor", // 156
"getactor", // 157
"setwall", // 158
"getwall", // 159
"findnearactor", // 160
"findnearactorvar", // 161
"setactorvar", // 162
"getactorvar", // 163
"espawn", // 164
"getplayer", // 165
"setplayer", // 166
"sqrt", // 167
"eventloadactor", // 168
"espawnvar", // 169
"getuserdef", // 170
"setuserdef", // 171
"subvarvar", // 172
"subvar", // 173
"ifvarn", // 174
"ifvarvarn", // 175
"ifvarand", // 176
"ifvarvarand", // 177
"myos", // 178
"myospal", // 179
"displayrand", // 180
"sin", // 181
"xorvarvar", // 182
"xorvar", // 183
"randvarvar", // 184
"myosx", // 185
"myospalx", // 186
"gmaxammo", // 187
"smaxammo", // 188
"startlevel", // 189
"eshoot", // 190
"qspawn", // 191
"rotatesprite", // 192
"defineprojectile", // 193
"spriteshadow", // 194
"cos", // 195
"eshootvar", // 196
"findnearactor3d", // 197
"findnearactor3dvar", // 198
"flash", // 199
"qspawnvar", // 200
"eqspawn", // 201
"eqspawnvar", // 202
"minitext", // 203
"gametext", // 204
"digitalnumber", // 205
"addweaponvar", // 206
"setprojectile", // 207
"angoff", // 208
"updatesector", // 209
"insertspriteq", // 210
"angoffvar", // 211
"whilevarn", // 212
"switch", // 213
"case", // 214
"default", // 215
"endswitch", // 216
"shootvar", // 217
"soundvar", // 218
"findplayer", // 219
"findotherplayer", // 220
"activatebysector", // 221 sectnum, spriteid
"operatesectors", // 222 sectnum, spriteid
"operaterespawns", // 223 lotag
"operateactivators", // 224 lotag, player index
"operatemasterswitches", // 225 lotag
"checkactivatormotion", // 226 lotag
"zshoot", // 227 zvar projnum
"dist", // 228 sprite1 sprite2
"ldist", // 229 sprite1 sprite2
"shiftvarl", // 230
"shiftvarr", // 231
"spritenvg", // 232
"getangle", // 233
"whilevarvarn", // 234
"hitscan", // 235
"time", // 236
"getplayervar", // 237
"setplayervar", // 238
"mulscale", // 239
"setaspect", // 240
"ezshoot", // 241
"spritenoshade", // 242
"movesprite", // 243
"checkavailweapon", // 244
"soundoncevar", // 245
"updatesectorz", // 246
"stopallsounds", // 247
"ssp", // 248
"stopsoundvar", // 249
"displayrandvar", // 250
"displayrandvarvar", // 251
"checkavailinven", // 252
"globalsoundvar", // 253
"guniqhudid", // 254
"getprojectile", // 255
"getthisprojectile", // 256
"setthisprojectile", // 257
"definecheat", // 258
"cheatkeys", // 259
"userquote", // 260
"precache", // 261
"definegamefuncname", // 262
"redefinequote", // 263
"qsprintf", // 264
"getpname", // 265
"qstrcat", // 266
"qstrcpy", // 267
"setsprite", // 268
"rotatepoint", // 269
"dragpoint", // 270
"getzrange", // 271
"changespritestat", // 272
"getceilzofslope", // 273
"getflorzofslope", // 274
"neartag", // 275
"definegametype", // 276
"changespritesect", // 277
"spriteflags", // 278
"savegamevar", // 279
"readgamevar", // 280
"findnearsprite", // 281
"findnearspritevar", // 282
"findnearsprite3d", // 283
"findnearsprite3dvar", // 284
"dynamicremap", // 285
"setinput", // 286
"getinput", // 287
"save", // 288
"cansee", // 289 Beginning EDuke32 SVN
"canseespr", // 290
"findnearactorz", // 291
"findnearactorzvar", // 292
"findnearspritez", // 293
"findnearspritezvar", // 294
"zshootvar", // 295
"ezshootvar", // 296
"getcurraddress", // 297
"jump", // 298
"qstrlen", // 299
"getincangle", // 300
"quake", // 301
"showview", // 302
"headspritestat", // 303
"prevspritestat", // 304
"nextspritestat", // 305
"headspritesect", // 306
"prevspritesect", // 307
"nextspritesect", // 308
"getkeyname", // 309
"qsubstr", // 310
"gametextz", // 311
"digitalnumberz", // 312
"spritenopal", // 313
"hitradiusvar", // 314
"rotatesprite16", // 315
"gamearray", // 316
"setarray", // 317
"resizearray", // 318
"writearraytofile", // 319
"readarrayfromfile", // 320
"starttrackvar", // 321
"qgetsysstr", // 322
"getticks", // 323
"gettspr", // 324
"settspr", // 325
"savemapstate", // 326
"loadmapstate", // 327
"clearmapstate", // 328
"scriptsize", // 329
"setgamename", // 330
"cmenu", // 331
"gettimedate", // 332
"activatecheat", // 333
"setgamepalette", // 334
"setdefname", // 335
"setcfgname", // 336
"ifvaror", // 337
"ifvarvaror", // 338
"ifvarxor", // 339
"ifvarvarxor", // 340
"ifvareither", // 341
"ifvarvareither", // 342
"getarraysize", // 343
"savenn", // 344
"copy", // 345
"<null>", // 346 internal inversion function
"sectorofwall", // 347
"qstrncat", // 348
"ifactorsound", // 349
"stopactorsound", // 350
"ifclient", // 351
"ifserver", // 352
"sectsetinterpolation", // 353
"sectclearinterpolation", // 354
"clipmove", // 355
"lineintersect", // 356
"rayintersect", // 357
"calchypotenuse", // 358
"clipmovenoslide", // 359
"includedefault", // 360
"setactorsoundpitch", // 361
"echo", // 362
"showviewunbiased", // 363
"rotatespritea", // 364
"shadeto", // 365
"endoflevel", // 366
"ifplayersl", // 367
"activate", // 368
"qstrdim", // 369
"screentext", // 370
"dynamicsoundremap", // 371
"screensound", // 372
"getmusicposition", // 373
"setmusicposition", // 374
"undefinevolume", // 375
"undefineskill", // 376
"undefinelevel", // 377
"startcutscene", // 378
"ifcutscene", // 379
"definevolumeflags", // 380
"resetplayerflags", // 381
"<null>"
};
#endif
// KEEPINSYNC with enum GameEvent_t and lunatic/con_lang.lua
const char *EventNames
[MAXEVENTS
] =
{
"EVENT_INIT",
"EVENT_ENTERLEVEL",
"EVENT_RESETWEAPONS",
"EVENT_RESETINVENTORY",
"EVENT_HOLSTER",
"EVENT_LOOKLEFT",
"EVENT_LOOKRIGHT",
"EVENT_SOARUP",
"EVENT_SOARDOWN",
"EVENT_CROUCH",
"EVENT_JUMP",
"EVENT_RETURNTOCENTER",
"EVENT_LOOKUP",
"EVENT_LOOKDOWN",
"EVENT_AIMUP",
"EVENT_FIRE",
"EVENT_CHANGEWEAPON",
"EVENT_GETSHOTRANGE",
"EVENT_GETAUTOAIMANGLE",
"EVENT_GETLOADTILE",
"EVENT_CHEATGETSTEROIDS",
"EVENT_CHEATGETHEAT",
"EVENT_CHEATGETBOOT",
"EVENT_CHEATGETSHIELD",
"EVENT_CHEATGETSCUBA",
"EVENT_CHEATGETHOLODUKE",
"EVENT_CHEATGETJETPACK",
"EVENT_CHEATGETFIRSTAID",
"EVENT_QUICKKICK",
"EVENT_INVENTORY",
"EVENT_USENIGHTVISION",
"EVENT_USESTEROIDS",
"EVENT_INVENTORYLEFT",
"EVENT_INVENTORYRIGHT",
"EVENT_HOLODUKEON",
"EVENT_HOLODUKEOFF",
"EVENT_USEMEDKIT",
"EVENT_USEJETPACK",
"EVENT_TURNAROUND",
"EVENT_DISPLAYWEAPON",
"EVENT_FIREWEAPON",
"EVENT_SELECTWEAPON",
"EVENT_MOVEFORWARD",
"EVENT_MOVEBACKWARD",
"EVENT_TURNLEFT",
"EVENT_TURNRIGHT",
"EVENT_STRAFELEFT",
"EVENT_STRAFERIGHT",
"EVENT_WEAPKEY1",
"EVENT_WEAPKEY2",
"EVENT_WEAPKEY3",
"EVENT_WEAPKEY4",
"EVENT_WEAPKEY5",
"EVENT_WEAPKEY6",
"EVENT_WEAPKEY7",
"EVENT_WEAPKEY8",
"EVENT_WEAPKEY9",
"EVENT_WEAPKEY10",
"EVENT_DRAWWEAPON",
"EVENT_DISPLAYCROSSHAIR",
"EVENT_DISPLAYREST",
"EVENT_DISPLAYSBAR",
"EVENT_RESETPLAYER",
"EVENT_INCURDAMAGE",
"EVENT_AIMDOWN",
"EVENT_GAME",
"EVENT_PREVIOUSWEAPON",
"EVENT_NEXTWEAPON",
"EVENT_SWIMUP",
"EVENT_SWIMDOWN",
"EVENT_GETMENUTILE",
"EVENT_SPAWN",
"EVENT_LOGO",
"EVENT_EGS",
"EVENT_DOFIRE",
"EVENT_PRESSEDFIRE",
"EVENT_USE",
"EVENT_PROCESSINPUT",
"EVENT_FAKEDOMOVETHINGS",
"EVENT_DISPLAYROOMS",
"EVENT_KILLIT",
"EVENT_LOADACTOR",
"EVENT_DISPLAYBONUSSCREEN",
"EVENT_DISPLAYMENU",
"EVENT_DISPLAYMENUREST",
"EVENT_DISPLAYLOADINGSCREEN",
"EVENT_ANIMATESPRITES",
"EVENT_NEWGAME",
"EVENT_SOUND",
"EVENT_CHECKTOUCHDAMAGE",
"EVENT_CHECKFLOORDAMAGE",
"EVENT_LOADGAME",
"EVENT_SAVEGAME",
"EVENT_PREGAME",
"EVENT_CHANGEMENU",
"EVENT_DAMAGEHPLANE",
"EVENT_ACTIVATECHEAT",
"EVENT_DISPLAYINACTIVEMENU",
"EVENT_DISPLAYINACTIVEMENUREST",
"EVENT_CUTSCENE",
"EVENT_DISPLAYCURSOR",
"EVENT_DISPLAYLEVELSTATS",
#ifdef LUNATIC
"EVENT_ANIMATEALLSPRITES",
#endif
};
#if !defined LUNATIC
const memberlabel_t SectorLabels
[]=
{
{ "wallptr", SECTOR_WALLPTR
, 0, 0 },
{ "wallnum", SECTOR_WALLNUM
, 0, 0 },
{ "ceilingz", SECTOR_CEILINGZ
, 0, 0 },
{ "floorz", SECTOR_FLOORZ
, 0, 0 },
{ "ceilingstat", SECTOR_CEILINGSTAT
, 0, 0 },
{ "floorstat", SECTOR_FLOORSTAT
, 0, 0 },
{ "ceilingpicnum", SECTOR_CEILINGPICNUM
, 0, 0 },
{ "ceilingslope", SECTOR_CEILINGSLOPE
, 0, 0 },
{ "ceilingshade", SECTOR_CEILINGSHADE
, 0, 0 },
{ "ceilingpal", SECTOR_CEILINGPAL
, 0, 0 },
{ "ceilingxpanning", SECTOR_CEILINGXPANNING
, 0, 0 },
{ "ceilingypanning", SECTOR_CEILINGYPANNING
, 0, 0 },
{ "floorpicnum", SECTOR_FLOORPICNUM
, 0, 0 },
{ "floorslope", SECTOR_FLOORSLOPE
, 0, 0 },
{ "floorshade", SECTOR_FLOORSHADE
, 0, 0 },
{ "floorpal", SECTOR_FLOORPAL
, 0, 0 },
{ "floorxpanning", SECTOR_FLOORXPANNING
, 0, 0 },
{ "floorypanning", SECTOR_FLOORYPANNING
, 0, 0 },
{ "visibility", SECTOR_VISIBILITY
, 0, 0 },
{ "fogpal", SECTOR_FOGPAL
, 0, 0 }, // formerly filler
{ "alignto", SECTOR_FOGPAL
, 0, 0 }, // formerly filler
{ "lotag", SECTOR_LOTAG
, 0, 0 },
{ "hitag", SECTOR_HITAG
, 0, 0 },
{ "extra", SECTOR_EXTRA
, 0, 0 },
{ "ceilingbunch", SECTOR_CEILINGBUNCH
, 0, 0 },
{ "floorbunch", SECTOR_FLOORBUNCH
, 0, 0 },
{ "ulotag", SECTOR_ULOTAG
, 0, 0 },
{ "uhitag", SECTOR_UHITAG
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t WallLabels
[]=
{
{ "x", WALL_X
, 0, 0 },
{ "y", WALL_Y
, 0, 0 },
{ "point2", WALL_POINT2
, 0, 0 },
{ "nextwall", WALL_NEXTWALL
, 0, 0 },
{ "nextsector", WALL_NEXTSECTOR
, 0, 0 },
{ "cstat", WALL_CSTAT
, 0, 0 },
{ "picnum", WALL_PICNUM
, 0, 0 },
{ "overpicnum", WALL_OVERPICNUM
, 0, 0 },
{ "shade", WALL_SHADE
, 0, 0 },
{ "pal", WALL_PAL
, 0, 0 },
{ "xrepeat", WALL_XREPEAT
, 0, 0 },
{ "yrepeat", WALL_YREPEAT
, 0, 0 },
{ "xpanning", WALL_XPANNING
, 0, 0 },
{ "ypanning", WALL_YPANNING
, 0, 0 },
{ "lotag", WALL_LOTAG
, 0, 0 },
{ "hitag", WALL_HITAG
, 0, 0 },
{ "extra", WALL_EXTRA
, 0, 0 },
{ "ulotag", WALL_ULOTAG
, 0, 0 },
{ "uhitag", WALL_UHITAG
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t ActorLabels
[]=
{
{ "x", ACTOR_X
, 0, 0 },
{ "y", ACTOR_Y
, 0, 0 },
{ "z", ACTOR_Z
, 0, 0 },
{ "cstat", ACTOR_CSTAT
, 0, 0 },
{ "picnum", ACTOR_PICNUM
, 0, 0 },
{ "shade", ACTOR_SHADE
, 0, 0 },
{ "pal", ACTOR_PAL
, 0, 0 },
{ "clipdist", ACTOR_CLIPDIST
, 0, 0 },
// { "filler", ACTOR_DETAIL, 0, 0 },
{ "blend", ACTOR_DETAIL
, 0, 0 },
{ "xrepeat", ACTOR_XREPEAT
, 0, 0 },
{ "yrepeat", ACTOR_YREPEAT
, 0, 0 },
{ "xoffset", ACTOR_XOFFSET
, 0, 0 },
{ "yoffset", ACTOR_YOFFSET
, 0, 0 },
{ "sectnum", ACTOR_SECTNUM
, 0, 0 },
{ "statnum", ACTOR_STATNUM
, 0, 0 },
{ "ang", ACTOR_ANG
, 0, 0 },
{ "owner", ACTOR_OWNER
, 0, 0 },
{ "xvel", ACTOR_XVEL
, 0, 0 },
{ "yvel", ACTOR_YVEL
, 0, 0 },
{ "zvel", ACTOR_ZVEL
, 0, 0 },
{ "lotag", ACTOR_LOTAG
, 0, 0 },
{ "hitag", ACTOR_HITAG
, 0, 0 },
{ "extra", ACTOR_EXTRA
, 0, 0 },
// ActorExtra labels...
{ "htcgg", ACTOR_HTCGG
, 0, 0 },
{ "htpicnum", ACTOR_HTPICNUM
, 0, 0 },
{ "htang", ACTOR_HTANG
, 0, 0 },
{ "htextra", ACTOR_HTEXTRA
, 0, 0 },
{ "htowner", ACTOR_HTOWNER
, 0, 0 },
{ "htmovflag", ACTOR_HTMOVFLAG
, 0, 0 },
{ "httempang", ACTOR_HTTEMPANG
, 0, 0 },
{ "htactorstayput", ACTOR_HTACTORSTAYPUT
, 0, 0 },
{ "htdispicnum", ACTOR_HTDISPICNUM
, 0, 0 },
{ "httimetosleep", ACTOR_HTTIMETOSLEEP
, 0, 0 },
{ "htfloorz", ACTOR_HTFLOORZ
, 0, 0 },
{ "htceilingz", ACTOR_HTCEILINGZ
, 0, 0 },
{ "htlastvx", ACTOR_HTLASTVX
, 0, 0 },
{ "htlastvy", ACTOR_HTLASTVY
, 0, 0 },
{ "htbposx", ACTOR_HTBPOSX
, 0, 0 },
{ "htbposy", ACTOR_HTBPOSY
, 0, 0 },
{ "htbposz", ACTOR_HTBPOSZ
, 0, 0 },
{ "htg_t", ACTOR_HTG_T
, LABEL_HASPARM2
, 10 },
// model flags
{ "angoff", ACTOR_ANGOFF
, 0, 0 },
{ "pitch", ACTOR_PITCH
, 0, 0 },
{ "roll", ACTOR_ROLL
, 0, 0 },
{ "mdxoff", ACTOR_MDXOFF
, 0, 0 },
{ "mdyoff", ACTOR_MDYOFF
, 0, 0 },
{ "mdzoff", ACTOR_MDZOFF
, 0, 0 },
{ "mdflags", ACTOR_MDFLAGS
, 0, 0 },
{ "xpanning", ACTOR_XPANNING
, 0, 0 },
{ "ypanning", ACTOR_YPANNING
, 0, 0 },
{ "htflags", ACTOR_HTFLAGS
, 0, 0 },
{ "alpha", ACTOR_ALPHA
, 0, 0 },
{ "ulotag", ACTOR_ULOTAG
, 0, 0 },
{ "uhitag", ACTOR_UHITAG
, 0, 0 },
{ "isvalid", ACTOR_ISVALID
, 0, 0 },
// aliases:
{ "movflags", ACTOR_HITAG
, 0, 0 },
{ "detail", ACTOR_DETAIL
, 0, 0 }, // deprecated name for 'blend'
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t TsprLabels
[]=
{
// tsprite access
{ "tsprx", ACTOR_X
, 0, 0 },
{ "tspry", ACTOR_Y
, 0, 0 },
{ "tsprz", ACTOR_Z
, 0, 0 },
{ "tsprcstat", ACTOR_CSTAT
, 0, 0 },
{ "tsprpicnum", ACTOR_PICNUM
, 0, 0 },
{ "tsprshade", ACTOR_SHADE
, 0, 0 },
{ "tsprpal", ACTOR_PAL
, 0, 0 },
{ "tsprclipdist", ACTOR_CLIPDIST
, 0, 0 },
// { "tsprfiller", ACTOR_DETAIL, 0, 0 },
{ "tsprblend", ACTOR_DETAIL
, 0, 0 },
{ "tsprxrepeat", ACTOR_XREPEAT
, 0, 0 },
{ "tspryrepeat", ACTOR_YREPEAT
, 0, 0 },
{ "tsprxoffset", ACTOR_XOFFSET
, 0, 0 },
{ "tspryoffset", ACTOR_YOFFSET
, 0, 0 },
{ "tsprsectnum", ACTOR_SECTNUM
, 0, 0 },
{ "tsprstatnum", ACTOR_STATNUM
, 0, 0 },
{ "tsprang", ACTOR_ANG
, 0, 0 },
{ "tsprowner", ACTOR_OWNER
, 0, 0 },
#if 1
{ "tsprxvel", ACTOR_XVEL
, 0, 0 },
{ "tspryvel", ACTOR_YVEL
, 0, 0 },
{ "tsprzvel", ACTOR_ZVEL
, 0, 0 },
{ "tsprlotag", ACTOR_LOTAG
, 0, 0 },
{ "tsprhitag", ACTOR_HITAG
, 0, 0 },
{ "tsprextra", ACTOR_EXTRA
, 0, 0 },
#endif
// aliases:
{ "tsprdetail", ACTOR_DETAIL
, 0, 0 }, // deprecated name for 'tsprblend'
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t PlayerLabels
[]=
{
{ "zoom", PLAYER_ZOOM
, 0, 0 },
{ "exitx", PLAYER_EXITX
, 0, 0 },
{ "exity", PLAYER_EXITY
, 0, 0 },
{ "loogiex", PLAYER_LOOGIEX
, LABEL_HASPARM2
, 64 },
{ "loogiey", PLAYER_LOOGIEY
, LABEL_HASPARM2
, 64 },
{ "numloogs", PLAYER_NUMLOOGS
, 0, 0 },
{ "loogcnt", PLAYER_LOOGCNT
, 0, 0 },
{ "posx", PLAYER_POSX
, 0, 0 },
{ "posy", PLAYER_POSY
, 0, 0 },
{ "posz", PLAYER_POSZ
, 0, 0 },
{ "horiz", PLAYER_HORIZ
, 0, 0 },
{ "ohoriz", PLAYER_OHORIZ
, 0, 0 },
{ "ohorizoff", PLAYER_OHORIZOFF
, 0, 0 },
{ "invdisptime", PLAYER_INVDISPTIME
, 0, 0 },
{ "bobposx", PLAYER_BOBPOSX
, 0, 0 },
{ "bobposy", PLAYER_BOBPOSY
, 0, 0 },
{ "oposx", PLAYER_OPOSX
, 0, 0 },
{ "oposy", PLAYER_OPOSY
, 0, 0 },
{ "oposz", PLAYER_OPOSZ
, 0, 0 },
{ "pyoff", PLAYER_PYOFF
, 0, 0 },
{ "opyoff", PLAYER_OPYOFF
, 0, 0 },
{ "posxv", PLAYER_POSXV
, 0, 0 },
{ "posyv", PLAYER_POSYV
, 0, 0 },
{ "poszv", PLAYER_POSZV
, 0, 0 },
{ "last_pissed_time", PLAYER_LAST_PISSED_TIME
, 0, 0 },
{ "truefz", PLAYER_TRUEFZ
, 0, 0 },
{ "truecz", PLAYER_TRUECZ
, 0, 0 },
{ "player_par", PLAYER_PLAYER_PAR
, 0, 0 },
{ "visibility", PLAYER_VISIBILITY
, 0, 0 },
{ "bobcounter", PLAYER_BOBCOUNTER
, 0, 0 },
{ "weapon_sway", PLAYER_WEAPON_SWAY
, 0, 0 },
{ "pals_time", PLAYER_PALS_TIME
, 0, 0 },
{ "randomflamex", PLAYER_RANDOMFLAMEX
, 0, 0 },
{ "crack_time", PLAYER_CRACK_TIME
, 0, 0 },
{ "aim_mode", PLAYER_AIM_MODE
, 0, 0 },
{ "ang", PLAYER_ANG
, 0, 0 },
{ "oang", PLAYER_OANG
, 0, 0 },
{ "angvel", PLAYER_ANGVEL
, 0, 0 },
{ "cursectnum", PLAYER_CURSECTNUM
, 0, 0 },
{ "look_ang", PLAYER_LOOK_ANG
, 0, 0 },
{ "last_extra", PLAYER_LAST_EXTRA
, 0, 0 },
{ "subweapon", PLAYER_SUBWEAPON
, 0, 0 },
{ "ammo_amount", PLAYER_AMMO_AMOUNT
, LABEL_HASPARM2
, MAX_WEAPONS
},
{ "wackedbyactor", PLAYER_WACKEDBYACTOR
, 0, 0 },
{ "frag", PLAYER_FRAG
, 0, 0 },
{ "fraggedself", PLAYER_FRAGGEDSELF
, 0, 0 },
{ "curr_weapon", PLAYER_CURR_WEAPON
, 0, 0 },
{ "last_weapon", PLAYER_LAST_WEAPON
, 0, 0 },
{ "tipincs", PLAYER_TIPINCS
, 0, 0 },
{ "horizoff", PLAYER_HORIZOFF
, 0, 0 },
{ "wantweaponfire", PLAYER_WANTWEAPONFIRE
, 0, 0 },
{ "holoduke_amount", PLAYER_HOLODUKE_AMOUNT
, 0, 0 },
{ "newowner", PLAYER_NEWOWNER
, 0, 0 },
{ "hurt_delay", PLAYER_HURT_DELAY
, 0, 0 },
{ "hbomb_hold_delay", PLAYER_HBOMB_HOLD_DELAY
, 0, 0 },
{ "jumping_counter", PLAYER_JUMPING_COUNTER
, 0, 0 },
{ "airleft", PLAYER_AIRLEFT
, 0, 0 },
{ "knee_incs", PLAYER_KNEE_INCS
, 0, 0 },
{ "access_incs", PLAYER_ACCESS_INCS
, 0, 0 },
{ "fta", PLAYER_FTA
, 0, 0 },
{ "ftq", PLAYER_FTQ
, 0, 0 },
{ "access_wallnum", PLAYER_ACCESS_WALLNUM
, 0, 0 },
{ "access_spritenum", PLAYER_ACCESS_SPRITENUM
, 0, 0 },
{ "kickback_pic", PLAYER_KICKBACK_PIC
, 0, 0 },
{ "got_access", PLAYER_GOT_ACCESS
, 0, 0 },
{ "weapon_ang", PLAYER_WEAPON_ANG
, 0, 0 },
{ "firstaid_amount", PLAYER_FIRSTAID_AMOUNT
, 0, 0 },
{ "somethingonplayer", PLAYER_SOMETHINGONPLAYER
, 0, 0 },
{ "on_crane", PLAYER_ON_CRANE
, 0, 0 },
{ "i", PLAYER_I
, 0, 0 },
{ "one_parallax_sectnum", PLAYER_ONE_PARALLAX_SECTNUM
, 0, 0 },
{ "over_shoulder_on", PLAYER_OVER_SHOULDER_ON
, 0, 0 },
{ "random_club_frame", PLAYER_RANDOM_CLUB_FRAME
, 0, 0 },
{ "fist_incs", PLAYER_FIST_INCS
, 0, 0 },
{ "one_eighty_count", PLAYER_ONE_EIGHTY_COUNT
, 0, 0 },
{ "cheat_phase", PLAYER_CHEAT_PHASE
, 0, 0 },
{ "dummyplayersprite", PLAYER_DUMMYPLAYERSPRITE
, 0, 0 },
{ "extra_extra8", PLAYER_EXTRA_EXTRA8
, 0, 0 },
{ "quick_kick", PLAYER_QUICK_KICK
, 0, 0 },
{ "heat_amount", PLAYER_HEAT_AMOUNT
, 0, 0 },
{ "actorsqu", PLAYER_ACTORSQU
, 0, 0 },
{ "timebeforeexit", PLAYER_TIMEBEFOREEXIT
, 0, 0 },
{ "customexitsound", PLAYER_CUSTOMEXITSOUND
, 0, 0 },
{ "weaprecs", PLAYER_WEAPRECS
, LABEL_HASPARM2
, MAX_WEAPONS
},
{ "weapreccnt", PLAYER_WEAPRECCNT
, 0, 0 },
{ "interface_toggle_flag", PLAYER_INTERFACE_TOGGLE_FLAG
, 0, 0 },
{ "rotscrnang", PLAYER_ROTSCRNANG
, 0, 0 },
{ "dead_flag", PLAYER_DEAD_FLAG
, 0, 0 },
{ "show_empty_weapon", PLAYER_SHOW_EMPTY_WEAPON
, 0, 0 },
{ "scuba_amount", PLAYER_SCUBA_AMOUNT
, 0, 0 },
{ "jetpack_amount", PLAYER_JETPACK_AMOUNT
, 0, 0 },
{ "steroids_amount", PLAYER_STEROIDS_AMOUNT
, 0, 0 },
{ "shield_amount", PLAYER_SHIELD_AMOUNT
, 0, 0 },
{ "holoduke_on", PLAYER_HOLODUKE_ON
, 0, 0 },
{ "pycount", PLAYER_PYCOUNT
, 0, 0 },
{ "weapon_pos", PLAYER_WEAPON_POS
, 0, 0 },
{ "frag_ps", PLAYER_FRAG_PS
, 0, 0 },
{ "transporter_hold", PLAYER_TRANSPORTER_HOLD
, 0, 0 },
{ "last_full_weapon", PLAYER_LAST_FULL_WEAPON
, 0, 0 },
{ "footprintshade", PLAYER_FOOTPRINTSHADE
, 0, 0 },
{ "boot_amount", PLAYER_BOOT_AMOUNT
, 0, 0 },
{ "scream_voice", PLAYER_SCREAM_VOICE
, 0, 0 },
{ "gm", PLAYER_GM
, 0, 0 },
{ "on_warping_sector", PLAYER_ON_WARPING_SECTOR
, 0, 0 },
{ "footprintcount", PLAYER_FOOTPRINTCOUNT
, 0, 0 },
{ "hbomb_on", PLAYER_HBOMB_ON
, 0, 0 },
{ "jumping_toggle", PLAYER_JUMPING_TOGGLE
, 0, 0 },
{ "rapid_fire_hold", PLAYER_RAPID_FIRE_HOLD
, 0, 0 },
{ "on_ground", PLAYER_ON_GROUND
, 0, 0 },
{ "name", PLAYER_NAME
, LABEL_ISSTRING
, 32 },
{ "inven_icon", PLAYER_INVEN_ICON
, 0, 0 },
{ "buttonpalette", PLAYER_BUTTONPALETTE
, 0, 0 },
{ "jetpack_on", PLAYER_JETPACK_ON
, 0, 0 },
{ "spritebridge", PLAYER_SPRITEBRIDGE
, 0, 0 },
{ "lastrandomspot", PLAYER_LASTRANDOMSPOT
, 0, 0 },
{ "scuba_on", PLAYER_SCUBA_ON
, 0, 0 },
{ "footprintpal", PLAYER_FOOTPRINTPAL
, 0, 0 },
{ "heat_on", PLAYER_HEAT_ON
, 0, 0 },
{ "holster_weapon", PLAYER_HOLSTER_WEAPON
, 0, 0 },
{ "falling_counter", PLAYER_FALLING_COUNTER
, 0, 0 },
{ "gotweapon", PLAYER_GOTWEAPON
, LABEL_HASPARM2
, MAX_WEAPONS
},
{ "refresh_inventory", PLAYER_REFRESH_INVENTORY
, 0, 0 },
{ "palette", PLAYER_PALETTE
, 0, 0 },
{ "toggle_key_flag", PLAYER_TOGGLE_KEY_FLAG
, 0, 0 },
{ "knuckle_incs", PLAYER_KNUCKLE_INCS
, 0, 0 },
{ "walking_snd_toggle", PLAYER_WALKING_SND_TOGGLE
, 0, 0 },
{ "palookup", PLAYER_PALOOKUP
, 0, 0 },
{ "hard_landing", PLAYER_HARD_LANDING
, 0, 0 },
{ "max_secret_rooms", PLAYER_MAX_SECRET_ROOMS
, 0, 0 },
{ "secret_rooms", PLAYER_SECRET_ROOMS
, 0, 0 },
{ "pals", PLAYER_PALS
, LABEL_HASPARM2
, 3 },
{ "max_actors_killed", PLAYER_MAX_ACTORS_KILLED
, 0, 0 },
{ "actors_killed", PLAYER_ACTORS_KILLED
, 0, 0 },
{ "return_to_center", PLAYER_RETURN_TO_CENTER
, 0, 0 },
{ "runspeed", PLAYER_RUNSPEED
, 0, 0 },
{ "sbs", PLAYER_SBS
, 0, 0 },
{ "reloading", PLAYER_RELOADING
, 0, 0 },
{ "auto_aim", PLAYER_AUTO_AIM
, 0, 0 },
{ "movement_lock", PLAYER_MOVEMENT_LOCK
, 0, 0 },
{ "sound_pitch", PLAYER_SOUND_PITCH
, 0, 0 },
{ "weaponswitch", PLAYER_WEAPONSWITCH
, 0, 0 },
{ "team", PLAYER_TEAM
, 0, 0 },
{ "max_player_health", PLAYER_MAX_PLAYER_HEALTH
, 0, 0 },
{ "max_shield_amount", PLAYER_MAX_SHIELD_AMOUNT
, 0, 0 },
{ "max_ammo_amount", PLAYER_MAX_AMMO_AMOUNT
, LABEL_HASPARM2
, MAX_WEAPONS
},
{ "last_quick_kick", PLAYER_LAST_QUICK_KICK
, 0, 0 },
{ "autostep", PLAYER_AUTOSTEP
, 0, 0 },
{ "autostep_sbw", PLAYER_AUTOSTEP_SBW
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t ProjectileLabels
[]=
{
{ "workslike", PROJ_WORKSLIKE
, 0, 0 },
{ "spawns", PROJ_SPAWNS
, 0, 0 },
{ "sxrepeat", PROJ_SXREPEAT
, 0, 0 },
{ "syrepeat", PROJ_SYREPEAT
, 0, 0 },
{ "sound", PROJ_SOUND
, 0, 0 },
{ "isound", PROJ_ISOUND
, 0, 0 },
{ "vel", PROJ_VEL
, 0, 0 },
{ "extra", PROJ_EXTRA
, 0, 0 },
{ "decal", PROJ_DECAL
, 0, 0 },
{ "trail", PROJ_TRAIL
, 0, 0 },
{ "txrepeat", PROJ_TXREPEAT
, 0, 0 },
{ "tyrepeat", PROJ_TYREPEAT
, 0, 0 },
{ "toffset", PROJ_TOFFSET
, 0, 0 },
{ "tnum", PROJ_TNUM
, 0, 0 },
{ "drop", PROJ_DROP
, 0, 0 },
{ "cstat", PROJ_CSTAT
, 0, 0 },
{ "clipdist", PROJ_CLIPDIST
, 0, 0 },
{ "shade", PROJ_SHADE
, 0, 0 },
{ "xrepeat", PROJ_XREPEAT
, 0, 0 },
{ "yrepeat", PROJ_YREPEAT
, 0, 0 },
{ "pal", PROJ_PAL
, 0, 0 },
{ "extra_rand", PROJ_EXTRA_RAND
, 0, 0 },
{ "hitradius", PROJ_HITRADIUS
, 0, 0 },
{ "velmult", PROJ_MOVECNT
, 0, 0 },
{ "offset", PROJ_OFFSET
, 0, 0 },
{ "bounces", PROJ_BOUNCES
, 0, 0 },
{ "bsound", PROJ_BSOUND
, 0, 0 },
{ "range", PROJ_RANGE
, 0, 0 },
{ "flashcolor", PROJ_FLASH_COLOR
, 0, 0 },
{ "userdata", PROJ_USERDATA
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t UserdefsLabels
[]=
{
// { "<null>", 1, 0, 0 },
{ "god", USERDEFS_GOD
, 0, 0 },
{ "warp_on", USERDEFS_WARP_ON
, 0, 0 },
{ "cashman", USERDEFS_CASHMAN
, 0, 0 },
{ "eog", USERDEFS_EOG
, 0, 0 },
{ "showallmap", USERDEFS_SHOWALLMAP
, 0, 0 },
{ "show_help", USERDEFS_SHOW_HELP
, 0, 0 },
{ "scrollmode", USERDEFS_SCROLLMODE
, 0, 0 },
{ "clipping", USERDEFS_CLIPPING
, 0, 0 },
{ "user_name", USERDEFS_USER_NAME
, LABEL_HASPARM2
, MAXPLAYERS
},
{ "ridecule", USERDEFS_RIDECULE
, LABEL_HASPARM2
| LABEL_ISSTRING
, 10 },
{ "savegame", USERDEFS_SAVEGAME
, LABEL_HASPARM2
| LABEL_ISSTRING
, 10 },
{ "pwlockout", USERDEFS_PWLOCKOUT
, LABEL_ISSTRING
, 128 },
{ "rtsname;", USERDEFS_RTSNAME
, LABEL_ISSTRING
, 128 },
{ "overhead_on", USERDEFS_OVERHEAD_ON
, 0, 0 },
{ "last_overhead", USERDEFS_LAST_OVERHEAD
, 0, 0 },
{ "showweapons", USERDEFS_SHOWWEAPONS
, 0, 0 },
{ "pause_on", USERDEFS_PAUSE_ON
, 0, 0 },
{ "from_bonus", USERDEFS_FROM_BONUS
, 0, 0 },
{ "camerasprite", USERDEFS_CAMERASPRITE
, 0, 0 },
{ "last_camsprite", USERDEFS_LAST_CAMSPRITE
, 0, 0 },
{ "last_level", USERDEFS_LAST_LEVEL
, 0, 0 },
{ "secretlevel", USERDEFS_SECRETLEVEL
, 0, 0 },
{ "playerbest", USERDEFS_PLAYERBEST
, 0, 0 },
{ "const_visibility", USERDEFS_CONST_VISIBILITY
, 0, 0 },
{ "uw_framerate", USERDEFS_UW_FRAMERATE
, 0, 0 },
{ "camera_time", USERDEFS_CAMERA_TIME
, 0, 0 },
{ "folfvel", USERDEFS_FOLFVEL
, 0, 0 },
{ "folavel", USERDEFS_FOLAVEL
, 0, 0 },
{ "folx", USERDEFS_FOLX
, 0, 0 },
{ "foly", USERDEFS_FOLY
, 0, 0 },
{ "fola", USERDEFS_FOLA
, 0, 0 },
{ "reccnt", USERDEFS_RECCNT
, 0, 0 },
{ "m_origin_x", USERDEFS_M_ORIGIN_X
, 0, 0 },
{ "m_origin_y", USERDEFS_M_ORIGIN_Y
, 0, 0 },
{ "usevoxels", USERDEFS_USEVOXELS
, 0, 0 },
{ "usehightile", USERDEFS_USEHIGHTILE
, 0, 0 },
{ "usemodels", USERDEFS_USEMODELS
, 0, 0 },
{ "entered_name", USERDEFS_ENTERED_NAME
, 0, 0 },
{ "screen_tilting", USERDEFS_SCREEN_TILTING
, 0, 0 },
{ "shadows", USERDEFS_SHADOWS
, 0, 0 },
{ "fta_on", USERDEFS_FTA_ON
, 0, 0 },
{ "executions", USERDEFS_EXECUTIONS
, 0, 0 },
{ "auto_run", USERDEFS_AUTO_RUN
, 0, 0 },
{ "coords", USERDEFS_COORDS
, 0, 0 },
{ "tickrate", USERDEFS_TICKRATE
, 0, 0 },
{ "m_coop", USERDEFS_M_COOP
, 0, 0 },
{ "coop", USERDEFS_COOP
, 0, 0 },
{ "screen_size", USERDEFS_SCREEN_SIZE
, 0, 0 },
{ "lockout", USERDEFS_LOCKOUT
, 0, 0 },
{ "crosshair", USERDEFS_CROSSHAIR
, 0, 0 },
// { "wchoice[MAXPLAYERS][MAX_WEAPONS]", USERDEFS_WCHOICE, 0, 0 },
{ "playerai", USERDEFS_PLAYERAI
, 0, 0 },
{ "respawn_monsters", USERDEFS_RESPAWN_MONSTERS
, 0, 0 },
{ "respawn_items", USERDEFS_RESPAWN_ITEMS
, 0, 0 },
{ "respawn_inventory", USERDEFS_RESPAWN_INVENTORY
, 0, 0 },
{ "recstat", USERDEFS_RECSTAT
, 0, 0 },
{ "monsters_off", USERDEFS_MONSTERS_OFF
, 0, 0 },
{ "brightness", USERDEFS_BRIGHTNESS
, 0, 0 },
{ "m_respawn_items", USERDEFS_M_RESPAWN_ITEMS
, 0, 0 },
{ "m_respawn_monsters", USERDEFS_M_RESPAWN_MONSTERS
, 0, 0 },
{ "m_respawn_inventory", USERDEFS_M_RESPAWN_INVENTORY
, 0, 0 },
{ "m_recstat", USERDEFS_M_RECSTAT
, 0, 0 },
{ "m_monsters_off", USERDEFS_M_MONSTERS_OFF
, 0, 0 },
{ "detail", USERDEFS_DETAIL
, 0, 0 },
{ "m_ffire", USERDEFS_M_FFIRE
, 0, 0 },
{ "ffire", USERDEFS_FFIRE
, 0, 0 },
{ "m_player_skill", USERDEFS_M_PLAYER_SKILL
, 0, 0 },
{ "m_level_number", USERDEFS_M_LEVEL_NUMBER
, 0, 0 },
{ "m_volume_number", USERDEFS_M_VOLUME_NUMBER
, 0, 0 },
{ "multimode", USERDEFS_MULTIMODE
, 0, 0 },
{ "player_skill", USERDEFS_PLAYER_SKILL
, 0, 0 },
{ "level_number", USERDEFS_LEVEL_NUMBER
, 0, 0 },
{ "volume_number", USERDEFS_VOLUME_NUMBER
, 0, 0 },
{ "m_marker", USERDEFS_M_MARKER
, 0, 0 },
{ "marker", USERDEFS_MARKER
, 0, 0 },
{ "mouseflip", USERDEFS_MOUSEFLIP
, 0, 0 },
{ "statusbarscale", USERDEFS_STATUSBARSCALE
, 0, 0 },
{ "drawweapon", USERDEFS_DRAWWEAPON
, 0, 0 },
{ "mouseaiming", USERDEFS_MOUSEAIMING
, 0, 0 },
{ "weaponswitch", USERDEFS_WEAPONSWITCH
, 0, 0 },
{ "democams", USERDEFS_DEMOCAMS
, 0, 0 },
{ "color", USERDEFS_COLOR
, 0, 0 },
{ "msgdisptime", USERDEFS_MSGDISPTIME
, 0, 0 },
{ "statusbarmode", USERDEFS_STATUSBARMODE
, 0, 0 },
{ "m_noexits", USERDEFS_M_NOEXITS
, 0, 0 },
{ "noexits", USERDEFS_NOEXITS
, 0, 0 },
{ "autovote", USERDEFS_AUTOVOTE
, 0, 0 },
{ "automsg", USERDEFS_AUTOMSG
, 0, 0 },
{ "idplayers", USERDEFS_IDPLAYERS
, 0, 0 },
{ "team", USERDEFS_TEAM
, 0, 0 },
{ "viewbob", USERDEFS_VIEWBOB
, 0, 0 },
{ "weaponsway", USERDEFS_WEAPONSWAY
, 0, 0 },
{ "angleinterpolation", USERDEFS_ANGLEINTERPOLATION
, 0, 0 },
{ "obituaries", USERDEFS_OBITUARIES
, 0, 0 },
{ "levelstats", USERDEFS_LEVELSTATS
, 0, 0 },
{ "crosshairscale", USERDEFS_CROSSHAIRSCALE
, 0, 0 },
{ "althud", USERDEFS_ALTHUD
, 0, 0 },
{ "display_bonus_screen", USERDEFS_DISPLAY_BONUS_SCREEN
, 0, 0 },
{ "show_level_text", USERDEFS_SHOW_LEVEL_TEXT
, 0, 0 },
{ "weaponscale", USERDEFS_WEAPONSCALE
, 0, 0 },
{ "textscale", USERDEFS_TEXTSCALE
, 0, 0 },
{ "runkey_mode", USERDEFS_RUNKEY_MODE
, 0, 0 },
{ "musictoggle", USERDEFS_MUSICTOGGLE
, 0, 0 },
{ "gametypeflags", USERDEFS_GAMETYPEFLAGS
, 0, 0 },
{ "m_gametypeflags", USERDEFS_M_GAMETYPEFLAGS
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
const memberlabel_t InputLabels
[]=
{
{ "avel", INPUT_AVEL
, 0, 0 },
{ "horz", INPUT_HORZ
, 0, 0 },
{ "fvel", INPUT_FVEL
, 0, 0 },
{ "svel", INPUT_SVEL
, 0, 0 },
{ "bits", INPUT_BITS
, 0, 0 },
{ "extbits", INPUT_EXTBITS
, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST
};
#endif
char *bitptr
; // pointer to bitmap of which bytecode positions contain pointers
#define BITPTR_POINTER 1
#if !defined LUNATIC
hashtable_t h_gamevars
= { MAXGAMEVARS
>>1, NULL
};
hashtable_t h_arrays
= { MAXGAMEARRAYS
>>1, NULL
};
hashtable_t h_labels
= { 11264>>1, NULL
};
static hashtable_t h_keywords
= { CON_END
>>1, NULL
};
static hashtable_t sectorH
= { SECTOR_END
>>1, NULL
};
static hashtable_t wallH
= { WALL_END
>>1, NULL
};
static hashtable_t userdefH
= { USERDEFS_END
>>1, NULL
};
static hashtable_t projectileH
= { PROJ_END
>>1, NULL
};
static hashtable_t playerH
= { PLAYER_END
>>1, NULL
};
static hashtable_t inputH
= { INPUT_END
>>1, NULL
};
static hashtable_t actorH
= { ACTOR_END
>>1, NULL
};
static hashtable_t tspriteH
= { ACTOR_END
>>1, NULL
};
void C_InitHashes
()
{
int32_t i
;
hash_init
(&h_gamevars
);
hash_init
(&h_arrays
);
hash_init
(&h_labels
);
inithashnames
();
initsoundhashnames
();
hash_init
(&h_keywords
);
hash_init
(§orH
);
hash_init
(&wallH
);
hash_init
(&userdefH
);
hash_init
(&projectileH
);
hash_init
(&playerH
);
hash_init
(&inputH
);
hash_init
(&actorH
);
hash_init
(&tspriteH
);
g_scriptLastKeyword
= NUMKEYWORDS
-1;
// determine last CON keyword for backward compatibility with older mods
if (g_scriptDateVersion
< g_keywdate
[NUMKEYWDATES
-1].
date)
{
for (i
=NUMKEYWDATES
-1; i
>=0; i
--)
{
if (g_scriptDateVersion
>= g_keywdate
[i
].
date)
{
g_scriptLastKeyword
= g_keywdate
[i
].
keyw;
break;
}
}
if (i
<0)
g_scriptLastKeyword
= g_keywdate
[0].
keyw-1; // may be slightly imprecise
}
for (i
=g_scriptLastKeyword
; i
>=0; i
--) hash_add
(&h_keywords
,keyw
[i
],i
,0);
for (i
=0; SectorLabels
[i
].
lId >= 0; i
++) hash_add
(§orH
,SectorLabels
[i
].
name,i
,0);
for (i
=0; WallLabels
[i
].
lId >= 0; i
++) hash_add
(&wallH
,WallLabels
[i
].
name,i
,0);
for (i
=0; UserdefsLabels
[i
].
lId >= 0; i
++) hash_add
(&userdefH
,UserdefsLabels
[i
].
name,i
,0);
for (i
=0; ProjectileLabels
[i
].
lId >= 0; i
++) hash_add
(&projectileH
,ProjectileLabels
[i
].
name,i
,0);
for (i
=0; PlayerLabels
[i
].
lId >= 0; i
++) hash_add
(&playerH
,PlayerLabels
[i
].
name,i
,0);
for (i
=0; InputLabels
[i
].
lId >= 0; i
++) hash_add
(&inputH
,InputLabels
[i
].
name,i
,0);
for (i
=0; ActorLabels
[i
].
lId >= 0; i
++) hash_add
(&actorH
,ActorLabels
[i
].
name,i
,0);
for (i
=0; TsprLabels
[i
].
lId >= 0; i
++) hash_add
(&tspriteH
,TsprLabels
[i
].
name,i
,0);
}
// "magic" number for { and }, overrides line number in compiled code for later detection
#define IFELSE_MAGIC 31337
static int32_t g_ifElseAborted
;
static int32_t C_SetScriptSize
(int32_t newsize
)
{
intptr_t oscriptPtr
= (unsigned)(g_scriptPtr
-script
);
intptr_t ocaseScriptPtr
= (unsigned)(g_caseScriptPtr
-script
);
intptr_t oparsingEventPtr
= (unsigned)(g_parsingEventPtr
-script
);
intptr_t oparsingActorPtr
= (unsigned)(g_parsingActorPtr
-script
);
intptr_t *newscript
;
intptr_t i
, j
;
int32_t osize
= g_scriptSize
;
char *scriptptrs
;
char *newbitptr
;
scriptptrs
= (char *)Xcalloc
(1, g_scriptSize
* sizeof(uint8_t));
for (i
=g_scriptSize
-1; i
>=0; i
--)
{
if (bitptr
[i
>>3]&(BITPTR_POINTER
<<(i
&7)))
{
if (EDUKE32_PREDICT_FALSE
((intptr_t)script
[i
] < (intptr_t)&script
[0] || (intptr_t)script
[i
] >= (intptr_t)&script
[g_scriptSize
]))
{
g_numCompilerErrors
++;
initprintf
("Internal compiler error at %" PRIdPTR
" (0x%" PRIxPTR
")\n",i
,i
);
}
scriptptrs
[i
] = 1;
script
[i
] -= (intptr_t)&script
[0];
}
else scriptptrs
[i
] = 0;
}
G_Util_PtrToIdx2
(&g_tile
[0].
execPtr, MAXTILES
, sizeof(tiledata_t
), script
, P2I_FWD_NON0
);
G_Util_PtrToIdx2
(&g_tile
[0].
loadPtr, MAXTILES
, sizeof(tiledata_t
), script
, P2I_FWD_NON0
);
G_Util_PtrToIdx
(apScriptGameEvent
, MAXGAMEEVENTS
, script
, P2I_FWD_NON0
);
initprintf
("Resizing code buffer to %d*%d bytes\n",newsize
, (int32_t)sizeof(intptr_t));
newscript
= (intptr_t *)Xrealloc
(script
, newsize
* sizeof(intptr_t));
newbitptr
= (char *)Xcalloc
(1,(((newsize
+7)>>3)+1) * sizeof(uint8_t));
if (newsize
>= osize
)
{
Bmemset
(&newscript
[0]+osize
,0,(newsize
-osize
) * sizeof(uint8_t));
Bmemcpy
(newbitptr
,bitptr
,sizeof(uint8_t) *((osize
+7)>>3));
}
else
Bmemcpy
(newbitptr
,bitptr
,sizeof(uint8_t) *((newsize
+7)>>3));
Bfree
(bitptr
);
bitptr
= newbitptr
;
if (script
!= newscript
)
{
initprintf
("Relocating compiled code from to 0x%" PRIxPTR
" to 0x%" PRIxPTR
"\n", (intptr_t)script
, (intptr_t)newscript
);
script
= newscript
;
}
g_scriptSize
= newsize
;
g_scriptPtr
= (intptr_t *)(script
+oscriptPtr
);
if (g_caseScriptPtr
)
g_caseScriptPtr
= (intptr_t *)(script
+ocaseScriptPtr
);
if (g_parsingEventPtr
)
g_parsingEventPtr
= (intptr_t *)(script
+oparsingEventPtr
);
if (g_parsingActorPtr
)
g_parsingActorPtr
= (intptr_t *)(script
+oparsingActorPtr
);
for (i
=(((newsize
>=osize
)?osize
:newsize
))-1; i
>=0; i
--)
if (scriptptrs
[i
])
{
j
= (intptr_t)script
[i
]+(intptr_t)&script
[0];
script
[i
] = j
;
}
G_Util_PtrToIdx2
(&g_tile
[0].
execPtr, MAXTILES
, sizeof(tiledata_t
), script
, P2I_BACK_NON0
);
G_Util_PtrToIdx2
(&g_tile
[0].
loadPtr, MAXTILES
, sizeof(tiledata_t
), script
, P2I_BACK_NON0
);
G_Util_PtrToIdx
(apScriptGameEvent
, MAXGAMEEVENTS
, script
, P2I_BACK_NON0
);
Bfree
(scriptptrs
);
return 0;
}
static int32_t ispecial
(const char c
)
{
if (c
== ' ' || c
== 0x0d || c
== '(' || c
== ')' ||
c
== ',' || c
== ';' || (c
== 0x0a /*&& ++g_lineNumber*/))
return 1;
return 0;
}
#define C_NextLine() while (*textptr != 0x0a && *textptr != 0x0d && *textptr != 0) textptr++
static int32_t C_SkipComments
(void)
{
do
{
switch (*textptr
)
{
case '\n':
g_lineNumber
++;
case ' ':
case '\t':
case '\r':
case 0x1a:
textptr
++;
break;
case '/':
switch (textptr
[1])
{
case '/': // C++ style comment
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: got comment.\n",g_szScriptFileName
,g_lineNumber
);
C_NextLine
();
continue;
case '*': // beginning of a C style comment
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: got start of comment block.\n",g_szScriptFileName
,g_lineNumber
);
do
{
if (*textptr
== '\n')
g_lineNumber
++;
textptr
++;
}
while (*textptr
&& (textptr
[0] != '*' || textptr
[1] != '/'));
if (EDUKE32_PREDICT_FALSE
(!*textptr
))
{
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
)
initprintf
("%s:%d: debug: EOF in comment!\n",g_szScriptFileName
,g_lineNumber
);
C_ReportError
(-1);
initprintf
("%s:%d: error: found `/*' with no `*/'.\n",g_szScriptFileName
,g_lineNumber
);
g_parsingActorPtr
= NULL
; g_processingState
= g_numBraces
= 0;
g_numCompilerErrors
++;
continue;
}
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: got end of comment block.\n",g_szScriptFileName
,g_lineNumber
);
textptr
+=2;
continue;
}
continue;
default:
if (ispecial
(*textptr
))
{
textptr
++;
continue;
}
case 0: // EOF
return ((g_scriptPtr
-script
) > (g_scriptSize
-32)) ? C_SetScriptSize
(g_scriptSize
<<1) : 0;
}
}
while (1);
}
#define GetDefID(szGameLabel) hash_find(&h_gamevars,szGameLabel)
#define GetADefID(szGameLabel) hash_find(&h_arrays,szGameLabel)
static int32_t isaltok
(const char c
)
{
return (isalnum(c
) || c
== '{' || c
== '}' || c
== '/' || c
== '\\' ||
c
== '*' || c
== '-' || c
== '_' || c
== '.');
}
static int32_t C_IsLabelChar
(const char c
, int32_t i
)
{
return (isalnum(c
) || c
=='_' || c
=='*' || c
=='?' ||
(i
> 0 && (c
=='+' || c
=='-' || c
=='.')));
}
static inline int32_t C_GetLabelNameID
(const memberlabel_t
*pLabel
, hashtable_t
*tH
, const char *psz
)
{
// find the label psz in the table pLabel.
// returns the ID for the label, or -1
int32_t l
= hash_findcase
(tH
,psz
);
return (l
>= 0) ? pLabel
[l
].
lId : -1;
}
static inline int32_t C_GetLabelNameOffset
(hashtable_t
*tH
, const char *psz
)
{
// find the label psz in the table pLabel.
// returns the offset in the array for the label, or -1
return hash_findcase
(tH
,psz
);
}
static void C_GetNextLabelName
(void)
{
int32_t i
= 0;
C_SkipComments
();
// while (ispecial(*textptr) == 0 && *textptr!='['&& *textptr!=']' && *textptr!='\t' && *textptr!='\n' && *textptr!='\r')
while (C_IsLabelChar
(*textptr
, i
))
label
[(g_numLabels
<<6)+(i
++)] = *(textptr
++);
label
[(g_numLabels
<<6)+i
] = 0;
if (!(g_numCompilerErrors
|g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: got label `%s'.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
}
static int32_t C_GetKeyword
(void)
{
int32_t i
;
char *temptextptr
;
C_SkipComments
();
temptextptr
= textptr
;
if (*temptextptr
== 0) // EOF
return -2;
while (isaltok
(*temptextptr
) == 0)
{
temptextptr
++;
if (*temptextptr
== 0)
return 0;
}
i
= 0;
while (isaltok
(*temptextptr
))
tempbuf
[i
++] = *(temptextptr
++);
tempbuf
[i
] = 0;
return hash_find
(&h_keywords
,tempbuf
);
}
static int32_t C_GetNextKeyword
(void) //Returns its code #
{
int32_t i
, l
;
C_SkipComments
();
if (*textptr
== 0) // EOF
return -2;
l
= 0;
while (isaltok
(*(textptr
+l
)))
{
tempbuf
[l
] = textptr
[l
];
l
++;
}
tempbuf
[l
] = 0;
if (EDUKE32_PREDICT_TRUE
((i
= hash_find
(&h_keywords
,tempbuf
)) >= 0))
{
if (i
== CON_LEFTBRACE
|| i
== CON_RIGHTBRACE
|| i
== CON_NULLOP
)
*g_scriptPtr
= i
+ (IFELSE_MAGIC
<<12);
else *g_scriptPtr
= i
+ (g_lineNumber
<<12);
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
textptr
+= l
;
g_scriptPtr
++;
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
)
initprintf
("%s:%d: debug: translating keyword `%s'.\n",g_szScriptFileName
,g_lineNumber
,keyw
[i
]);
return i
;
}
textptr
+= l
;
g_numCompilerErrors
++;
if (EDUKE32_PREDICT_FALSE
((tempbuf
[0] == '{' || tempbuf
[0] == '}') && tempbuf
[1] != 0))
{
C_ReportError
(-1);
initprintf
("%s:%d: error: expected whitespace between `%c' and `%s'.\n",g_szScriptFileName
,g_lineNumber
,tempbuf
[0],tempbuf
+1);
}
else C_ReportError
(ERROR_EXPECTEDKEYWORD
);
return -1;
}
static int32_t parse_decimal_number
(void) // (textptr)
{
// decimal constants -- this is finicky business
int64_t num
= strtoll
(textptr
, NULL
, 10); // assume long long to be int64_t
if (EDUKE32_PREDICT_TRUE
(num
>= INT32_MIN
&& num
<= INT32_MAX
))
{
// all OK
}
else if (EDUKE32_PREDICT_FALSE
(num
> INT32_MAX
&& num
<= UINT32_MAX
))
{
// Number interpreted as uint32, but packed as int32 (on 32-bit archs)
// (CON code in the wild exists that does this). Note that such conversion
// is implementation-defined (C99 6.3.1.3) but GCC does the 'expected' thing.
#if 0
initprintf
("%s:%d: warning: number greater than INT32_MAX converted to a negative one.\n",
g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
#endif
}
else
{
// out of range, this is arguably worse
initprintf
("%s:%d: warning: number out of the range of a 32-bit integer encountered.\n",
g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
return (int32_t)num
;
}
static int32_t parse_hex_constant
(const char *hexnum
)
{
int64_t x
;
sscanf(hexnum
, "%" PRIx64
"", &x
);
if (EDUKE32_PREDICT_FALSE
(x
> UINT32_MAX
))
{
initprintf
("%s:%d: warning: number 0x%" PRIx64
" truncated to 32 bits.\n",
g_szScriptFileName
,g_lineNumber
, x
);
g_numCompilerWarnings
++;
}
return x
;
}
static void C_GetNextVarType
(int32_t type
)
{
int32_t i
=0,f
=0;
C_SkipComments
();
if (!type
&& !g_labelsOnly
&& (isdigit(*textptr
) || ((*textptr
== '-') && (isdigit(*(textptr
+1))))))
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++ = MAXGAMEVARS
;
if (tolower(textptr
[1])=='x') // hex constants
*g_scriptPtr
= parse_hex_constant
(textptr
+2);
else
*g_scriptPtr
= parse_decimal_number
();
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
)
initprintf
("%s:%d: debug: accepted constant %ld in place of gamevar.\n",
g_szScriptFileName
,g_lineNumber
,(long)*g_scriptPtr
);
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
g_scriptPtr
++;
#if 1
while (!ispecial
(*textptr
) && *textptr
!= ']') textptr
++;
#else
C_GetNextLabelName
();
#endif
return;
}
else if ((*textptr
== '-')/* && !isdigit(*(textptr+1))*/)
{
if (EDUKE32_PREDICT_FALSE
(type
))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
C_GetNextLabelName
();
return;
}
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
)
initprintf
("%s:%d: debug: flagging gamevar as negative.\n", g_szScriptFileName
, g_lineNumber
); //,Batol(textptr));
f
= (MAXGAMEVARS
<<1);
textptr
++;
}
C_GetNextLabelName
();
if (EDUKE32_PREDICT_FALSE
(!g_skipKeywordCheck
&& hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
return;
}
C_SkipComments
(); //skip comments and whitespace
if ((*textptr
== '[')) //read of array as a gamevar
{
int32_t lLabelID
= -1;
f
|= (MAXGAMEVARS
<<2);
textptr
++;
i
=GetADefID
(label
+(g_numLabels
<<6));
if (i
< 0)
{
i
=GetDefID
(label
+(g_numLabels
<<6));
if (i
< g_iSpriteVarID
|| i
> g_iActorVarID
)
i
= -1;
if (EDUKE32_PREDICT_FALSE
(i
< 0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEARRAY
);
return;
}
f
&= ~
(MAXGAMEVARS
<<2); // not an array
f
|= (MAXGAMEVARS
<<3);
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=(i
|f
);
C_GetNextVarType
(0);
C_SkipComments
();
if (EDUKE32_PREDICT_FALSE
(*textptr
!= ']'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_GAMEARRAYBNC
);
return;
}
textptr
++;
//writing arrays in this way is not supported because it would require too many changes to other code
if (EDUKE32_PREDICT_FALSE
(type
))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_INVALIDARRAYWRITE
);
return;
}
if (f
& (MAXGAMEVARS
<<3))
{
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!= '.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
return;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
/*initprintf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));*/
if (i
== g_iSpriteVarID
)
lLabelID
=C_GetLabelNameOffset
(&actorH
,Bstrtolower
(label
+(g_numLabels
<<6)));
else if (i
== g_iSectorVarID
)
lLabelID
=C_GetLabelNameOffset
(§orH
,Bstrtolower
(label
+(g_numLabels
<<6)));
else if (i
== g_iWallVarID
)
lLabelID
=C_GetLabelNameOffset
(&wallH
,Bstrtolower
(label
+(g_numLabels
<<6)));
else if (i
== g_iPlayerVarID
)
lLabelID
=C_GetLabelNameOffset
(&playerH
,Bstrtolower
(label
+(g_numLabels
<<6)));
else if (i
== g_iActorVarID
)
lLabelID
=GetDefID
(label
+(g_numLabels
<<6));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
return;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
if (i
== g_iSpriteVarID
)
{
*g_scriptPtr
++=ActorLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",ActorLabels[lLabelID].flags);
if (ActorLabels
[lLabelID
].
flags & LABEL_HASPARM2
)
{
//printf("Member has PARM2\n");
// get parm2
// get the ID of the DEF
C_GetNextVarType
(0);
}
}
else if (i
== g_iSectorVarID
)
*g_scriptPtr
++=SectorLabels
[lLabelID
].
lId;
else if (i
== g_iWallVarID
)
*g_scriptPtr
++=SectorLabels
[lLabelID
].
lId;
else if (i
== g_iPlayerVarID
)
{
*g_scriptPtr
++=PlayerLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",ActorLabels[lLabelID].flags);
if (PlayerLabels
[lLabelID
].
flags & LABEL_HASPARM2
)
{
//printf("Member has PARM2\n");
// get parm2
// get the ID of the DEF
C_GetNextVarType
(0);
}
}
else if (i
== g_iActorVarID
)
*g_scriptPtr
++=lLabelID
;
}
return;
}
// initprintf("not an array");
i
=GetDefID
(label
+(g_numLabels
<<6));
if (i
<0) //gamevar not found
{
if (!type
&& !g_labelsOnly
)
{
//try looking for a define instead
Bstrcpy
(tempbuf
,label
+(g_numLabels
<<6));
i
= hash_find
(&h_labels
,tempbuf
);
if (EDUKE32_PREDICT_TRUE
(i
>=0))
{
if (EDUKE32_PREDICT_TRUE
(labeltype
[i
] & LABEL_DEFINE
))
{
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
)
initprintf
("%s:%d: debug: accepted defined label `%s' instead of gamevar.\n",g_szScriptFileName
,g_lineNumber
,label
+(i
<<6));
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++ = MAXGAMEVARS
;
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++ = labelcode
[i
];
return;
}
}
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEVAR
);
return;
}
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEVAR
);
textptr
++;
return;
}
if (EDUKE32_PREDICT_FALSE
(type
== GAMEVAR_READONLY
&& aGameVars
[i
].
dwFlags & GAMEVAR_READONLY
))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_VARREADONLY
);
return;
}
else if (EDUKE32_PREDICT_FALSE
(aGameVars
[i
].
dwFlags & type
))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_VARTYPEMISMATCH
);
return;
}
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: accepted gamevar `%s'.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=(i
|f
);
}
#define C_GetNextVar() C_GetNextVarType(0)
static inline void C_GetManyVarsType
(int32_t type
, int32_t num
)
{
int32_t i
;
for (i
=num
-1; i
>=0; i
--)
C_GetNextVarType
(type
);
}
#define C_GetManyVars(num) C_GetManyVarsType(0,num)
// returns:
// -1 on EOF or wrong type or error
// 0 if literal value
// LABEL_* (>0) if that type and matched
//
// *g_scriptPtr will contain the value OR 0 if wrong type or error
static int32_t C_GetNextValue
(int32_t type
)
{
int32_t i
, l
;
C_SkipComments
();
if (*textptr
== 0) // EOF
return -1;
l
= 0;
while (isaltok
(*(textptr
+l
)))
{
tempbuf
[l
] = textptr
[l
];
l
++;
}
tempbuf
[l
] = 0;
if (EDUKE32_PREDICT_FALSE
(!g_skipKeywordCheck
&& hash_find
(&h_keywords
,tempbuf
/*label+(g_numLabels<<6)*/)>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
textptr
+=l
;
}
i
= hash_find
(&h_labels
,tempbuf
);
if (i
>=0)
{
char *el
,*gl
;
if (EDUKE32_PREDICT_TRUE
(labeltype
[i
] & type
))
{
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
{
gl
= (char *)C_GetLabelType
(labeltype
[i
]);
initprintf
("%s:%d: debug: accepted %s label `%s'.\n",g_szScriptFileName
,g_lineNumber
,gl
,label
+(i
<<6));
Bfree
(gl
);
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*(g_scriptPtr
++) = labelcode
[i
];
textptr
+= l
;
return labeltype
[i
];
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*(g_scriptPtr
++) = 0;
textptr
+= l
;
el
= (char *)C_GetLabelType
(type
);
gl
= (char *)C_GetLabelType
(labeltype
[i
]);
C_ReportError
(-1);
initprintf
("%s:%d: warning: expected %s, found %s.\n",g_szScriptFileName
,g_lineNumber
,el
,gl
);
g_numCompilerWarnings
++;
Bfree
(el
);
Bfree
(gl
);
return -1; // valid label name, but wrong type
}
if (EDUKE32_PREDICT_FALSE
(isdigit(*textptr
) == 0 && *textptr
!= '-'))
{
C_ReportError
(ERROR_PARAMUNDEFINED
);
g_numCompilerErrors
++;
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
= 0;
g_scriptPtr
++;
textptr
+=l
;
return -1; // error!
}
if (EDUKE32_PREDICT_FALSE
(isdigit(*textptr
) && g_labelsOnly
))
{
C_ReportError
(WARNING_LABELSONLY
);
g_numCompilerWarnings
++;
}
i
= l
-1;
do
{
// FIXME: check for 0-9 A-F for hex
if (textptr
[0] == '0' && textptr
[1] == 'x') break; // kill the warning for hex
if (EDUKE32_PREDICT_FALSE
(!isdigit(textptr
[i
--])))
{
C_ReportError
(-1);
initprintf
("%s:%d: warning: invalid character `%c' in definition!\n",g_szScriptFileName
,g_lineNumber
,textptr
[i
+1]);
g_numCompilerWarnings
++;
break;
}
}
while (i
> 0);
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
if (tolower(textptr
[1])=='x')
*g_scriptPtr
= parse_hex_constant
(textptr
+2);
else
*g_scriptPtr
= parse_decimal_number
();
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: accepted constant %ld.\n",
g_szScriptFileName
,g_lineNumber
,(long)*g_scriptPtr
);
g_scriptPtr
++;
textptr
+= l
;
return 0; // literal value
}
static inline int32_t C_IntPow2
(int32_t v
)
{
return ((v
!=0) && (v
&(v
-1))==0);
}
static inline uint32_t C_Pow2IntLogBase2
(int32_t v
)
{
static const uint32_t b
[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0,
0xFF00FF00, 0xFFFF0000
};
register uint32_t r
= (v
& b
[0]) != 0;
int32_t i
= 4;
for (; i
> 0; i
--)
r
|= ((v
& b
[i
]) != 0) << i
;
return r
;
}
static int32_t C_CheckMalformedBranch
(intptr_t lastScriptPtr
)
{
switch (C_GetKeyword
())
{
case CON_RIGHTBRACE
:
case CON_ENDA
:
case CON_ENDEVENT
:
case CON_ENDS
:
case CON_ELSE
:
g_scriptPtr
= lastScriptPtr
+ &script
[0];
g_ifElseAborted
= 1;
C_ReportError
(-1);
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: malformed `%s' branch\n",g_szScriptFileName
,g_lineNumber
,
keyw
[*(g_scriptPtr
) & 0xFFF]);
return 1;
}
return 0;
}
static int32_t C_CheckEmptyBranch
(int32_t tw
, intptr_t lastScriptPtr
)
{
// ifrnd and the others actually do something when the condition is executed
if ((Bstrncmp
(keyw
[tw
], "if", 2) && tw
!= CON_ELSE
) ||
tw
== CON_IFRND
|| tw
== CON_IFHITWEAPON
|| tw
== CON_IFCANSEE
|| tw
== CON_IFCANSEETARGET
||
tw
== CON_IFPDISTL
|| tw
== CON_IFPDISTG
|| tw
== CON_IFGOTWEAPONCE
)
{
g_ifElseAborted
= 0;
return 0;
}
if ((*(g_scriptPtr
) & 0xFFF) != CON_NULLOP
|| *(g_scriptPtr
)>>12 != IFELSE_MAGIC
)
g_ifElseAborted
= 0;
if (EDUKE32_PREDICT_FALSE
(g_ifElseAborted
))
{
C_ReportError
(-1);
g_numCompilerWarnings
++;
g_scriptPtr
= lastScriptPtr
+ &script
[0];
initprintf
("%s:%d: warning: empty `%s' branch\n",g_szScriptFileName
,g_lineNumber
,
keyw
[*(g_scriptPtr
) & 0xFFF]);
*(g_scriptPtr
) = (CON_NULLOP
+ (IFELSE_MAGIC
<<12));
return 1;
}
return 0;
}
static int32_t C_CountCaseStatements
()
{
int32_t lCount
;
char *temptextptr
= textptr
;
int32_t temp_ScriptLineNumber
= g_lineNumber
;
intptr_t scriptoffset
= (unsigned)(g_scriptPtr
-script
);
intptr_t caseoffset
= (unsigned)(g_caseScriptPtr
-script
);
// int32_t i;
g_numCases
=0;
g_caseScriptPtr
=NULL
;
//Bsprintf(g_szBuf,"CSS: %.12s",textptr);
//AddLog(g_szBuf);
C_ParseCommand
(1);
// since we processed the endswitch, we need to re-increment g_checkingSwitch
g_checkingSwitch
++;
textptr
=temptextptr
;
g_scriptPtr
= (intptr_t *)(script
+scriptoffset
);
g_lineNumber
= temp_ScriptLineNumber
;
lCount
=g_numCases
;
g_numCases
=0;
g_caseScriptPtr
= (intptr_t *)(script
+caseoffset
);
g_numCases
= 0;
return lCount
;
}
static void C_Include
(const char *confile
)
{
int32_t temp_ScriptLineNumber
;
int32_t temp_ifelse_check
;
int32_t j
;
char *origtptr
, *mptr
;
char parentScriptFileName
[255];
int32_t fp
;
fp
= kopen4loadfrommod
(confile
,g_loadFromGroupOnly
);
if (EDUKE32_PREDICT_FALSE
(fp
< 0))
{
g_numCompilerErrors
++;
initprintf
("%s:%d: error: could not find file `%s'.\n",g_szScriptFileName
,g_lineNumber
,confile
);
return;
}
j
= kfilelength
(fp
);
mptr
= (char *)Xmalloc
(j
+1);
initprintf
("Including: %s (%d bytes)\n",confile
, j
);
kread
(fp
, mptr
, j
);
kclose
(fp
);
mptr
[j
] = 0;
if (*textptr
== '"') // skip past the closing quote if it's there so we don't screw up the next line
textptr
++;
origtptr
= textptr
;
Bstrcpy
(parentScriptFileName
, g_szScriptFileName
);
Bstrcpy
(g_szScriptFileName
, confile
);
temp_ScriptLineNumber
= g_lineNumber
;
g_lineNumber
= 1;
temp_ifelse_check
= g_checkingIfElse
;
g_checkingIfElse
= 0;
textptr
= mptr
;
C_SkipComments
();
C_ParseCommand
(1);
Bstrcpy
(g_szScriptFileName
, parentScriptFileName
);
g_totalLines
+= g_lineNumber
;
g_lineNumber
= temp_ScriptLineNumber
;
g_checkingIfElse
= temp_ifelse_check
;
textptr
= origtptr
;
Bfree
(mptr
);
}
#endif // !defined LUNATIC
#ifdef _WIN32
static void check_filename_case
(const char *fn
)
{
int32_t fp
;
if ((fp
= kopen4loadfrommod
(fn
, g_loadFromGroupOnly
)) >= 0)
kclose
(fp
);
}
#else
static void check_filename_case
(const char *fn
) { UNREFERENCED_PARAMETER
(fn
); }
#endif
void G_DoGameStartup
(const int32_t *params
)
{
int32_t j
= 0;
ud.
const_visibility = params
[j
++];
g_impactDamage
= params
[j
++];
g_maxPlayerHealth
= g_player
[0].
ps->max_player_health
= g_player
[0].
ps->max_shield_amount
= params
[j
++];
g_startArmorAmount
= params
[j
++];
g_actorRespawnTime
= params
[j
++];
if (g_scriptVersion
>= 11)
g_itemRespawnTime
= params
[j
++];
else
g_itemRespawnTime
= g_actorRespawnTime
;
if (g_scriptVersion
>= 11)
g_playerFriction
= params
[j
++];
if (g_scriptVersion
== 14)
g_spriteGravity
= params
[j
++];
if (g_scriptVersion
>= 11)
{
g_rpgBlastRadius
= params
[j
++];
g_pipebombBlastRadius
= params
[j
++];
g_shrinkerBlastRadius
= params
[j
++];
g_tripbombBlastRadius
= params
[j
++];
g_morterBlastRadius
= params
[j
++];
g_bouncemineBlastRadius
= params
[j
++];
g_seenineBlastRadius
= params
[j
++];
}
g_player
[0].
ps->max_ammo_amount
[PISTOL_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[SHOTGUN_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[CHAINGUN_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[RPG_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[HANDBOMB_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[SHRINKER_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[DEVISTATOR_WEAPON
] = params
[j
++];
g_player
[0].
ps->max_ammo_amount
[TRIPBOMB_WEAPON
] = params
[j
++];
if (g_scriptVersion
>= 13)
{
g_player
[0].
ps->max_ammo_amount
[FREEZE_WEAPON
] = params
[j
++];
if (g_scriptVersion
== 14)
g_player
[0].
ps->max_ammo_amount
[GROW_WEAPON
] = params
[j
++];
g_damageCameras
= params
[j
++];
g_numFreezeBounces
= params
[j
++];
g_freezerSelfDamage
= params
[j
++];
if (g_scriptVersion
== 14)
{
g_spriteDeleteQueueSize
= params
[j
++];
g_spriteDeleteQueueSize
= clamp
(g_spriteDeleteQueueSize
, 0, 1024);
g_tripbombLaserMode
= params
[j
++];
}
}
}
void C_DefineMusic
(int32_t vol
, int32_t lev
, const char *fn
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
+1);
Bassert
((unsigned)lev
< MAXLEVELS
);
{
map_t
*const map
= &MapInfo
[(MAXLEVELS
*vol
)+lev
];
Bfree
(map
->musicfn
);
map
->musicfn
= dup_filename
(fn
);
check_filename_case
(map
->musicfn
);
}
}
#ifdef LUNATIC
void C_DefineSound
(int32_t sndidx
, const char *fn
, int32_t args
[5])
{
Bassert
((unsigned)sndidx
< MAXSOUNDS
);
{
sound_t
*const snd
= &g_sounds
[sndidx
];
Bfree
(snd
->filename
);
snd
->filename
= dup_filename
(fn
);
check_filename_case
(snd
->filename
);
snd
->ps
= args
[0];
snd
->pe
= args
[1];
snd
->pr
= args
[2];
snd
->m
= args
[3] & ~SF_ONEINST_INTERNAL
;
if (args
[3] & SF_LOOP
)
snd
->m
|= SF_ONEINST_INTERNAL
;
snd
->vo
= args
[4];
if (sndidx
> g_maxSoundPos
)
g_maxSoundPos
= sndidx
;
}
}
void C_DefineQuote
(int32_t qnum
, const char *qstr
)
{
C_AllocQuote
(qnum
);
Bstrncpyz
(ScriptQuotes
[qnum
], qstr
, MAXQUOTELEN
);
}
void C_DefineVolumeName
(int32_t vol
, const char *name
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
);
Bstrncpyz
(EpisodeNames
[vol
], name
, sizeof(EpisodeNames
[vol
]));
g_numVolumes
= max
(g_numVolumes
, vol
+1);
}
void C_DefineSkillName
(int32_t skill
, const char *name
)
{
Bassert
((unsigned)skill
< MAXSKILLS
);
Bstrncpyz
(SkillNames
[skill
], name
, sizeof(SkillNames
[skill
]));
g_numSkills
= max
(g_numSkills
, skill
+1);
}
void C_DefineLevelName
(int32_t vol
, int32_t lev
, const char *fn
,
int32_t partime
, int32_t designertime
,
const char *levelname
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
);
Bassert
((unsigned)lev
< MAXLEVELS
);
{
map_t
*const map
= &MapInfo
[(MAXLEVELS
*vol
)+lev
];
Bfree
(map
->filename
);
map
->filename
= dup_filename
(fn
);
// TODO: truncate to 32 chars?
Bfree
(map
->name
);
map
->name
= Xstrdup
(levelname
);
map
->partime
= REALGAMETICSPERSEC
* partime
;
map
->designertime
= REALGAMETICSPERSEC
* designertime
;
}
}
void C_DefineGameFuncName
(int32_t idx
, const char *name
)
{
assert((unsigned)idx
< NUMGAMEFUNCTIONS
);
Bstrncpyz
(gamefunctions
[idx
], name
, MAXGAMEFUNCLEN
);
Bstrncpyz
(keydefaults
[3*idx
], name
, MAXGAMEFUNCLEN
);
hash_add
(&h_gamefuncs
, gamefunctions
[idx
], idx
, 0);
}
void C_DefineGameType
(int32_t idx
, int32_t flags
, const char *name
)
{
Bassert
((unsigned)idx
< MAXGAMETYPES
);
GametypeFlags
[idx
] = flags
;
Bstrncpyz
(GametypeNames
[idx
], name
, sizeof(GametypeNames
[idx
]));
g_numGametypes
= idx
+1;
}
#endif
void C_DefineVolumeFlags
(int32_t vol
, int32_t flags
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
);
EpisodeFlags
[vol
] = flags
;
}
void C_UndefineVolume
(int32_t vol
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
);
for (int32_t i
= 0; i
< MAXLEVELS
; i
++)
C_UndefineLevel
(vol
, i
);
EpisodeNames
[vol
][0] = '\0';
g_numVolumes
= 0;
for (int32_t i
= MAXVOLUMES
-1; i
>= 0; i
--)
{
if (EpisodeNames
[i
][0])
{
g_numVolumes
= i
+1;
break;
}
}
}
void C_UndefineSkill
(int32_t skill
)
{
Bassert
((unsigned)skill
< MAXSKILLS
);
SkillNames
[skill
][0] = '\0';
g_numSkills
= 0;
for (int32_t i
= MAXSKILLS
-1; i
>= 0; i
--)
{
if (SkillNames
[i
][0])
{
g_numSkills
= i
+1;
break;
}
}
}
void C_UndefineLevel
(int32_t vol
, int32_t lev
)
{
Bassert
((unsigned)vol
< MAXVOLUMES
);
Bassert
((unsigned)lev
< MAXLEVELS
);
{
map_t
*const map
= &MapInfo
[(MAXLEVELS
*vol
)+lev
];
if (map
->filename
)
Bfree
(map
->filename
);
map
->filename
= NULL
;
if (map
->name
)
Bfree
(map
->name
);
map
->name
= NULL
;
map
->partime
= 0;
map
->designertime
= 0;
}
}
LUNATIC_EXTERN
int32_t C_SetDefName
(const char *name
)
{
clearDefNamePtr
();
g_defNamePtr
= dup_filename
(name
);
if (g_defNamePtr
)
initprintf
("Using DEF file: %s.\n", g_defNamePtr
);
return (g_defNamePtr
==NULL
);
}
LUNATIC_EXTERN
void C_DefineProjectile
(int32_t j
, int32_t what
, int32_t val
)
{
switch (what
)
{
case PROJ_WORKSLIKE
:
g_tile
[j
].
defproj.
workslike = ProjectileData
[j
].
workslike = val
; break;
case PROJ_SPAWNS
:
g_tile
[j
].
defproj.
spawns = ProjectileData
[j
].
spawns = val
; break;
case PROJ_SXREPEAT
:
g_tile
[j
].
defproj.
sxrepeat = ProjectileData
[j
].
sxrepeat = val
; break;
case PROJ_SYREPEAT
:
g_tile
[j
].
defproj.
syrepeat = ProjectileData
[j
].
syrepeat = val
; break;
case PROJ_SOUND
:
g_tile
[j
].
defproj.
sound = ProjectileData
[j
].
sound = val
; break;
case PROJ_ISOUND
:
g_tile
[j
].
defproj.
isound = ProjectileData
[j
].
isound = val
; break;
case PROJ_VEL
:
g_tile
[j
].
defproj.
vel = ProjectileData
[j
].
vel = val
; break;
case PROJ_EXTRA
:
g_tile
[j
].
defproj.
extra = ProjectileData
[j
].
extra = val
; break;
case PROJ_DECAL
:
g_tile
[j
].
defproj.
decal = ProjectileData
[j
].
decal = val
; break;
case PROJ_TRAIL
:
g_tile
[j
].
defproj.
trail = ProjectileData
[j
].
trail = val
; break;
case PROJ_TXREPEAT
:
g_tile
[j
].
defproj.
txrepeat = ProjectileData
[j
].
txrepeat = val
; break;
case PROJ_TYREPEAT
:
g_tile
[j
].
defproj.
tyrepeat = ProjectileData
[j
].
tyrepeat = val
; break;
case PROJ_TOFFSET
:
g_tile
[j
].
defproj.
toffset = ProjectileData
[j
].
toffset = val
; break;
case PROJ_TNUM
:
g_tile
[j
].
defproj.
tnum = ProjectileData
[j
].
tnum = val
; break;
case PROJ_DROP
:
g_tile
[j
].
defproj.
drop = ProjectileData
[j
].
drop = val
; break;
case PROJ_CSTAT
:
g_tile
[j
].
defproj.
cstat = ProjectileData
[j
].
cstat = val
; break;
case PROJ_CLIPDIST
:
g_tile
[j
].
defproj.
clipdist = ProjectileData
[j
].
clipdist = val
; break;
case PROJ_SHADE
:
g_tile
[j
].
defproj.
shade = ProjectileData
[j
].
shade = val
; break;
case PROJ_XREPEAT
:
g_tile
[j
].
defproj.
xrepeat = ProjectileData
[j
].
xrepeat = val
; break;
case PROJ_YREPEAT
:
g_tile
[j
].
defproj.
yrepeat = ProjectileData
[j
].
yrepeat = val
; break;
case PROJ_PAL
:
g_tile
[j
].
defproj.
pal = ProjectileData
[j
].
pal = val
; break;
case PROJ_EXTRA_RAND
:
g_tile
[j
].
defproj.
extra_rand = ProjectileData
[j
].
extra_rand = val
; break;
case PROJ_HITRADIUS
:
g_tile
[j
].
defproj.
hitradius = ProjectileData
[j
].
hitradius = val
; break;
case PROJ_MOVECNT
:
g_tile
[j
].
defproj.
movecnt = ProjectileData
[j
].
movecnt = val
; break;
case PROJ_OFFSET
:
g_tile
[j
].
defproj.
offset = ProjectileData
[j
].
offset = val
; break;
case PROJ_BOUNCES
:
g_tile
[j
].
defproj.
bounces = ProjectileData
[j
].
bounces = val
; break;
case PROJ_BSOUND
:
g_tile
[j
].
defproj.
bsound = ProjectileData
[j
].
bsound = val
; break;
case PROJ_RANGE
:
g_tile
[j
].
defproj.
range = ProjectileData
[j
].
range = val
; break;
case PROJ_FLASH_COLOR
:
g_tile
[j
].
defproj.
flashcolor = ProjectileData
[j
].
flashcolor = val
; break;
case PROJ_USERDATA
:
g_tile
[j
].
defproj.
userdata = ProjectileData
[j
].
userdata = val
; break;
default: break;
}
g_tile
[j
].
flags |= SFLAG_PROJECTILE
;
}
int32_t C_AllocQuote
(int32_t qnum
)
{
Bassert
((unsigned)qnum
< MAXQUOTES
);
if (ScriptQuotes
[qnum
] == NULL
)
{
ScriptQuotes
[qnum
] = (char *)Xcalloc
(MAXQUOTELEN
,sizeof(uint8_t));
return 1;
}
return 0;
}
void C_InitQuotes
(void)
{
for (int i
= 0; i
< 128; i
++) C_AllocQuote
(i
);
#ifdef EDUKE32_TOUCH_DEVICES
ScriptQuotes
[QUOTE_DEAD
] = 0;
#else
for (int i
= MAXQUOTELEN
- 7; i
>= 0; i
--)
if (Bstrncmp
(&ScriptQuotes
[QUOTE_DEAD
][i
], "SPACE", 5) == 0)
{
Bmemset
(tempbuf
, 0, sizeof(tempbuf
));
Bstrncpy
(tempbuf
, ScriptQuotes
[QUOTE_DEAD
], i
);
Bstrcat
(tempbuf
, "USE");
Bstrcat
(tempbuf
, &ScriptQuotes
[QUOTE_DEAD
][i
+ 5]);
Bstrncpy
(ScriptQuotes
[QUOTE_DEAD
], tempbuf
, MAXQUOTELEN
- 1);
i
= MAXQUOTELEN
- 7;
}
#endif
// most of these are based on Blood, obviously
const char *PlayerObituaries
[] =
{
"^02%s^02 beat %s^02 like a cur",
"^02%s^02 broke %s",
"^02%s^02 body bagged %s",
"^02%s^02 boned %s^02 like a fish",
"^02%s^02 castrated %s",
"^02%s^02 creamed %s",
"^02%s^02 crushed %s",
"^02%s^02 destroyed %s",
"^02%s^02 diced %s",
"^02%s^02 disemboweled %s",
"^02%s^02 erased %s",
"^02%s^02 eviscerated %s",
"^02%s^02 flailed %s",
"^02%s^02 flattened %s",
"^02%s^02 gave AnAl MaDnEsS to %s",
"^02%s^02 gave %s^02 Anal Justice",
"^02%s^02 hosed %s",
"^02%s^02 hurt %s^02 real bad",
"^02%s^02 killed %s",
"^02%s^02 made dog meat out of %s",
"^02%s^02 made mincemeat out of %s",
"^02%s^02 manhandled %s",
"^02%s^02 massacred %s",
"^02%s^02 mutilated %s",
"^02%s^02 murdered %s",
"^02%s^02 neutered %s",
"^02%s^02 punted %s",
"^02%s^02 reamed %s",
"^02%s^02 ripped %s^02 a new orifice",
"^02%s^02 rocked %s",
"^02%s^02 sent %s^02 to hell",
"^02%s^02 shredded %s",
"^02%s^02 slashed %s",
"^02%s^02 slaughtered %s",
"^02%s^02 sliced %s",
"^02%s^02 smacked %s around",
"^02%s^02 smashed %s",
"^02%s^02 snuffed %s",
"^02%s^02 sodomized %s",
"^02%s^02 splattered %s",
"^02%s^02 sprayed %s",
"^02%s^02 squashed %s",
"^02%s^02 throttled %s",
"^02%s^02 toasted %s",
"^02%s^02 vented %s",
"^02%s^02 ventilated %s",
"^02%s^02 wasted %s",
"^02%s^02 wrecked %s",
};
const char *PlayerSelfObituaries
[] =
{
"^02%s^02 is excrement",
"^02%s^02 is hamburger",
"^02%s^02 suffered scrotum separation",
"^02%s^02 volunteered for population control",
"^02%s^02 has suicided",
"^02%s^02 bled out",
};
EDUKE32_STATIC_ASSERT
(OBITQUOTEINDEX
+ ARRAY_SIZE
(PlayerObituaries
)-1 < MAXQUOTES
);
EDUKE32_STATIC_ASSERT
(SUICIDEQUOTEINDEX
+ ARRAY_SIZE
(PlayerSelfObituaries
)-1 < MAXQUOTES
);
g_numObituaries
= ARRAY_SIZE
(PlayerObituaries
);
for (int i
= g_numObituaries
- 1; i
>= 0; i
--)
{
if (C_AllocQuote
(i
+ OBITQUOTEINDEX
))
Bstrcpy
(ScriptQuotes
[i
+ OBITQUOTEINDEX
], PlayerObituaries
[i
]);
}
g_numSelfObituaries
= ARRAY_SIZE
(PlayerSelfObituaries
);
for (int i
= g_numSelfObituaries
- 1; i
>= 0; i
--)
{
if (C_AllocQuote
(i
+ SUICIDEQUOTEINDEX
))
Bstrcpy
(ScriptQuotes
[i
+ SUICIDEQUOTEINDEX
], PlayerSelfObituaries
[i
]);
}
}
LUNATIC_EXTERN
void C_SetCfgName
(const char *cfgname
)
{
char temp
[BMAX_PATH
];
struct Bstat st
;
int32_t fullscreen
= ud.
config.
ScreenMode;
int32_t xdim
= ud.
config.
ScreenWidth, ydim
= ud.
config.
ScreenHeight, bpp
= ud.
config.
ScreenBPP;
int32_t usemouse
= ud.
config.
UseMouse, usejoy
= ud.
config.
UseJoystick;
#ifdef USE_OPENGL
int32_t glrm
= glrendmode
;
#endif
if (Bstrcmp
(setupfilename
, SETUPFILENAME
) != 0) // set to something else via -cfg
return;
if (Bstat
(g_modDir
, &st
) < 0)
{
if (errno
== ENOENT
) // path doesn't exist
{
if (Bmkdir
(g_modDir
, S_IRWXU
) < 0)
{
OSD_Printf
("Failed to create configuration file directory %s\n", g_modDir
);
return;
}
else OSD_Printf
("Created configuration file directory %s\n", g_modDir
);
}
else
{
// another type of failure
return;
}
}
else if ((st.
st_mode & S_IFDIR
) != S_IFDIR
)
{
// directory isn't a directory
return;
}
// XXX: Back up 'cfgname' as it may be the global 'tempbuf'.
Bstrncpyz
(temp
, cfgname
, sizeof(temp
));
CONFIG_WriteSetup
(1);
if (g_modDir
[0] != '/')
Bsnprintf
(setupfilename
, sizeof(setupfilename
), "%s/%s", g_modDir
, temp
);
else
Bstrncpyz
(setupfilename
, temp
, sizeof(setupfilename
));
initprintf
("Using config file \"%s\".\n", setupfilename
);
CONFIG_ReadSetup
();
ud.
config.
ScreenMode = fullscreen
;
ud.
config.
ScreenWidth = xdim
;
ud.
config.
ScreenHeight = ydim
;
ud.
config.
ScreenBPP = bpp
;
ud.
config.
UseMouse = usemouse
;
ud.
config.
UseJoystick = usejoy
;
#ifdef USE_OPENGL
glrendmode
= glrm
;
#endif
}
#if !defined LUNATIC
static void C_BitOrNextValue
(int32_t *valptr
)
{
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
*valptr
|= *g_scriptPtr
;
}
static void C_FinishBitOr
(int32_t value
)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
= value
;
g_scriptPtr
++;
}
static int32_t C_ParseCommand
(int32_t loop
)
{
int32_t i
, j
=0, k
=0, tw
, otw
;
// char *temptextptr;
intptr_t *tempscrptr
= NULL
;
do
{
if (EDUKE32_PREDICT_FALSE
(quitevent
))
{
initprintf
("Aborted.\n");
G_Shutdown
();
Bexit
(0);
}
if (EDUKE32_PREDICT_FALSE
(g_numCompilerErrors
> 63 || (*textptr
== '\0') || (*(textptr
+1) == '\0') || C_SkipComments
()))
return 1;
if (EDUKE32_PREDICT_FALSE
(g_scriptDebug
))
C_ReportError
(-1);
tempscrptr
= NULL
; // temptextptr = NULL;
otw
= g_lastKeyword
;
switch ((g_lastKeyword
= tw
= C_GetNextKeyword
()))
{
default:
case -1:
case -2:
return 1; //End
case CON_STATE
:
if (g_parsingActorPtr
== NULL
&& g_processingState
== 0)
{
C_GetNextLabelName
();
g_scriptPtr
--;
labelcode
[g_numLabels
] = g_scriptPtr
-script
;
labeltype
[g_numLabels
] = LABEL_STATE
;
g_processingState
= 1;
Bsprintf
(g_szCurrentBlockName
,"%s",label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_gamevars
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
hash_add
(&h_labels
,label
+(g_numLabels
<<6),g_numLabels
,0);
g_numLabels
++;
continue;
}
C_GetNextLabelName
();
if (EDUKE32_PREDICT_FALSE
((j
= hash_find
(&h_labels
,label
+(g_numLabels
<<6))) < 0))
{
C_ReportError
(-1);
initprintf
("%s:%d: error: state `%s' not found.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
g_numCompilerErrors
++;
g_scriptPtr
++;
continue;
}
if (EDUKE32_PREDICT_FALSE
((labeltype
[j
] & LABEL_STATE
) != LABEL_STATE
))
{
char *gl
= (char *) C_GetLabelType
(labeltype
[j
]);
C_ReportError
(-1);
initprintf
("%s:%d: warning: expected state, found %s.\n", g_szScriptFileName
, g_lineNumber
, gl
);
g_numCompilerWarnings
++;
Bfree
(gl
);
*(g_scriptPtr
-1) = CON_NULLOP
; // get rid of the state, leaving a nullop to satisfy if conditions
bitptr
[(g_scriptPtr
-script
-1)>>3] &= ~
(1<<((g_scriptPtr
-script
-1)&7));
continue; // valid label name, but wrong type
}
if (!(g_numCompilerErrors
|| g_numCompilerWarnings
) && g_scriptDebug
> 1)
initprintf
("%s:%d: debug: accepted state label `%s'.\n", g_szScriptFileName
, g_lineNumber
, label
+(j
<<6));
*g_scriptPtr
= (intptr_t) (script
+labelcode
[j
]);
// 'state' type labels are always script addresses, as far as I can see
bitptr
[(g_scriptPtr
-script
)>>3] |= (BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
g_scriptPtr
++;
continue;
case CON_ENDS
:
if (EDUKE32_PREDICT_FALSE
(g_processingState
== 0))
{
C_ReportError
(-1);
initprintf
("%s:%d: error: found `ends' without open `state'.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerErrors
++;
}
// else
{
if (EDUKE32_PREDICT_FALSE
(g_numBraces
> 0))
{
C_ReportError
(ERROR_OPENBRACKET
);
g_numCompilerErrors
++;
}
else if (EDUKE32_PREDICT_FALSE
(g_numBraces
< 0))
{
C_ReportError
(ERROR_CLOSEBRACKET
);
g_numCompilerErrors
++;
}
if (EDUKE32_PREDICT_FALSE
(g_checkingSwitch
> 0))
{
C_ReportError
(ERROR_NOENDSWITCH
);
g_numCompilerErrors
++;
g_checkingSwitch
= 0; // can't be checking anymore...
}
g_processingState
= 0;
Bsprintf
(g_szCurrentBlockName
,"(none)");
}
continue;
case CON_SETTHISPROJECTILE
:
case CON_SETPROJECTILE
:
case CON_GETTHISPROJECTILE
:
case CON_GETPROJECTILE
:
{
int32_t lLabelID
;
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
if (tw
== CON_SETTHISPROJECTILE
)
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameOffset
(&projectileH
,Bstrtolower
(label
+(g_numLabels
<<6)));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=ProjectileLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",PlayerLabels[lLabelID].flags);
// now at target VAR...
// get the ID of the DEF
switch (tw
)
{
case CON_SETPROJECTILE
:
case CON_SETTHISPROJECTILE
:
C_GetNextVar
();
break;
default:
C_GetNextVarType
(GAMEVAR_READONLY
);
break;
}
continue;
}
case CON_GAMEVAR
:
// syntax: gamevar <var1> <initial value> <flags>
// defines var1 and sets initial value.
// flags are used to define usage
// (see top of this files for flags)
//printf("Got gamedef. Getting Label. '%.20s'\n",textptr);
if (EDUKE32_PREDICT_FALSE
(isdigit(*textptr
) || (*textptr
== '-')))
{
C_GetNextLabelName
();
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
C_GetNextValue
(LABEL_DEFINE
);
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
-= 3; // we complete the process anyways just to skip past the fucked up section
continue;
}
C_GetNextLabelName
();
//printf("Got Label '%.20s'\n",textptr);
// Check to see it's already defined
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
//printf("Translating number '%.20s'\n",textptr);
C_GetNextValue
(LABEL_DEFINE
); // get initial value
//printf("Done Translating number. '%.20s'\n",textptr);
C_GetNextValue
(LABEL_DEFINE
); // get flags
//Bsprintf(g_szBuf,"Adding GameVar=\"%s\", val=%l, flags=%lX",label+(g_numLabels<<6),
// *(g_scriptPtr-2), *(g_scriptPtr-1));
//AddLog(g_szBuf);
if (EDUKE32_PREDICT_FALSE
((*(g_scriptPtr
-1)&GAMEVAR_USER_MASK
)==3))
{
g_numCompilerWarnings
++;
*(g_scriptPtr
-1)^=GAMEVAR_PERPLAYER
;
C_ReportError
(WARNING_BADGAMEVAR
);
}
Gv_NewVar
(label
+(g_numLabels
<<6),*(g_scriptPtr
-2),
(*(g_scriptPtr
-1))
// can't define default or secret
& (~
(GAMEVAR_DEFAULT
| GAMEVAR_SECRET
))
);
//AddLog("Added gamevar");
g_scriptPtr
-= 3; // no need to save in script...
continue;
case CON_GAMEARRAY
:
if (EDUKE32_PREDICT_FALSE
(isdigit(*textptr
) || (*textptr
== '-')))
{
C_GetNextLabelName
();
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
C_GetNextValue
(LABEL_DEFINE
);
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
-= 2; // we complete the process anyways just to skip past the fucked up section
continue;
}
C_GetNextLabelName
();
//printf("Got Label '%.20s'\n",textptr);
// Check to see it's already defined
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
i
= hash_find
(&h_gamevars
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
C_GetNextValue
(LABEL_DEFINE
);
Gv_NewArray
(label
+(g_numLabels
<<6),NULL
,*(g_scriptPtr
-1), GAMEARRAY_NORMAL
);
g_scriptPtr
-= 2; // no need to save in script...
continue;
case CON_DEFINE
:
{
//printf("Got definition. Getting Label. '%.20s'\n",textptr);
C_GetNextLabelName
();
//printf("Got label. '%.20s'\n",textptr);
// Check to see it's already defined
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
i
= hash_find
(&h_gamevars
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
//printf("Translating. '%.20s'\n",textptr);
C_GetNextValue
(LABEL_DEFINE
);
//printf("Translated. '%.20s'\n",textptr);
i
= hash_find
(&h_labels
,label
+(g_numLabels
<<6));
if (i
>=0)
{
// if (i >= g_numDefaultLabels)
if (EDUKE32_PREDICT_FALSE
(labelcode
[i
] != *(g_scriptPtr
-1)))
{
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: ignored redefinition of `%s' to %d (old: %d).\n",g_szScriptFileName
,
g_lineNumber
,label
+(g_numLabels
<<6), (int32_t)(*(g_scriptPtr
-1)), labelcode
[i
]);
//C_ReportError(WARNING_DUPLICATEDEFINITION);
}
}
else
{
// printf("Defining Definition \"%s\" to be '%d'\n",label+(g_numLabels<<6),*(g_scriptPtr-1));
hash_add
(&h_labels
,label
+(g_numLabels
<<6),g_numLabels
,0);
labeltype
[g_numLabels
] = LABEL_DEFINE
;
labelcode
[g_numLabels
++] = *(g_scriptPtr
-1);
if (*(g_scriptPtr
-1) >= 0 && *(g_scriptPtr
-1) < MAXTILES
&& g_dynamicTileMapping
)
G_ProcessDynamicTileMapping
(label
+((g_numLabels
-1)<<6),*(g_scriptPtr
-1));
}
g_scriptPtr
-= 2;
continue;
}
case CON_PALFROM
:
for (j
=3; j
>=0; j
--)
{
if (C_GetKeyword
() == -1)
C_GetNextValue
(LABEL_DEFINE
);
else break;
}
while (j
>-1)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++ = 0;
j
--;
}
continue;
case CON_MOVE
:
if (g_parsingActorPtr
|| g_processingState
)
{
if (EDUKE32_PREDICT_FALSE
((C_GetNextValue
(LABEL_MOVE
|LABEL_DEFINE
) == 0) && (*(g_scriptPtr
-1) != 0) && (*(g_scriptPtr
-1) != 1)))
{
C_ReportError
(-1);
bitptr
[(g_scriptPtr
-script
-1)>>3] &= ~
(1<<((g_scriptPtr
-script
-1)&7));
*(g_scriptPtr
-1) = 0;
initprintf
("%s:%d: warning: expected a move, found a constant.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
j
= 0;
while (C_GetKeyword
() == -1)
C_BitOrNextValue
(&j
);
C_FinishBitOr
(j
);
}
else
{
g_scriptPtr
--;
C_GetNextLabelName
();
// Check to see it's already defined
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_gamevars
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
if (EDUKE32_PREDICT_FALSE
((i
= hash_find
(&h_labels
,label
+(g_numLabels
<<6))) >= 0))
{
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: duplicate move `%s' ignored.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
}
else
{
hash_add
(&h_labels
,label
+(g_numLabels
<<6),g_numLabels
,0);
labeltype
[g_numLabels
] = LABEL_MOVE
;
labelcode
[g_numLabels
++] = g_scriptPtr
-script
;
}
for (j
=1; j
>=0; j
--)
{
if (C_GetKeyword
() != -1) break;
C_GetNextValue
(LABEL_DEFINE
);
}
for (k
=j
; k
>=0; k
--)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
= 0;
g_scriptPtr
++;
}
}
continue;
case CON_MUSIC
:
{
// NOTE: this doesn't get stored in the PCode...
// music 1 stalker.mid dethtoll.mid streets.mid watrwld1.mid snake1.mid
// thecall.mid ahgeez.mid dethtoll.mid streets.mid watrwld1.mid snake1.mid
g_scriptPtr
--;
C_GetNextValue
(LABEL_DEFINE
); // Volume Number (0/4)
g_scriptPtr
--;
k
= *g_scriptPtr
-1; // 0-based volume number. -1 or MAXVOLUMES: "special"
if (k
== -1)
k
= MAXVOLUMES
;
if (EDUKE32_PREDICT_FALSE
((unsigned)k
>= MAXVOLUMES
+1)) // if it's not background or special music
{
g_numCompilerErrors
++;
C_ReportError
(-1);
initprintf
("%s:%d: error: volume number must be between 0 and MAXVOLUMES+1=%d.\n",
g_szScriptFileName
, g_lineNumber
, MAXVOLUMES
+1);
continue;
}
i
= 0;
// get the file name...
while (C_GetKeyword
() == -1)
{
C_SkipComments
();
j
= 0;
tempbuf
[j
] = '/';
while (isaltok
(*(textptr
+j
)))
{
tempbuf
[j
+1] = textptr
[j
];
j
++;
}
tempbuf
[j
+1] = '\0';
C_DefineMusic
(k
, i
, tempbuf
);
textptr
+= j
;
if (i
>= MAXLEVELS
)
break;
i
++;
}
}
continue;
case CON_INCLUDE
:
g_scriptPtr
--;
C_SkipComments
();
j
= 0;
while (isaltok
(*textptr
))
{
tempbuf
[j
] = *(textptr
++);
j
++;
}
tempbuf
[j
] = '\0';
C_Include
(tempbuf
);
continue;
case CON_INCLUDEDEFAULT
:
C_SkipComments
();
C_Include
(G_DefaultConFile
());
continue;
case CON_AI
:
if (g_parsingActorPtr
|| g_processingState
)
{
C_GetNextValue
(LABEL_AI
);
}
else
{
g_scriptPtr
--;
C_GetNextLabelName
();
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
i
= hash_find
(&h_gamevars
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
i
= hash_find
(&h_labels
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: duplicate ai `%s' ignored.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
}
else
{
labeltype
[g_numLabels
] = LABEL_AI
;
hash_add
(&h_labels
,label
+(g_numLabels
<<6),g_numLabels
,0);
labelcode
[g_numLabels
++] = g_scriptPtr
-script
;
}
for (j
=0; j
<3; j
++)
{
if (C_GetKeyword
() != -1) break;
if (j
== 1)
C_GetNextValue
(LABEL_ACTION
);
else if (j
== 2)
{
if (EDUKE32_PREDICT_FALSE
((C_GetNextValue
(LABEL_MOVE
|LABEL_DEFINE
) == 0) &&
(*(g_scriptPtr
-1) != 0) && (*(g_scriptPtr
-1) != 1)))
{
C_ReportError
(-1);
bitptr
[(g_scriptPtr
-script
-1)>>3] &= ~
(1<<((g_scriptPtr
-script
-1)&7));
*(g_scriptPtr
-1) = 0;
initprintf
("%s:%d: warning: expected a move, found a constant.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
k
= 0;
while (C_GetKeyword
() == -1)
C_BitOrNextValue
(&k
);
C_FinishBitOr
(k
);
j
= 666;
break;
}
}
if (j
== 666)
continue;
for (k
=j
; k
<3; k
++)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
= 0;
g_scriptPtr
++;
}
}
continue;
case CON_ACTION
:
if (g_parsingActorPtr
|| g_processingState
)
{
C_GetNextValue
(LABEL_ACTION
);
}
else
{
g_scriptPtr
--;
C_GetNextLabelName
();
// Check to see it's already defined
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
i
= hash_find
(&h_gamevars
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
C_ReportError
(WARNING_NAMEMATCHESVAR
);
}
i
= hash_find
(&h_labels
,label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
>=0))
{
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: duplicate action `%s' ignored.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
}
else
{
labeltype
[g_numLabels
] = LABEL_ACTION
;
labelcode
[g_numLabels
] = g_scriptPtr
-script
;
hash_add
(&h_labels
,label
+(g_numLabels
<<6),g_numLabels
,0);
g_numLabels
++;
}
for (j
=4; j
>=0; j
--)
{
if (C_GetKeyword
() != -1) break;
C_GetNextValue
(LABEL_DEFINE
);
}
for (k
=j
; k
>=0; k
--)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*(g_scriptPtr
++) = 0;
}
}
continue;
case CON_ACTOR
:
case CON_USERACTOR
:
case CON_EVENTLOADACTOR
:
if (EDUKE32_PREDICT_FALSE
(g_processingState
|| g_parsingActorPtr
))
{
C_ReportError
(ERROR_FOUNDWITHIN
);
g_numCompilerErrors
++;
}
g_numBraces
= 0;
g_scriptPtr
--;
g_parsingActorPtr
= g_scriptPtr
;
if (tw
== CON_USERACTOR
)
{
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
}
// save the actor name w/o consuming it
C_SkipComments
();
j
= 0;
while (isaltok
(*(textptr
+j
)))
{
g_szCurrentBlockName
[j
] = textptr
[j
];
j
++;
}
g_szCurrentBlockName
[j
] = 0;
if (tw
== CON_USERACTOR
)
{
j
= *g_scriptPtr
;
if (EDUKE32_PREDICT_FALSE
(j
> 6 || (j
&3)==3))
{
C_ReportError
(-1);
initprintf
("%s:%d: warning: invalid useractor type. Must be 0, 1, 2"
" (notenemy, enemy, enemystayput) or have 4 added (\"doesn't move\").\n",
g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
j
= 0;
}
}
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
if (EDUKE32_PREDICT_FALSE
((unsigned)*g_scriptPtr
>= MAXTILES
))
{
C_ReportError
(ERROR_EXCEEDSMAXTILES
);
g_numCompilerErrors
++;
continue;
}
if (tw
== CON_EVENTLOADACTOR
)
{
g_tile
[*g_scriptPtr
].
loadPtr = g_parsingActorPtr
;
g_checkingIfElse
= 0;
continue;
}
g_tile
[*g_scriptPtr
].
execPtr = g_parsingActorPtr
;
if (tw
== CON_USERACTOR
)
{
if (j
& 1)
g_tile
[*g_scriptPtr
].
flags |= SFLAG_BADGUY
;
if (j
& 2)
g_tile
[*g_scriptPtr
].
flags |= (SFLAG_BADGUY
|SFLAG_BADGUYSTAYPUT
);
if (j
& 4)
g_tile
[*g_scriptPtr
].
flags |= SFLAG_ROTFIXED
;
}
for (j
=0; j
<4; j
++)
{
bitptr
[(g_parsingActorPtr
+j
-script
)>>3] &= ~
(1<<((g_parsingActorPtr
+j
-script
)&7));
*(g_parsingActorPtr
+j
) = 0;
if (j
== 3)
{
j
= 0;
while (C_GetKeyword
() == -1)
C_BitOrNextValue
(&j
);
C_FinishBitOr
(j
);
break;
}
else
{
if (C_GetKeyword
() != -1)
{
for (i
=4-j
; i
; i
--)
{
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*(g_scriptPtr
++) = 0;
}
break;
}
switch (j
)
{
case 0:
C_GetNextValue
(LABEL_DEFINE
);
break;
case 1:
C_GetNextValue
(LABEL_ACTION
);
break;
case 2:
// XXX: LABEL_MOVE|LABEL_DEFINE, what is this shit? compatibility?
// yep, it sure is :(
if (EDUKE32_PREDICT_FALSE
((C_GetNextValue
(LABEL_MOVE
|LABEL_DEFINE
) == 0) && (*(g_scriptPtr
-1) != 0) && (*(g_scriptPtr
-1) != 1)))
{
C_ReportError
(-1);
bitptr
[(g_scriptPtr
-script
-1)>>3] &= ~
(1<<((g_scriptPtr
-script
-1)&7));
*(g_scriptPtr
-1) = 0;
initprintf
("%s:%d: warning: expected a move, found a constant.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
break;
}
if (*(g_scriptPtr
-1) >= (intptr_t)&script
[0] && *(g_scriptPtr
-1) < (intptr_t)&script
[g_scriptSize
])
bitptr
[(g_parsingActorPtr
+j
-script
)>>3] |= (BITPTR_POINTER
<<((g_parsingActorPtr
+j
-script
)&7));
else bitptr
[(g_parsingActorPtr
+j
-script
)>>3] &= ~
(1<<((g_parsingActorPtr
+j
-script
)&7));
*(g_parsingActorPtr
+j
) = *(g_scriptPtr
-1);
}
}
g_checkingIfElse
= 0;
continue;
case CON_ONEVENT
:
if (EDUKE32_PREDICT_FALSE
(g_processingState
|| g_parsingActorPtr
))
{
C_ReportError
(ERROR_FOUNDWITHIN
);
g_numCompilerErrors
++;
}
g_numBraces
= 0;
g_scriptPtr
--;
g_parsingEventPtr
= g_scriptPtr
;
g_parsingActorPtr
= g_scriptPtr
;
C_SkipComments
();
j
= 0;
while (isaltok
(*(textptr
+j
)))
{
g_szCurrentBlockName
[j
] = textptr
[j
];
j
++;
}
g_szCurrentBlockName
[j
] = 0;
// g_labelsOnly = 1;
C_GetNextValue
(LABEL_DEFINE
);
g_labelsOnly
= 0;
g_scriptPtr
--;
j
= *g_scriptPtr
; // type of event
g_currentEvent
= j
;
//Bsprintf(g_szBuf,"Adding Event for %d at %lX",j, g_parsingEventPtr);
//AddLog(g_szBuf);
if (EDUKE32_PREDICT_FALSE
((unsigned)j
> MAXGAMEEVENTS
-1))
{
initprintf
("%s:%d: error: invalid event ID.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerErrors
++;
continue;
}
// if event has already been declared then store previous script location
if (apScriptGameEvent
[j
])
{
previous_event
=apScriptGameEvent
[j
];
}
apScriptGameEvent
[j
]=g_parsingEventPtr
;
g_checkingIfElse
= 0;
continue;
case CON_QSPRINTF
:
C_GetManyVars
(2);
j
= 0;
while (C_GetKeyword
() == -1 && j
< 32)
C_GetNextVar
(), j
++;
*g_scriptPtr
++ = CON_NULLOP
+ (g_lineNumber
<<12);
continue;
case CON_CSTAT
:
C_GetNextValue
(LABEL_DEFINE
);
if (EDUKE32_PREDICT_FALSE
(*(g_scriptPtr
-1) == 32767))
{
*(g_scriptPtr
-1) = 32768;
C_ReportError
(-1);
initprintf
("%s:%d: warning: tried to set cstat 32767, using 32768 instead.\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
else if (EDUKE32_PREDICT_FALSE
((*(g_scriptPtr
-1) & 32) && (*(g_scriptPtr
-1) & 16)))
{
i
= *(g_scriptPtr
-1);
*(g_scriptPtr
-1) ^= 48;
C_ReportError
(-1);
initprintf
("%s:%d: warning: tried to set cstat %d, using %d instead.\n",g_szScriptFileName
,g_lineNumber
,i
,(int32_t)(*(g_scriptPtr
-1)));
g_numCompilerWarnings
++;
}
continue;
case CON_HITRADIUSVAR
:
C_GetManyVars
(5);
continue;
case CON_HITRADIUS
:
C_GetNextValue
(LABEL_DEFINE
);
C_GetNextValue
(LABEL_DEFINE
);
C_GetNextValue
(LABEL_DEFINE
);
case CON_ADDAMMO
:
case CON_ADDWEAPON
:
case CON_SIZETO
:
case CON_SIZEAT
:
case CON_DEBRIS
:
case CON_ADDINVENTORY
:
case CON_GUTS
:
C_GetNextValue
(LABEL_DEFINE
);
case CON_ESPAWN
:
case CON_ESHOOT
:
case CON_QSPAWN
:
case CON_EQSPAWN
:
case CON_STRENGTH
:
case CON_SHOOT
:
case CON_ADDPHEALTH
:
case CON_SPAWN
:
case CON_COUNT
:
case CON_ENDOFGAME
:
case CON_ENDOFLEVEL
:
case CON_SPRITEPAL
:
case CON_CACTOR
:
case CON_MONEY
:
case CON_ADDKILLS
:
case CON_DEBUG
:
case CON_ADDSTRENGTH
:
case CON_CSTATOR
:
case CON_MAIL
:
case CON_PAPER
:
case CON_SLEEPTIME
:
case CON_CLIPDIST
:
case CON_LOTSOFGLASS
:
case CON_SAVENN
:
case CON_SAVE
:
case CON_ANGOFF
:
case CON_QUOTE
:
case CON_SOUND
:
case CON_GLOBALSOUND
:
case CON_SOUNDONCE
:
case CON_STOPSOUND
:
C_GetNextValue
(LABEL_DEFINE
);
continue;
case CON_ELSE
:
if (EDUKE32_PREDICT_FALSE
(!g_checkingIfElse
))
{
g_scriptPtr
--;
tempscrptr
= g_scriptPtr
;
g_numCompilerWarnings
++;
C_ReportError
(-1);
initprintf
("%s:%d: warning: found `else' with no `if'.\n",g_szScriptFileName
,g_lineNumber
);
if (C_GetKeyword
() == CON_LEFTBRACE
)
{
C_GetNextKeyword
();
g_numBraces
++;
C_ParseCommand
(1);
}
else C_ParseCommand
(0);
g_scriptPtr
= tempscrptr
;
continue;
}
{
intptr_t offset
;
intptr_t lastScriptPtr
= g_scriptPtr
- &script
[0] - 1;
g_ifElseAborted
= 0;
g_checkingIfElse
--;
if (C_CheckMalformedBranch
(lastScriptPtr
))
continue;
tempscrptr
= g_scriptPtr
;
offset
= (unsigned)(tempscrptr
-script
);
g_scriptPtr
++; //Leave a spot for the fail location
C_ParseCommand
(0);
if (C_CheckEmptyBranch
(tw
, lastScriptPtr
))
continue;
tempscrptr
= (intptr_t *)script
+offset
;
*tempscrptr
= (intptr_t) g_scriptPtr
;
bitptr
[(tempscrptr
-script
)>>3] |= (BITPTR_POINTER
<<((tempscrptr
-script
)&7));
}
continue;
case CON_SETSECTOR
:
case CON_GETSECTOR
:
{
int32_t lLabelID
;
// syntax getsector[<var>].x <VAR>
// gets the value of sector[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameID
(SectorLabels
,§orH
,Bstrtolower
(label
+(g_numLabels
<<6)));
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=lLabelID
;
// now at target VAR...
// get the ID of the DEF
if (tw
==CON_GETSECTOR
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_FINDNEARACTOR
:
case CON_FINDNEARACTOR3D
:
case CON_FINDNEARSPRITE
:
case CON_FINDNEARSPRITE3D
:
case CON_FINDNEARACTORZ
:
case CON_FINDNEARSPRITEZ
:
{
// syntax findnearactor <type> <maxdist> <getvar>
// gets the sprite ID of the nearest actor within max dist
// that is of <type> into <getvar>
// -1 for none found
C_GetNextValue
(LABEL_DEFINE
); // get <type>
C_GetNextValue
(LABEL_DEFINE
); // get maxdist
switch (tw
)
{
case CON_FINDNEARACTORZ
:
case CON_FINDNEARSPRITEZ
:
C_GetNextValue
(LABEL_DEFINE
);
default:
break;
}
// target var
// get the ID of the DEF
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
}
case CON_FINDNEARACTORVAR
:
case CON_FINDNEARACTOR3DVAR
:
case CON_FINDNEARSPRITEVAR
:
case CON_FINDNEARSPRITE3DVAR
:
case CON_FINDNEARACTORZVAR
:
case CON_FINDNEARSPRITEZVAR
:
{
C_GetNextValue
(LABEL_DEFINE
); // get <type>
// get the ID of the DEF
C_GetNextVar
();
switch (tw
)
{
case CON_FINDNEARACTORZVAR
:
case CON_FINDNEARSPRITEZVAR
:
C_GetNextVar
();
default:
break;
}
// target var
// get the ID of the DEF
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
}
case CON_SETWALL
:
case CON_GETWALL
:
{
int32_t lLabelID
;
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameID
(WallLabels
,&wallH
,Bstrtolower
(label
+(g_numLabels
<<6)));
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=lLabelID
;
// now at target VAR...
// get the ID of the DEF
if (tw
== CON_GETWALL
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_SETPLAYER
:
case CON_GETPLAYER
:
{
int32_t lLabelID
;
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameOffset
(&playerH
,Bstrtolower
(label
+(g_numLabels
<<6)));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=PlayerLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",PlayerLabels[lLabelID].flags);
if (PlayerLabels
[lLabelID
].
flags & LABEL_HASPARM2
)
{
//printf("Member has PARM2\n");
// get parm2
// get the ID of the DEF
C_GetNextVar
();
}
else
{
//printf("Member does not have Parm2\n");
}
// now at target VAR...
// get the ID of the DEF
if (tw
==CON_GETPLAYER
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_SETINPUT
:
case CON_GETINPUT
:
{
int32_t lLabelID
;
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameOffset
(&inputH
,Bstrtolower
(label
+(g_numLabels
<<6)));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=InputLabels
[lLabelID
].
lId;
// now at target VAR...
// get the ID of the DEF
if (tw
==CON_GETINPUT
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_SETUSERDEF
:
case CON_GETUSERDEF
:
{
int32_t lLabelID
;
// syntax [gs]etuserdef.x <VAR>
// gets the value of ud.xxx into <VAR>
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameID
(UserdefsLabels
,&userdefH
,Bstrtolower
(label
+(g_numLabels
<<6)));
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=lLabelID
;
// now at target VAR...
// get the ID of the DEF
if (tw
==CON_GETUSERDEF
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_SETACTORVAR
:
case CON_SETPLAYERVAR
:
case CON_GETACTORVAR
:
case CON_GETPLAYERVAR
:
{
// syntax [gs]etactorvar[<var>].<varx> <VAR>
// gets the value of the per-actor variable varx into VAR
// now get name of <var>
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .<varx>
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
if (g_scriptPtr
[-1] == g_iThisActorID
) // convert to "setvarvar"
{
g_scriptPtr
--;
g_scriptPtr
[-1]=CON_SETVARVAR
;
if (tw
== CON_SETACTORVAR
|| tw
== CON_SETPLAYERVAR
)
{
C_GetNextVarType
(GAMEVAR_READONLY
);
C_GetNextVar
();
}
else
{
g_scriptPtr
++;
C_GetNextVar
();
g_scriptPtr
-=2;
C_GetNextVarType
(GAMEVAR_READONLY
);
g_scriptPtr
++;
}
continue;
}
/// now pointing at 'xxx'
// get the ID of the DEF
C_GetNextLabelName
();
//printf("found label of \"%s\"\n", label+(g_numLabels<<6));
// Check to see if it's a keyword
if (EDUKE32_PREDICT_FALSE
(hash_find
(&h_keywords
,label
+(g_numLabels
<<6))>=0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_ISAKEYWORD
);
continue;
}
i
=GetDefID
(label
+(g_numLabels
<<6));
//printf("Label \"%s\" ID is %d\n",label+(g_numLabels<<6), i);
if (EDUKE32_PREDICT_FALSE
(i
<0))
{
// not a defined DEF
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEVAR
);
continue;
}
if (EDUKE32_PREDICT_FALSE
(aGameVars
[i
].
dwFlags & GAMEVAR_READONLY
))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_VARREADONLY
);
continue;
}
switch (tw
)
{
case CON_SETACTORVAR
:
if (EDUKE32_PREDICT_FALSE
(!(aGameVars
[i
].
dwFlags & GAMEVAR_PERACTOR
)))
{
g_numCompilerErrors
++;
C_ReportError
(-1);
initprintf
("%s:%d: error: variable `%s' is not per-actor.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
continue;
}
break;
case CON_SETPLAYERVAR
:
if (EDUKE32_PREDICT_FALSE
(!(aGameVars
[i
].
dwFlags & GAMEVAR_PERPLAYER
)))
{
g_numCompilerErrors
++;
C_ReportError
(-1);
initprintf
("%s:%d: error: variable `%s' is not per-player.\n",g_szScriptFileName
,g_lineNumber
,label
+(g_numLabels
<<6));
continue;
}
break;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=i
; // the ID of the DEF (offset into array...)
switch (tw
)
{
case CON_GETACTORVAR
:
case CON_GETPLAYERVAR
:
C_GetNextVarType
(GAMEVAR_READONLY
);
break;
default:
C_GetNextVar
();
break;
}
continue;
}
case CON_SETACTOR
:
case CON_GETACTOR
:
{
int32_t lLabelID
;
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
textptr
++;
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!= '.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameOffset
(&actorH
,Bstrtolower
(label
+(g_numLabels
<<6)));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=ActorLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",ActorLabels[lLabelID].flags);
if (ActorLabels
[lLabelID
].
flags & LABEL_HASPARM2
)
{
//printf("Member has PARM2\n");
// get parm2
// get the ID of the DEF
C_GetNextVar
();
}
// now at target VAR...
// get the ID of the DEF
if (tw
== CON_GETACTOR
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_GETTSPR
:
case CON_SETTSPR
:
{
int32_t lLabelID
;
#if 0
if (unlikely
(g_currentEvent
!= EVENT_ANIMATESPRITES
))
{
C_ReportError
(-1);
initprintf
("%s:%d: warning: found `%s' outside of EVENT_ANIMATESPRITES\n",g_szScriptFileName
,g_lineNumber
,tempbuf
);
g_numCompilerWarnings
++;
}
#endif
// syntax getwall[<var>].x <VAR>
// gets the value of wall[<var>].xxx into <VAR>
// now get name of .xxx
while ((*textptr
!= '['))
{
textptr
++;
}
if (*textptr
== '[')
textptr
++;
// get the ID of the DEF
g_labelsOnly
= 1;
C_GetNextVar
();
g_labelsOnly
= 0;
// now get name of .xxx
while (*textptr
!= '.')
{
if (*textptr
== 0xa)
break;
if (!*textptr
)
break;
textptr
++;
}
if (EDUKE32_PREDICT_FALSE
(*textptr
!='.'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYNTAXERROR
);
continue;
}
textptr
++;
/// now pointing at 'xxx'
C_GetNextLabelName
();
//printf("found xxx label of \"%s\"\n", label+(g_numLabels<<6));
lLabelID
=C_GetLabelNameOffset
(&tspriteH
,Bstrtolower
(label
+(g_numLabels
<<6)));
//printf("LabelID is %d\n",lLabelID);
if (EDUKE32_PREDICT_FALSE
(lLabelID
== -1))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_SYMBOLNOTRECOGNIZED
);
continue;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=TsprLabels
[lLabelID
].
lId;
//printf("member's flags are: %02Xh\n",ActorLabels[lLabelID].flags);
// now at target VAR...
// get the ID of the DEF
if (tw
== CON_GETTSPR
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else
C_GetNextVar
();
continue;
}
case CON_RANDVARVAR
:
case CON_SETVARVAR
:
case CON_ADDVARVAR
:
case CON_SUBVARVAR
:
case CON_MULVARVAR
:
case CON_DIVVARVAR
:
case CON_MODVARVAR
:
case CON_ANDVARVAR
:
case CON_ORVARVAR
:
case CON_XORVARVAR
:
case CON_DISPLAYRANDVARVAR
:
case CON_SIN
:
case CON_COS
:
case CON_QSTRLEN
:
case CON_HEADSPRITESTAT
:
case CON_PREVSPRITESTAT
:
case CON_NEXTSPRITESTAT
:
case CON_HEADSPRITESECT
:
case CON_PREVSPRITESECT
:
case CON_NEXTSPRITESECT
:
case CON_SECTOROFWALL
:
C_GetNextVarType
(GAMEVAR_READONLY
);
case CON_ADDLOGVAR
:
case CON_ESHOOTVAR
:
case CON_ESPAWNVAR
:
case CON_QSPAWNVAR
:
case CON_EQSPAWNVAR
:
case CON_OPERATERESPAWNS
:
case CON_OPERATEMASTERSWITCHES
:
case CON_CHECKACTIVATORMOTION
:
case CON_TIME
:
case CON_INITTIMER
:
case CON_LOCKPLAYER
:
case CON_SHOOTVAR
:
case CON_QUAKE
:
case CON_JUMP
:
case CON_CMENU
:
case CON_SOUNDVAR
:
case CON_GLOBALSOUNDVAR
:
case CON_STOPSOUNDVAR
:
case CON_SCREENSOUND
:
case CON_SOUNDONCEVAR
:
case CON_ANGOFFVAR
:
case CON_CHECKAVAILWEAPON
:
case CON_CHECKAVAILINVEN
:
case CON_GUNIQHUDID
:
case CON_SAVEGAMEVAR
:
case CON_USERQUOTE
:
case CON_ECHO
:
case CON_STARTTRACKVAR
:
case CON_CLEARMAPSTATE
:
case CON_ACTIVATECHEAT
:
case CON_SETGAMEPALETTE
:
case CON_SECTSETINTERPOLATION
:
case CON_SECTCLEARINTERPOLATION
:
case CON_SETACTORANGLE
:
case CON_SETPLAYERANGLE
:
case CON_SETMUSICPOSITION
:
case CON_STARTCUTSCENE
:
case CON_RESETPLAYERFLAGS
:
C_GetNextVar
();
continue;
case CON_SQRT
:
C_GetNextVar
();
case CON_FINDPLAYER
:
case CON_FINDOTHERPLAYER
:
case CON_DISPLAYRAND
:
case CON_READGAMEVAR
:
case CON_GETANGLETOTARGET
:
case CON_GETACTORANGLE
:
case CON_GETPLAYERANGLE
:
case CON_GETTICKS
:
case CON_GETCURRADDRESS
:
case CON_GETMUSICPOSITION
:
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
case CON_ENHANCED
:
// don't store in pCode...
g_scriptPtr
--;
//printf("We are enhanced, baby...\n");
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
if (EDUKE32_PREDICT_FALSE
(*g_scriptPtr
> BYTEVERSION_JF
))
{
g_numCompilerWarnings
++;
initprintf
("%s:%d: warning: need build %d, found build %d\n",g_szScriptFileName
,g_lineNumber
,k
,BYTEVERSION_JF
);
}
continue;
case CON_DYNAMICREMAP
:
g_scriptPtr
--;
if (EDUKE32_PREDICT_FALSE
(g_dynamicTileMapping
))
{
initprintf
("%s:%d: warning: duplicate dynamicremap statement\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
else
#ifdef DYNTILEREMAP_ENABLE
initprintf
("Using dynamic tile remapping\n");
g_dynamicTileMapping
= 1;
#else
{
initprintf
("%s:%d: warning: dynamic tile remapping is disabled in this build\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
#endif
continue;
case CON_DYNAMICSOUNDREMAP
:
g_scriptPtr
--;
if (EDUKE32_PREDICT_FALSE
(g_dynamicSoundMapping
))
{
initprintf
("%s:%d: warning: duplicate dynamicsoundremap statement\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
else
#ifdef DYNSOUNDREMAP_ENABLE
initprintf
("Using dynamic sound remapping\n");
g_dynamicSoundMapping
= 1;
#else
{
initprintf
("%s:%d: warning: dynamic sound remapping is disabled in this build\n",g_szScriptFileName
,g_lineNumber
);
g_numCompilerWarnings
++;
}
#endif
continue;
case CON_RANDVAR
:
case CON_ZSHOOT
:
case CON_EZSHOOT
:
case CON_SETVAR
:
case CON_ADDVAR
:
case CON_SUBVAR
:
case CON_DISPLAYRANDVAR
:
case CON_MULVAR
:
case CON_DIVVAR
:
case CON_MODVAR
:
case CON_ANDVAR
:
case CON_ORVAR
:
case CON_XORVAR
:
case CON_SHIFTVARL
:
case CON_SHIFTVARR
:
{
intptr_t *inst
= g_scriptPtr
-1;
char *tptr
= textptr
;
// syntax: [rand|add|set]var <var1> <const1>
// sets var1 to const1
// adds const1 to var1 (const1 can be negative...)
//printf("Found [add|set]var at line= %d\n",g_lineNumber);
// get the ID of the DEF
if (tw
!= CON_ZSHOOT
&& tw
!= CON_EZSHOOT
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else C_GetNextVar
();
C_GetNextValue
(LABEL_DEFINE
); // the number to check against...
if (tw
== CON_DIVVAR
|| tw
== CON_MULVAR
)
{
int32_t i
= *(g_scriptPtr
-1);
j
= klabs
(i
);
if (i
== -1)
{
*inst
= CON_INV
+(g_lineNumber
<<12);
g_scriptPtr
--;
continue;
}
if (C_IntPow2
(j
))
{
*inst
= ((tw
== CON_DIVVAR
) ? CON_SHIFTVARR
: CON_SHIFTVARL
)+(g_lineNumber
<<12);
*(g_scriptPtr
-1) = C_Pow2IntLogBase2
(j
);
// initprintf("%s:%d: replacing multiply/divide with shift\n",g_szScriptFileName,g_lineNumber);
if (i
== j
)
continue;
*g_scriptPtr
++ = CON_INV
+(g_lineNumber
<<12);
textptr
= tptr
;
C_GetNextVarType
(GAMEVAR_READONLY
);
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
// initprintf("%s:%d: adding inversion\n",g_szScriptFileName,g_lineNumber);
}
}
}
continue;
case CON_WRITEARRAYTOFILE
:
case CON_READARRAYFROMFILE
:
C_GetNextLabelName
();
i
=GetADefID
(label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
< 0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEARRAY
);
return 1;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=i
;
C_GetNextValue
(LABEL_DEFINE
);
continue;
case CON_COPY
:
C_GetNextLabelName
();
i
=GetADefID
(label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
< 0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEARRAY
);
return 1;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=i
;
C_SkipComments
();// skip comments and whitespace
if (EDUKE32_PREDICT_FALSE
(*textptr
!= '['))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_GAMEARRAYBNO
);
return 1;
}
textptr
++;
C_GetNextVar
();
C_SkipComments
();// skip comments and whitespace
if (EDUKE32_PREDICT_FALSE
(*textptr
!= ']'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_GAMEARRAYBNC
);
return 1;
}
textptr
++;
case CON_SETARRAY
:
C_GetNextLabelName
();
i
=GetADefID
(label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
< 0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEARRAY
);
return 1;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=i
;
if (EDUKE32_PREDICT_FALSE
(aGameArrays
[i
].
dwFlags & GAMEARRAY_READONLY
))
{
C_ReportError
(ERROR_ARRAYREADONLY
);
g_numCompilerErrors
++;
return 1;
}
C_SkipComments
();// skip comments and whitespace
if (EDUKE32_PREDICT_FALSE
(*textptr
!= '['))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_GAMEARRAYBNO
);
return 1;
}
textptr
++;
C_GetNextVar
();
C_SkipComments
();// skip comments and whitespace
if (EDUKE32_PREDICT_FALSE
(*textptr
!= ']'))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_GAMEARRAYBNC
);
return 1;
}
textptr
++;
C_GetNextVar
();
continue;
case CON_GETARRAYSIZE
:
case CON_RESIZEARRAY
:
C_GetNextLabelName
();
i
=GetADefID
(label
+(g_numLabels
<<6));
if (EDUKE32_PREDICT_FALSE
(i
< 0))
{
g_numCompilerErrors
++;
C_ReportError
(ERROR_NOTAGAMEARRAY
);
return 1;
}
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++ = i
;
if (tw
==CON_RESIZEARRAY
&& (aGameArrays
[i
].
dwFlags & GAMEARRAY_TYPE_MASK
))
{
C_ReportError
(-1);
initprintf
("can't resize system array `%s'.", label
+(g_numLabels
<<6));
return 1;
}
C_SkipComments
();
C_GetNextVarType
(tw
==CON_GETARRAYSIZE
? GAMEVAR_READONLY
: 0);
continue;
case CON_SMAXAMMO
:
case CON_ADDWEAPONVAR
:
case CON_ACTIVATEBYSECTOR
:
case CON_OPERATESECTORS
:
case CON_OPERATEACTIVATORS
:
case CON_SSP
:
case CON_GMAXAMMO
:
case CON_DIST
:
case CON_LDIST
:
case CON_GETINCANGLE
:
case CON_GETANGLE
:
case CON_MULSCALE
:
case CON_SETASPECT
:
// get the ID of the DEF
switch (tw
)
{
case CON_DIST
:
case CON_LDIST
:
case CON_GETANGLE
:
case CON_GETINCANGLE
:
case CON_MULSCALE
:
C_GetNextVarType
(GAMEVAR_READONLY
);
break;
default:
C_GetNextVar
();
break;
}
// get the ID of the DEF
if (tw
== CON_GMAXAMMO
)
C_GetNextVarType
(GAMEVAR_READONLY
);
else C_GetNextVar
();
switch (tw
)
{
case CON_DIST
:
case CON_LDIST
:
case CON_GETANGLE
:
case CON_GETINCANGLE
:
C_GetNextVar
();
break;
case CON_MULSCALE
:
C_GetManyVars
(2);
break;
}
continue;
case CON_FLASH
:
case CON_SAVEMAPSTATE
:
case CON_LOADMAPSTATE
:
if (tw
!= CON_FLASH
)
{
if (EDUKE32_PREDICT_FALSE
(g_currentEvent
== EVENT_ANIMATESPRITES
))
{
initprintf
("%s:%d: warning: found `%s' inside EVENT_ANIMATESPRITES\n",
g_szScriptFileName
,g_lineNumber
,tempbuf
);
g_numCompilerWarnings
++;
}
}
continue;
case CON_ACTIVATE
:
*(g_scriptPtr
-1) = CON_OPERATEACTIVATORS
;
C_GetNextValue
(LABEL_DEFINE
);
*g_scriptPtr
++ = 0;
continue;
case CON_GETFLORZOFSLOPE
:
case CON_GETCEILZOFSLOPE
:
C_GetManyVars
(3);
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
case CON_DEFINEPROJECTILE
:
{
int32_t y
, z
;
if (EDUKE32_PREDICT_FALSE
(g_processingState
|| g_parsingActorPtr
))
{
C_ReportError
(ERROR_FOUNDWITHIN
);
g_numCompilerErrors
++;
}
g_scriptPtr
--;
C_GetNextValue
(LABEL_DEFINE
);
j
= *(g_scriptPtr
-1);
C_GetNextValue
(LABEL_DEFINE
);
y
= *(g_scriptPtr
-1);
C_GetNextValue
(LABEL_DEFINE
);
z
= *(g_scriptPtr
-1);
if (EDUKE32_PREDICT_FALSE
((unsigned)j
>= MAXTILES
))
{
C_ReportError
(ERROR_EXCEEDSMAXTILES
);
g_numCompilerErrors
++;
continue;
}
C_DefineProjectile
(j
, y
, z
);
continue;
}
case CON_SPRITEFLAGS
:
if (g_parsingActorPtr
== NULL
&& g_processingState
== 0)
{
g_scriptPtr
--;
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
j
= *g_scriptPtr
;
int32_t flags
= 0;
do
C_BitOrNextValue
(&flags
);
while (C_GetKeyword
() == -1);
if (EDUKE32_PREDICT_FALSE
((unsigned)j
>= MAXTILES
))
{
C_ReportError
(ERROR_EXCEEDSMAXTILES
);
g_numCompilerErrors
++;
continue;
}
g_tile
[j
].
flags = flags
;
continue;
}
C_GetNextVar
();
continue;
case CON_SPRITESHADOW
:
case CON_SPRITENVG
:
case CON_SPRITENOSHADE
:
case CON_SPRITENOPAL
:
case CON_PRECACHE
:
if (EDUKE32_PREDICT_FALSE
(g_processingState
|| g_parsingActorPtr
))
{
C_ReportError
(ERROR_FOUNDWITHIN
);
g_numCompilerErrors
++;
}
g_scriptPtr
--;
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
j
= *g_scriptPtr
;
if (EDUKE32_PREDICT_FALSE
((unsigned)j
>= MAXTILES
))
{
C_ReportError
(ERROR_EXCEEDSMAXTILES
);
g_numCompilerErrors
++;
continue;
}
switch (tw
)
{
case CON_SPRITESHADOW
:
g_tile
[*g_scriptPtr
].
flags |= SFLAG_SHADOW
;
break;
case CON_SPRITENVG
:
g_tile
[*g_scriptPtr
].
flags |= SFLAG_NVG
;
break;
case CON_SPRITENOSHADE
:
g_tile
[*g_scriptPtr
].
flags |= SFLAG_NOSHADE
;
break;
case CON_SPRITENOPAL
:
g_tile
[*g_scriptPtr
].
flags |= SFLAG_NOPAL
;
break;
case CON_PRECACHE
:
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
i
= *g_scriptPtr
;
if (EDUKE32_PREDICT_FALSE
((unsigned)i
>= MAXTILES
))
{
C_ReportError
(ERROR_EXCEEDSMAXTILES
);
g_numCompilerErrors
++;
}
g_tile
[j
].
cacherange = i
;
C_GetNextValue
(LABEL_DEFINE
);
g_scriptPtr
--;
if (*g_scriptPtr
)
g_tile
[j
].
flags |= SFLAG_CACHE
;
break;
}
continue;
case CON_IFACTORSOUND
:
case CON_IFVARVARG
:
case CON_IFVARVARL
:
case CON_IFVARVARE
:
case CON_IFVARVARN
:
case CON_IFVARVARAND
:
case CON_IFVARVAROR
:
case CON_IFVARVARXOR
:
case CON_IFVARVAREITHER
:
case CON_WHILEVARVARN
:
{
intptr_t offset
;
intptr_t lastScriptPtr
= g_scriptPtr
- &script
[0] - 1;
g_ifElseAborted
= 0;
C_GetManyVars
(2);
if (C_CheckMalformedBranch
(lastScriptPtr
))
continue;
tempscrptr
= g_scriptPtr
;
offset
= (unsigned)(g_scriptPtr
-script
);
g_scriptPtr
++; // Leave a spot for the fail location
C_ParseCommand
(0);
if (C_CheckEmptyBranch
(tw
, lastScriptPtr
))
continue;
tempscrptr
= (intptr_t *)script
+offset
;
*tempscrptr
= (intptr_t) g_scriptPtr
;
bitptr
[(tempscrptr
-script
)>>3] |= (BITPTR_POINTER
<<((tempscrptr
-script
)&7));
if (tw
!= CON_WHILEVARVARN
)
{
j
= C_GetKeyword
();
if (j
== CON_ELSE
|| j
== CON_LEFTBRACE
)
g_checkingIfElse
++;
}
continue;
}
case CON_STARTTRACK
:
// one parameter (track#)
C_GetNextValue
(LABEL_DEFINE
);
continue;
case CON_IFVARL
:
case CON_IFVARG
:
case CON_IFVARE
:
case CON_IFVARN
:
case CON_IFVARAND
:
case CON_IFVAROR
:
case CON_IFVARXOR
:
case CON_IFVAREITHER
:
case CON_WHILEVARN
:
{
intptr_t offset
;
intptr_t lastScriptPtr
= (g_scriptPtr
-script
-1);
g_ifElseAborted
= 0;
// get the ID of the DEF
C_GetNextVar
();
C_GetNextValue
(LABEL_DEFINE
); // the number to check against...
if (C_CheckMalformedBranch
(lastScriptPtr
))
continue;
tempscrptr
= g_scriptPtr
;
offset
= (unsigned)(tempscrptr
-script
);
g_scriptPtr
++; //Leave a spot for the fail location
C_ParseCommand
(0);
if (C_CheckEmptyBranch
(tw
, lastScriptPtr
))
continue;
tempscrptr
= (intptr_t *)script
+offset
;
*tempscrptr
= (intptr_t) g_scriptPtr
;
bitptr
[(tempscrptr
-script
)>>3] |= (BITPTR_POINTER
<<((tempscrptr
-script
)&7));
if (tw
!= CON_WHILEVARN
)
{
j
= C_GetKeyword
();
if (j
== CON_ELSE
|| j
== CON_LEFTBRACE
)
g_checkingIfElse
++;
}
continue;
}
case CON_ROTATESPRITE16
:
case CON_ROTATESPRITE
:
if (EDUKE32_PREDICT_FALSE
(g_parsingEventPtr
== NULL
&& g_processingState
== 0))
{
C_ReportError
(ERROR_EVENTONLY
);
g_numCompilerErrors
++;
}
// syntax:
// int32_t x, int32_t y, int32_t z, short a, short tilenum, int8_t shade, char orientation, x1, y1, x2, y2
// myospal adds char pal
// get the ID of the DEFs
C_GetManyVars
(12);
continue;
case CON_ROTATESPRITEA
:
if (EDUKE32_PREDICT_FALSE
(g_parsingEventPtr
== NULL
&& g_processingState
== 0))
{
C_ReportError
(ERROR_EVENTONLY
);
g_numCompilerErrors
++;
}
C_GetManyVars
(13);
continue;
case CON_SHOWVIEW
:
case CON_SHOWVIEWUNBIASED
:
if (EDUKE32_PREDICT_FALSE
(g_parsingEventPtr
== NULL
&& g_processingState
== 0))
{
C_ReportError
(ERROR_EVENTONLY
);
g_numCompilerErrors
++;
}
C_GetManyVars
(10);
continue;
case CON_GETZRANGE
:
C_GetManyVars
(4);
C_GetManyVarsType
(GAMEVAR_READONLY
,4);
C_GetManyVars
(2);
continue;
case CON_CLIPMOVE
:
case CON_CLIPMOVENOSLIDE
:
// <retvar>,<x>,<y>,z,<sectnum>, xvect,yvect,walldist,floordist,ceildist,clipmask
C_GetManyVarsType
(GAMEVAR_READONLY
,3);
C_GetNextVar
();
C_GetNextVarType
(GAMEVAR_READONLY
);
C_GetManyVars
(6);
continue;
case CON_CALCHYPOTENUSE
:
C_GetNextVarType
(GAMEVAR_READONLY
);
C_GetManyVars
(2);
continue;
case CON_LINEINTERSECT
:
case CON_RAYINTERSECT
:
// lineintersect x y z x y z x y x y <intx> <inty> <intz> <ret>
// rayintersect x y z vx vy vz x y x y <intx> <inty> <intz> <ret>
C_GetManyVars
(10);
C_GetManyVarsType
(GAMEVAR_READONLY
,4);
continue;
case CON_HITSCAN
:
case CON_CANSEE
:
// get the ID of the DEF
C_GetManyVars
(tw
==CON_CANSEE
?8:7);
C_GetManyVarsType
(GAMEVAR_READONLY
,tw
==CON_CANSEE
?1:6);
if (tw
==CON_HITSCAN
) C_GetNextVar
();
continue;
case CON_CANSEESPR
:
C_GetManyVars
(2);
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
case CON_NEARTAG
:
C_GetManyVars
(5);
C_GetManyVarsType
(GAMEVAR_READONLY
,4);
C_GetManyVars
(2);
continue;
case CON_ROTATEPOINT
:
C_GetManyVars
(5);
C_GetManyVarsType
(GAMEVAR_READONLY
,2);
continue;
case CON_GETTIMEDATE
:
C_GetManyVarsType
(GAMEVAR_READONLY
,8);
continue;
case CON_MOVESPRITE
:
case CON_SETSPRITE
:
C_GetManyVars
(4);
if (tw
== CON_MOVESPRITE
)
{
C_GetNextVar
();
C_GetNextVarType
(GAMEVAR_READONLY
);
}
continue;
case CON_MINITEXT
:
case CON_GAMETEXT
:
case CON_GAMETEXTZ
:
case CON_DIGITALNUMBER
:
case CON_DIGITALNUMBERZ
:
case CON_SCREENTEXT
:
if (EDUKE32_PREDICT_FALSE
(g_parsingEventPtr
== NULL
&& g_processingState
== 0))
{
C_ReportError
(ERROR_EVENTONLY
);
g_numCompilerErrors
++;
}
switch (tw
)
{
case CON_SCREENTEXT
:
C_GetManyVars
(8);
case CON_GAMETEXTZ
:
case CON_DIGITALNUMBERZ
:
C_GetManyVars
(1);
case CON_GAMETEXT
:
case CON_DIGITALNUMBER
:
C_GetManyVars
(6);
default:
C_GetManyVars
(5);
break;
}
continue;
case CON_UPDATESECTOR
:
case CON_UPDATESECTORZ
:
C_GetManyVars
(2);
if (tw
==CON_UPDATESECTORZ
)
C_GetNextVar
();
C_GetNextVarType
(GAMEVAR_READONLY
);
continue;
case CON_MYOS
:
case CON_MYOSPAL
:
case CON_MYOSX
:
case CON_MYOSPALX
:
if (EDUKE32_PREDICT_FALSE
(g_parsingEventPtr
== NULL
&& g_processingState
== 0))
{
C_ReportError
(ERROR_EVENTONLY
);
g_numCompilerErrors
++;
}
// syntax:
// int32_t x, int32_t y, short tilenum, int8_t shade, char orientation
// myospal adds char pal
C_GetManyVars
(5);
if (tw
==CON_MYOSPAL
|| tw
==CON_MYOSPALX
)
{
// Parse: pal
// get the ID of the DEF
C_GetNextVar
();
}
continue;
case CON_SWITCH
:
{
intptr_t tempoffset
;
g_checkingSwitch
++; // allow nesting (if other things work)
C_GetNextVar
();
tempscrptr
= g_scriptPtr
;
tempoffset
= (unsigned)(tempscrptr
-script
);
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=0; // leave spot for end location (for after processing)
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));
*g_scriptPtr
++=0; // count of case statements
g_caseScriptPtr
=g_scriptPtr
; // the first case's pointer.
bitptr
[(g_scriptPtr
-script
)>>3] &= ~
(BITPTR_POINTER
<<((g_scriptPtr
-script
)&7));