Subversion Repositories eduke32

Rev

Rev 4941 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
398 terminx 1
//-------------------------------------------------------------------------
2
/*
1652 terminx 3
Copyright (C) 2010 EDuke32 developers and contributors
398 terminx 4
 
1652 terminx 5
This file is part of EDuke32.
398 terminx 6
 
7
EDuke32 is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 
15
See the GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
4541 hendricks2 19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
398 terminx 20
*/
21
//-------------------------------------------------------------------------
22
 
23
#include "duke3d.h"
2726 hendricks2 24
#include "common_game.h"
1677 terminx 25
#include "gamevars.h"
398 terminx 26
#include "gamedef.h"
514 terminx 27
#include "osd.h"
1950 helixhorne 28
#include "savegame.h"
4496 hendricks2 29
#include "menus.h"
398 terminx 30
 
4747 terminx 31
#define gamevars_c_
3459 helixhorne 32
 
4286 helixhorne 33
#ifdef LUNATIC
34
int32_t g_noResetVars;
35
LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
36
#else
4902 terminx 37
 
38
gamevar_t aGameVars[MAXGAMEVARS];
39
gamearray_t aGameArrays[MAXGAMEARRAYS];
40
int32_t g_gameVarCount=0;
41
int32_t g_gameArrayCount=0;
42
 
43
// pointers to weapon gamevar data
44
intptr_t *aplWeaponClip[MAX_WEAPONS];       // number of items in magazine
45
intptr_t *aplWeaponReload[MAX_WEAPONS];     // delay to reload (include fire)
46
intptr_t *aplWeaponFireDelay[MAX_WEAPONS];      // delay to fire
47
intptr_t *aplWeaponHoldDelay[MAX_WEAPONS];      // delay after release fire button to fire (0 for none)
48
intptr_t *aplWeaponTotalTime[MAX_WEAPONS];      // The total time the weapon is cycling before next fire.
49
intptr_t *aplWeaponFlags[MAX_WEAPONS];      // Flags for weapon
50
intptr_t *aplWeaponShoots[MAX_WEAPONS];     // what the weapon shoots
51
intptr_t *aplWeaponSpawnTime[MAX_WEAPONS];      // the frame at which to spawn an item
52
intptr_t *aplWeaponSpawn[MAX_WEAPONS];      // the item to spawn
53
intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS];  // number of shots per 'burst' (one ammo per 'burst')
54
intptr_t *aplWeaponWorksLike[MAX_WEAPONS];      // What original the weapon works like
55
intptr_t *aplWeaponInitialSound[MAX_WEAPONS];   // Sound made when weapon starts firing. zero for no sound
56
intptr_t *aplWeaponFireSound[MAX_WEAPONS];      // Sound made when firing (each time for automatic)
57
intptr_t *aplWeaponSound2Time[MAX_WEAPONS];     // Alternate sound time
58
intptr_t *aplWeaponSound2Sound[MAX_WEAPONS];    // Alternate sound sound ID
59
intptr_t *aplWeaponReloadSound1[MAX_WEAPONS];    // Sound of magazine being removed
60
intptr_t *aplWeaponReloadSound2[MAX_WEAPONS];    // Sound of magazine being inserted
61
intptr_t *aplWeaponSelectSound[MAX_WEAPONS];     // Sound of weapon being selected
62
intptr_t *aplWeaponFlashColor[MAX_WEAPONS];     // Muzzle flash color
63
 
3354 helixhorne 64
# include "gamestructures.c"
1204 terminx 65
 
4839 helixhorne 66
// Frees the memory for the *values* of game variables and arrays. Resets their
67
// counts to zero. Call this function as many times as needed.
68
//
69
// Returns: old g_gameVarCount | (g_gameArrayCount<<16).
70
static int32_t Gv_Free(void)
398 terminx 71
{
4839 helixhorne 72
    for (int32_t i=0; i<g_gameVarCount; i++)
782 terminx 73
    {
4698 terminx 74
        if (aGameVars[i].dwFlags & GAMEVAR_USER_MASK)
75
            ALIGNED_FREE_AND_NULL(aGameVars[i].val.plValues);
1657 terminx 76
 
1189 terminx 77
        aGameVars[i].dwFlags |= GAMEVAR_RESET;
4839 helixhorne 78
    }
1657 terminx 79
 
4839 helixhorne 80
    for (int32_t i=0; i<g_gameArrayCount; i++)
81
    {
4698 terminx 82
        if (aGameArrays[i].dwFlags & GAMEARRAY_NORMAL)
83
            ALIGNED_FREE_AND_NULL(aGameArrays[i].plValues);
1657 terminx 84
 
3274 hendricks2 85
        aGameArrays[i].dwFlags |= GAMEARRAY_RESET;
782 terminx 86
    }
3416 helixhorne 87
 
4839 helixhorne 88
    EDUKE32_STATIC_ASSERT(MAXGAMEVARS < 32768);
89
    int32_t ret = g_gameVarCount | (g_gameArrayCount<<16);
3416 helixhorne 90
    g_gameVarCount = g_gameArrayCount = 0;
4839 helixhorne 91
 
1625 terminx 92
    hash_init(&h_gamevars);
93
    hash_init(&h_arrays);
4839 helixhorne 94
 
95
    return ret;
398 terminx 96
}
97
 
4839 helixhorne 98
// Calls Gv_Free() and in addition frees the labels of all game variables and
99
// arrays.
100
// Only call this function ONCE...
1143 terminx 101
static void Gv_Clear(void)
398 terminx 102
{
4839 helixhorne 103
    int32_t n = Gv_Free();
104
    int32_t gameVarCount = n&65535, gameArrayCount = n>>16;
398 terminx 105
 
3416 helixhorne 106
    // Now, only do work that Gv_Free() hasn't done.
4839 helixhorne 107
    for (int32_t i=0; i<gameVarCount; i++)
4698 terminx 108
        DO_FREE_AND_NULL(aGameVars[i].szLabel);
398 terminx 109
 
4839 helixhorne 110
    for (int32_t i=0; i<gameArrayCount; i++)
4698 terminx 111
        DO_FREE_AND_NULL(aGameArrays[i].szLabel);
398 terminx 112
}
113
 
1595 helixhorne 114
int32_t Gv_ReadSave(int32_t fil, int32_t newbehav)
398 terminx 115
{
860 terminx 116
    char savedstate[MAXVOLUMES*MAXLEVELS];
1595 helixhorne 117
    char tbuf[12];
398 terminx 118
 
1595 helixhorne 119
    if (newbehav)
120
    {
121
        if (kread(fil, tbuf, 12)!=12) goto corrupt;
122
        if (Bmemcmp(tbuf, "BEG: EDuke32", 12)) { OSD_Printf("BEG ERR\n"); return 2; }
123
    }
124
 
860 terminx 125
    Bmemset(&savedstate,0,sizeof(savedstate));
126
 
782 terminx 127
    //     AddLog("Reading gamevars from savegame");
398 terminx 128
 
1143 terminx 129
    Gv_Free(); // nuke 'em from orbit, it's the only way to be sure...
1185 terminx 130
 
782 terminx 131
    //  Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
132
    //  AddLog(g_szBuf);
398 terminx 133
 
1143 terminx 134
    if (kdfread(&g_gameVarCount,sizeof(g_gameVarCount),1,fil) != 1) goto corrupt;
5069 terminx 135
    for (int i=0; i<g_gameVarCount; i++)
782 terminx 136
    {
4839 helixhorne 137
        char *const olabel = aGameVars[i].szLabel;
138
 
139
        if (kdfread(&aGameVars[i], sizeof(gamevar_t), 1, fil) != 1)
140
            goto corrupt;
141
 
142
        if (olabel == NULL)
143
            aGameVars[i].szLabel = (char *)Xmalloc(MAXVARLABEL * sizeof(uint8_t));
144
        else
145
            aGameVars[i].szLabel = olabel;
146
 
147
        if (kdfread(aGameVars[i].szLabel, MAXVARLABEL, 1, fil) != 1)
148
            goto corrupt;
1677 terminx 149
        hash_add(&h_gamevars, aGameVars[i].szLabel,i, 1);
398 terminx 150
 
1143 terminx 151
        if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
782 terminx 152
        {
4698 terminx 153
            aGameVars[i].val.plValues = (intptr_t*)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
1189 terminx 154
            if (kdfread(aGameVars[i].val.plValues,sizeof(intptr_t) * MAXPLAYERS, 1, fil) != 1) goto corrupt;
782 terminx 155
        }
1143 terminx 156
        else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR)
782 terminx 157
        {
4698 terminx 158
            aGameVars[i].val.plValues = (intptr_t*)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
1189 terminx 159
            if (kdfread(&aGameVars[i].val.plValues[0],sizeof(intptr_t), MAXSPRITES, fil) != MAXSPRITES) goto corrupt;
782 terminx 160
        }
161
    }
1189 terminx 162
    //  Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
163
    //  AddLog(g_szBuf);
398 terminx 164
 
1189 terminx 165
    Gv_InitWeaponPointers();
166
 
1182 terminx 167
    //  Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
168
    //  AddLog(g_szBuf);
1143 terminx 169
    Gv_RefreshPointers();
534 terminx 170
 
1143 terminx 171
    if (kdfread(&g_gameArrayCount,sizeof(g_gameArrayCount),1,fil) != 1) goto corrupt;
5069 terminx 172
    for (int i=0; i<g_gameArrayCount; i++)
782 terminx 173
    {
3295 helixhorne 174
        if (aGameArrays[i].dwFlags&GAMEARRAY_READONLY)
175
            continue;
176
 
4839 helixhorne 177
        char *const olabel = aGameArrays[i].szLabel;
178
 
3295 helixhorne 179
        // read for .size and .dwFlags (the rest are pointers):
4839 helixhorne 180
        if (kdfread(&aGameArrays[i], sizeof(gamearray_t), 1, fil) != 1)
181
            goto corrupt;
3295 helixhorne 182
 
4839 helixhorne 183
        if (olabel == NULL)
184
            aGameArrays[i].szLabel = (char *)Xmalloc(MAXARRAYLABEL * sizeof(uint8_t));
185
        else
186
            aGameArrays[i].szLabel = olabel;
187
 
188
        if (kdfread(aGameArrays[i].szLabel,sizeof(uint8_t) * MAXARRAYLABEL, 1, fil) != 1)
189
            goto corrupt;
1677 terminx 190
        hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
1189 terminx 191
 
4698 terminx 192
        aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, aGameArrays[i].size * GAR_ELTSZ);
2689 helixhorne 193
        if (kdfread(aGameArrays[i].plValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
782 terminx 194
    }
676 terminx 195
 
782 terminx 196
    //  Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
197
    //  AddLog(g_szBuf);
198
    if (kdfread(apScriptGameEvent,sizeof(apScriptGameEvent),1,fil) != 1) goto corrupt;
1950 helixhorne 199
    G_Util_PtrToIdx(apScriptGameEvent, MAXGAMEEVENTS, script, P2I_BACK_NON0);
398 terminx 200
 
782 terminx 201
    //  Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
202
    //  AddLog(g_szBuf);
860 terminx 203
 
204
    if (kdfread(&savedstate[0],sizeof(savedstate),1,fil) != 1) goto corrupt;
205
 
5069 terminx 206
    for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
860 terminx 207
    {
208
        if (savedstate[i])
209
        {
1143 terminx 210
            if (MapInfo[i].savedstate == NULL)
4698 terminx 211
                MapInfo[i].savedstate = (mapstate_t *)Xaligned_alloc(16, sizeof(mapstate_t));
1143 terminx 212
            if (kdfread(MapInfo[i].savedstate,sizeof(mapstate_t),1,fil) != sizeof(mapstate_t)) goto corrupt;
5069 terminx 213
            for (int j=0; j<g_gameVarCount; j++)
862 terminx 214
            {
1143 terminx 215
                if (aGameVars[j].dwFlags & GAMEVAR_NORESET) continue;
216
                if (aGameVars[j].dwFlags & GAMEVAR_PERPLAYER)
862 terminx 217
                {
1451 terminx 218
//                    if (!MapInfo[i].savedstate->vars[j])
4698 terminx 219
                    MapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
1143 terminx 220
                    if (kdfread(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil) != 1) goto corrupt;
862 terminx 221
                }
1143 terminx 222
                else if (aGameVars[j].dwFlags & GAMEVAR_PERACTOR)
862 terminx 223
                {
1451 terminx 224
//                    if (!MapInfo[i].savedstate->vars[j])
4698 terminx 225
                    MapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
1143 terminx 226
                    if (kdfread(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil) != MAXSPRITES) goto corrupt;
862 terminx 227
                }
228
            }
860 terminx 229
        }
3791 helixhorne 230
        else
860 terminx 231
        {
1143 terminx 232
            G_FreeMapState(i);
860 terminx 233
        }
234
    }
235
 
1595 helixhorne 236
    if (!newbehav)
237
    {
2185 helixhorne 238
        intptr_t l;
239
 
1595 helixhorne 240
        if (kdfread(&l,sizeof(l),1,fil) != 1) goto corrupt;
241
        if (kdfread(g_szBuf,l,1,fil) != 1) goto corrupt;
242
        g_szBuf[l]=0;
243
        OSD_Printf("%s\n",g_szBuf);
244
    }
245
    else
246
    {
247
        if (kread(fil, tbuf, 12)!=12) goto corrupt;
248
        if (Bmemcmp(tbuf, "EOF: EDuke32", 12)) { OSD_Printf("EOF ERR\n"); return 2; }
249
    }
398 terminx 250
 
3459 helixhorne 251
# if 0
782 terminx 252
    {
253
        FILE *fp;
254
        AddLog("Dumping Vars...");
255
        fp=fopen("xxx.txt","w");
256
        if (fp)
257
        {
1143 terminx 258
            Gv_DumpValues(fp);
782 terminx 259
            fclose(fp);
260
        }
261
        AddLog("Done Dumping...");
262
    }
3459 helixhorne 263
# endif
782 terminx 264
    return(0);
398 terminx 265
corrupt:
782 terminx 266
    return(1);
398 terminx 267
}
268
 
1595 helixhorne 269
void Gv_WriteSave(FILE *fil, int32_t newbehav)
398 terminx 270
{
860 terminx 271
    char savedstate[MAXVOLUMES*MAXLEVELS];
398 terminx 272
 
860 terminx 273
    Bmemset(&savedstate,0,sizeof(savedstate));
274
 
782 terminx 275
    //   AddLog("Saving Game Vars to File");
1595 helixhorne 276
    if (newbehav)
277
        fwrite("BEG: EDuke32", 12, 1, fil);
278
 
1143 terminx 279
    dfwrite(&g_gameVarCount,sizeof(g_gameVarCount),1,fil);
398 terminx 280
 
5069 terminx 281
    for (int i=0; i<g_gameVarCount; i++)
782 terminx 282
    {
283
        dfwrite(&(aGameVars[i]),sizeof(gamevar_t),1,fil);
1205 terminx 284
        dfwrite(aGameVars[i].szLabel,sizeof(uint8_t) * MAXVARLABEL, 1, fil);
398 terminx 285
 
1143 terminx 286
        if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
782 terminx 287
        {
1205 terminx 288
            //Bsprintf(g_szBuf,"Writing value array for %s (%d)",aGameVars[i].szLabel,sizeof(int32_t) * MAXPLAYERS);
782 terminx 289
            //AddLog(g_szBuf);
1189 terminx 290
            dfwrite(aGameVars[i].val.plValues,sizeof(intptr_t) * MAXPLAYERS, 1, fil);
782 terminx 291
        }
1143 terminx 292
        else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR)
782 terminx 293
        {
1205 terminx 294
            //Bsprintf(g_szBuf,"Writing value array for %s (%d)",aGameVars[i].szLabel,sizeof(int32_t) * MAXSPRITES);
782 terminx 295
            //AddLog(g_szBuf);
1189 terminx 296
            dfwrite(&aGameVars[i].val.plValues[0],sizeof(intptr_t), MAXSPRITES, fil);
782 terminx 297
        }
298
    }
398 terminx 299
 
1143 terminx 300
    dfwrite(&g_gameArrayCount,sizeof(g_gameArrayCount),1,fil);
676 terminx 301
 
5069 terminx 302
    for (int i=0; i<g_gameArrayCount; i++)
782 terminx 303
    {
3295 helixhorne 304
        if (aGameArrays[i].dwFlags&GAMEARRAY_READONLY)
305
            continue;
306
 
307
        // write for .size and .dwFlags (the rest are pointers):
308
        dfwrite(&aGameArrays[i],sizeof(gamearray_t),1,fil);
309
 
1205 terminx 310
        dfwrite(aGameArrays[i].szLabel,sizeof(uint8_t) * MAXARRAYLABEL, 1, fil);
2689 helixhorne 311
        dfwrite(aGameArrays[i].plValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil);
782 terminx 312
    }
676 terminx 313
 
1950 helixhorne 314
    G_Util_PtrToIdx(apScriptGameEvent, MAXGAMEEVENTS, script, P2I_FWD_NON0);
782 terminx 315
    dfwrite(apScriptGameEvent,sizeof(apScriptGameEvent),1,fil);
1950 helixhorne 316
    G_Util_PtrToIdx(apScriptGameEvent, MAXGAMEEVENTS, script, P2I_BACK_NON0);
398 terminx 317
 
5069 terminx 318
    for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
1143 terminx 319
        if (MapInfo[i].savedstate != NULL)
860 terminx 320
            savedstate[i] = 1;
321
 
322
    dfwrite(&savedstate[0],sizeof(savedstate),1,fil);
323
 
5069 terminx 324
    for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
1143 terminx 325
        if (MapInfo[i].savedstate)
862 terminx 326
        {
1143 terminx 327
            dfwrite(MapInfo[i].savedstate,sizeof(mapstate_t),1,fil);
5069 terminx 328
            for (int j=0; j<g_gameVarCount; j++)
862 terminx 329
            {
1143 terminx 330
                if (aGameVars[j].dwFlags & GAMEVAR_NORESET) continue;
331
                if (aGameVars[j].dwFlags & GAMEVAR_PERPLAYER)
862 terminx 332
                {
1143 terminx 333
                    dfwrite(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil);
862 terminx 334
                }
1143 terminx 335
                else if (aGameVars[j].dwFlags & GAMEVAR_PERACTOR)
862 terminx 336
                {
1540 terminx 337
                    dfwrite(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil);
862 terminx 338
                }
339
            }
340
        }
860 terminx 341
 
1595 helixhorne 342
    if (!newbehav)
343
    {
2185 helixhorne 344
        intptr_t l;
345
 
1595 helixhorne 346
        Bsprintf(g_szBuf,"EOF: EDuke32");
347
        l=Bstrlen(g_szBuf);
348
        dfwrite(&l,sizeof(l),1,fil);
349
        dfwrite(g_szBuf,l,1,fil);
350
    }
351
    else
352
        fwrite("EOF: EDuke32", 12, 1, fil);
398 terminx 353
}
354
 
1221 terminx 355
void Gv_DumpValues(void)
398 terminx 356
{
1205 terminx 357
    int32_t i;
1195 terminx 358
 
1221 terminx 359
    OSD_Printf("// Current Game Definitions\n\n");
1195 terminx 360
 
1229 terminx 361
    for (i=0; i<g_gameVarCount; i++)
782 terminx 362
    {
1143 terminx 363
        if (aGameVars[i].dwFlags & (GAMEVAR_SECRET))
782 terminx 364
            continue; // do nothing...
1195 terminx 365
 
1221 terminx 366
        OSD_Printf("gamevar %s ",aGameVars[i].szLabel);
1195 terminx 367
 
368
        if (aGameVars[i].dwFlags & (GAMEVAR_INTPTR))
1677 terminx 369
            OSD_Printf("%d",*((int32_t *)aGameVars[i].val.lValue));
1195 terminx 370
        else if (aGameVars[i].dwFlags & (GAMEVAR_SHORTPTR))
1677 terminx 371
            OSD_Printf("%d",*((int16_t *)aGameVars[i].val.lValue));
1195 terminx 372
        else if (aGameVars[i].dwFlags & (GAMEVAR_CHARPTR))
1677 terminx 373
            OSD_Printf("%d",*((char *)aGameVars[i].val.lValue));
782 terminx 374
        else
1221 terminx 375
            OSD_Printf("%" PRIdPTR "",aGameVars[i].val.lValue);
376
 
1195 terminx 377
        if (aGameVars[i].dwFlags & (GAMEVAR_PERPLAYER))
1221 terminx 378
            OSD_Printf(" GAMEVAR_PERPLAYER");
1195 terminx 379
        else if (aGameVars[i].dwFlags & (GAMEVAR_PERACTOR))
1221 terminx 380
            OSD_Printf(" GAMEVAR_PERACTOR");
1195 terminx 381
        else
4321 hendricks2 382
            OSD_Printf(" %" PRIdPTR,aGameVars[i].dwFlags/* & (GAMEVAR_USER_MASK)*/);
1221 terminx 383
 
384
        OSD_Printf(" // ");
1195 terminx 385
        if (aGameVars[i].dwFlags & (GAMEVAR_SYSTEM))
1221 terminx 386
            OSD_Printf(" (system)");
1857 terminx 387
        if (aGameVars[i].dwFlags & (GAMEVAR_PTR_MASK))
1221 terminx 388
            OSD_Printf(" (pointer)");
1195 terminx 389
        if (aGameVars[i].dwFlags & (GAMEVAR_READONLY))
1221 terminx 390
            OSD_Printf(" (read only)");
391
        if (aGameVars[i].dwFlags & (GAMEVAR_SPECIAL))
392
            OSD_Printf(" (special)");
393
        OSD_Printf("\n");
782 terminx 394
    }
1221 terminx 395
    OSD_Printf("\n// end of game definitions\n");
398 terminx 396
}
397
 
2230 helixhorne 398
// XXX: This function is very strange.
1179 terminx 399
void Gv_ResetVars(void) /* this is called during a new game and nowhere else */
398 terminx 400
{
1143 terminx 401
    Gv_Free();
398 terminx 402
 
4536 terminx 403
    osd->log.errors = 0;
404
 
5069 terminx 405
    for (int i=0; i<MAXGAMEVARS; i++)
782 terminx 406
    {
1665 terminx 407
        if (aGameVars[i].szLabel != NULL)
408
            Gv_NewVar(aGameVars[i].szLabel,
1677 terminx 409
                      aGameVars[i].dwFlags & GAMEVAR_NODEFAULT ? aGameVars[i].val.lValue : aGameVars[i].lDefault,
410
                      aGameVars[i].dwFlags);
782 terminx 411
    }
676 terminx 412
 
5069 terminx 413
    for (int i=0; i<MAXGAMEARRAYS; i++)
782 terminx 414
    {
3274 hendricks2 415
        if (aGameArrays[i].szLabel != NULL && (aGameArrays[i].dwFlags & GAMEARRAY_RESET))
416
            Gv_NewArray(aGameArrays[i].szLabel,aGameArrays[i].plValues,aGameArrays[i].size,aGameArrays[i].dwFlags);
782 terminx 417
    }
398 terminx 418
}
419
 
3274 hendricks2 420
int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags)
676 terminx 421
{
1205 terminx 422
    int32_t i;
676 terminx 423
 
4680 terminx 424
    if (EDUKE32_PREDICT_FALSE(g_gameArrayCount >= MAXGAMEARRAYS))
1179 terminx 425
    {
426
        g_numCompilerErrors++;
427
        C_ReportError(-1);
428
        initprintf("%s:%d: error: too many arrays!\n",g_szScriptFileName,g_lineNumber);
429
        return 0;
430
    }
431
 
4680 terminx 432
    if (EDUKE32_PREDICT_FALSE(Bstrlen(pszLabel) > (MAXARRAYLABEL-1)))
782 terminx 433
    {
1143 terminx 434
        g_numCompilerErrors++;
435
        C_ReportError(-1);
436
        initprintf("%s:%d: error: array name `%s' exceeds limit of %d characters.\n",g_szScriptFileName,g_lineNumber,pszLabel, MAXARRAYLABEL);
782 terminx 437
        return 0;
438
    }
1625 terminx 439
    i = hash_find(&h_arrays,pszLabel);
4680 terminx 440
 
441
    if (EDUKE32_PREDICT_FALSE(i >=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET)))
782 terminx 442
    {
1024 terminx 443
        // found it it's a duplicate in error
3274 hendricks2 444
 
1143 terminx 445
        g_numCompilerWarnings++;
3274 hendricks2 446
 
447
        if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK)
448
        {
449
            C_ReportError(-1);
450
            initprintf("ignored redefining system array `%s'.", pszLabel);
451
        }
452
        else
453
            C_ReportError(WARNING_DUPLICATEDEFINITION);
454
 
1024 terminx 455
        return 0;
782 terminx 456
    }
1179 terminx 457
 
1143 terminx 458
    i = g_gameArrayCount;
1179 terminx 459
 
460
    if (aGameArrays[i].szLabel == NULL)
4839 helixhorne 461
        aGameArrays[i].szLabel = (char *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
4698 terminx 462
 
1179 terminx 463
    if (aGameArrays[i].szLabel != pszLabel)
464
        Bstrcpy(aGameArrays[i].szLabel,pszLabel);
3274 hendricks2 465
 
466
    if (!(dwFlags & GAMEARRAY_TYPE_MASK))
4698 terminx 467
    {
4793 helixhorne 468
        Baligned_free(aGameArrays[i].plValues);
4698 terminx 469
        aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
470
        Bmemset(aGameArrays[i].plValues, 0, asize * GAR_ELTSZ);
471
    }
3274 hendricks2 472
    else
473
        aGameArrays[i].plValues=(intptr_t *)arrayptr;
474
 
1179 terminx 475
    aGameArrays[i].size=asize;
3274 hendricks2 476
    aGameArrays[i].dwFlags = dwFlags & ~GAMEARRAY_RESET;
477
 
1179 terminx 478
    g_gameArrayCount++;
1677 terminx 479
    hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
3354 helixhorne 480
 
1179 terminx 481
    return 1;
676 terminx 482
}
483
 
2005 terminx 484
int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
398 terminx 485
{
1205 terminx 486
    int32_t i, j;
398 terminx 487
 
1179 terminx 488
    //Bsprintf(g_szBuf,"Gv_NewVar(%s, %d, %X)",pszLabel, lValue, dwFlags);
782 terminx 489
    //AddLog(g_szBuf);
398 terminx 490
 
4680 terminx 491
    if (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS))
1179 terminx 492
    {
493
        g_numCompilerErrors++;
494
        C_ReportError(-1);
495
        initprintf("%s:%d: error: too many gamevars!\n",g_szScriptFileName,g_lineNumber);
496
        return 0;
497
    }
498
 
4680 terminx 499
    if (EDUKE32_PREDICT_FALSE(Bstrlen(pszLabel) > (MAXVARLABEL-1)))
782 terminx 500
    {
1143 terminx 501
        g_numCompilerErrors++;
502
        C_ReportError(-1);
503
        initprintf("%s:%d: error: variable name `%s' exceeds limit of %d characters.\n",g_szScriptFileName,g_lineNumber,pszLabel, MAXVARLABEL);
782 terminx 504
        return 0;
505
    }
1179 terminx 506
 
1625 terminx 507
    i = hash_find(&h_gamevars,pszLabel);
1034 terminx 508
 
1189 terminx 509
    if (i >= 0 && !(aGameVars[i].dwFlags & GAMEVAR_RESET))
782 terminx 510
    {
1034 terminx 511
        // found it...
4680 terminx 512
        if (EDUKE32_PREDICT_FALSE(aGameVars[i].dwFlags & (GAMEVAR_PTR_MASK)))
782 terminx 513
        {
1143 terminx 514
            C_ReportError(-1);
515
            initprintf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
1034 terminx 516
            return 0;
782 terminx 517
        }
4680 terminx 518
        else if (EDUKE32_PREDICT_FALSE(!(aGameVars[i].dwFlags & GAMEVAR_SYSTEM)))
1034 terminx 519
        {
520
            // it's a duplicate in error
1143 terminx 521
            g_numCompilerWarnings++;
522
            C_ReportError(WARNING_DUPLICATEDEFINITION);
1034 terminx 523
            return 0;
524
        }
782 terminx 525
    }
1179 terminx 526
 
1034 terminx 527
    if (i == -1)
1143 terminx 528
        i = g_gameVarCount;
1034 terminx 529
 
3416 helixhorne 530
    // If it's a user gamevar...
1143 terminx 531
    if ((aGameVars[i].dwFlags & GAMEVAR_SYSTEM) == 0)
1035 terminx 532
    {
3416 helixhorne 533
        // Allocate and set its label
1035 terminx 534
        if (aGameVars[i].szLabel == NULL)
4491 helixhorne 535
            aGameVars[i].szLabel = (char *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
4698 terminx 536
 
1035 terminx 537
        if (aGameVars[i].szLabel != pszLabel)
538
            Bstrcpy(aGameVars[i].szLabel,pszLabel);
3416 helixhorne 539
 
540
        // and the flags
1035 terminx 541
        aGameVars[i].dwFlags=dwFlags;
542
 
4698 terminx 543
        // only free if per-{actor,player}
1195 terminx 544
        if (aGameVars[i].dwFlags & GAMEVAR_USER_MASK)
4698 terminx 545
            ALIGNED_FREE_AND_NULL(aGameVars[i].val.plValues);
782 terminx 546
    }
1035 terminx 547
 
548
    // if existing is system, they only get to change default value....
1189 terminx 549
    aGameVars[i].lDefault = lValue;
550
    aGameVars[i].dwFlags &= ~GAMEVAR_RESET;
1035 terminx 551
 
1179 terminx 552
    if (i == g_gameVarCount)
782 terminx 553
    {
1035 terminx 554
        // we're adding a new one.
1677 terminx 555
        hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0);
782 terminx 556
    }
1035 terminx 557
 
3416 helixhorne 558
    // Set initial values. (Or, override values for system gamevars.)
1143 terminx 559
    if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
1035 terminx 560
    {
1189 terminx 561
        if (!aGameVars[i].val.plValues)
4698 terminx 562
        {
563
            aGameVars[i].val.plValues = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
564
            Bmemset(aGameVars[i].val.plValues, 0, MAXPLAYERS * sizeof(intptr_t));
565
        }
1229 terminx 566
        for (j=MAXPLAYERS-1; j>=0; j--)
1189 terminx 567
            aGameVars[i].val.plValues[j]=lValue;
1035 terminx 568
    }
1143 terminx 569
    else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR)
1035 terminx 570
    {
1189 terminx 571
        if (!aGameVars[i].val.plValues)
4698 terminx 572
        {
573
            aGameVars[i].val.plValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
574
            Bmemset(aGameVars[i].val.plValues, 0, MAXSPRITES * sizeof(intptr_t));
575
        }
1229 terminx 576
        for (j=MAXSPRITES-1; j>=0; j--)
1189 terminx 577
            aGameVars[i].val.plValues[j]=lValue;
1035 terminx 578
    }
1189 terminx 579
    else aGameVars[i].val.lValue = lValue;
580
 
1035 terminx 581
    return 1;
398 terminx 582
}
583
 
1205 terminx 584
static int32_t Gv_GetVarIndex(const char *szGameLabel)
398 terminx 585
{
1625 terminx 586
    int32_t i = hash_find(&h_gamevars,szGameLabel);
4680 terminx 587
 
588
    if (EDUKE32_PREDICT_FALSE(i == -1))
1185 terminx 589
    {
3343 helixhorne 590
        OSD_Printf(OSD_ERROR "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n",szGameLabel);
1185 terminx 591
        return 0;
592
    }
4680 terminx 593
 
1185 terminx 594
    return i;
398 terminx 595
}
596
 
4631 terminx 597
int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer)
398 terminx 598
{
1440 terminx 599
    if (id == g_iThisActorID)
600
        return iActor;
601
 
782 terminx 602
    if (id == MAXGAMEVARS)
4895 terminx 603
        return *insptr++;
715 terminx 604
 
4895 terminx 605
    int negateResult = !!(id & (MAXGAMEVARS << 1));
4680 terminx 606
 
607
    if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && !negateResult))
608
        goto nastyhacks;
609
 
4895 terminx 610
    id &= (MAXGAMEVARS - 1);
4680 terminx 611
 
4895 terminx 612
    int rv, f;
613
    f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK);
614
 
5069 terminx 615
    if (!f) rv = aGameVars[id].val.lValue;
4895 terminx 616
    else if (f == GAMEVAR_PERPLAYER)
782 terminx 617
    {
5069 terminx 618
        if (EDUKE32_PREDICT_FALSE((unsigned) iPlayer >= MAXPLAYERS)) goto badplayer;
619
        rv = aGameVars[id].val.plValues[iPlayer];
4895 terminx 620
    }
621
    else if (f == GAMEVAR_PERACTOR)
622
    {
5069 terminx 623
        if (EDUKE32_PREDICT_FALSE((unsigned) iActor >= MAXSPRITES)) goto badsprite;
624
        rv = aGameVars[id].val.plValues[iActor];
4680 terminx 625
    }
4895 terminx 626
    else switch (f)
627
    {
5069 terminx 628
        case GAMEVAR_INTPTR: rv = *(int32_t *)aGameVars[id].val.lValue; break;
629
        case GAMEVAR_SHORTPTR: rv = *(int16_t *)aGameVars[id].val.lValue; break;
630
        case GAMEVAR_CHARPTR: rv = *(char *)aGameVars[id].val.lValue; break;
4941 hendricks2 631
        default: EDUKE32_UNREACHABLE_SECTION(rv = 0; break);
4895 terminx 632
    }
961 terminx 633
 
5069 terminx 634
    return (rv ^ -negateResult) + negateResult;
4895 terminx 635
 
4680 terminx 636
nastyhacks:
4895 terminx 637
    if (id & (MAXGAMEVARS << 2))  // array
4680 terminx 638
    {
4895 terminx 639
        id &= (MAXGAMEVARS - 1);  // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
715 terminx 640
 
4895 terminx 641
        int32_t index = Gv_GetVar(*insptr++, iActor, iPlayer);
1179 terminx 642
 
4895 terminx 643
        if (EDUKE32_PREDICT_FALSE((unsigned)index >= (unsigned)aGameArrays[id].size))
4680 terminx 644
        {
645
            iActor = index;
646
            goto badindex;
647
        }
1440 terminx 648
 
5069 terminx 649
        rv = aGameArrays[id].plValues[index];
4680 terminx 650
    }
5069 terminx 651
    else if (id&(MAXGAMEVARS<<3)) // struct shortcut vars
4680 terminx 652
    {
5069 terminx 653
        int indexvar = *insptr;
4680 terminx 654
        int32_t index=Gv_GetVar(*insptr++, iActor, iPlayer);
1204 terminx 655
 
4680 terminx 656
        switch ((id&(MAXGAMEVARS-1)) - g_iSpriteVarID)
657
        {
658
        case 0: //if (id == g_iSpriteVarID)
659
        {
5069 terminx 660
            int const label = *insptr++;
1204 terminx 661
 
4680 terminx 662
            /*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/
5069 terminx 663
            indexvar = (EDUKE32_PREDICT_FALSE(ActorLabels[label].flags & LABEL_HASPARM2)) ?
664
                        Gv_GetVar(*insptr++, iActor, iPlayer) : 0;
1204 terminx 665
 
4680 terminx 666
            if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXSPRITES))
667
            {
5069 terminx 668
                iActor = index;
4680 terminx 669
                goto badsprite;
670
            }
2016 terminx 671
 
5069 terminx 672
            rv = VM_AccessSpriteX(index, label, indexvar) ^ -negateResult;
673
            break;
4680 terminx 674
        }
5069 terminx 675
 
4680 terminx 676
        case 3: //else if (id == g_iPlayerVarID)
677
        {
5069 terminx 678
            int const label = *insptr++;
1204 terminx 679
 
5069 terminx 680
            if (indexvar == g_iThisActorID) index = vm.g_p;
1204 terminx 681
 
5069 terminx 682
            indexvar = (EDUKE32_PREDICT_FALSE(PlayerLabels[label].flags & LABEL_HASPARM2)) ?
683
                Gv_GetVar(*insptr++, iActor, iPlayer) : 0;
2016 terminx 684
 
4680 terminx 685
            if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXPLAYERS))
686
            {
687
                iPlayer = index;
688
                goto badplayer;
1204 terminx 689
            }
690
 
5069 terminx 691
            rv = VM_AccessPlayerX(index, label, indexvar);
692
            break;
782 terminx 693
        }
5069 terminx 694
 
4680 terminx 695
        case 4: //else if (id == g_iActorVarID)
5069 terminx 696
            rv = Gv_GetVar(*insptr++, index, iPlayer);
697
            break;
698
 
4680 terminx 699
        case 1: //else if (id == g_iSectorVarID)
5069 terminx 700
            if (indexvar == g_iThisActorID) index = sprite[vm.g_i].sectnum;
4680 terminx 701
            if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXSECTORS))
702
            {
703
                iPlayer = index;
704
                insptr++;
705
                goto badsector;
706
            }
5069 terminx 707
            rv = VM_AccessSectorX(index, *insptr++);
708
            break;
709
 
4680 terminx 710
        case 2: //else if (id == g_iWallVarID)
711
            if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXWALLS))
712
            {
713
                iPlayer = index;
714
                insptr++;
715
                goto badwall;
716
            }
5069 terminx 717
            rv = VM_AccessWallX(index, *insptr++);
718
            break;
719
 
1189 terminx 720
        default:
4680 terminx 721
            EDUKE32_UNREACHABLE_SECTION(return -1);
782 terminx 722
        }
723
    }
5069 terminx 724
    else
725
    {
726
        CON_ERRPRINTF("Gv_GetVar(): invalid gamevar ID (%d)\n", id);
727
        return -1;
728
    }
1857 terminx 729
 
5069 terminx 730
    return (rv ^ -negateResult) + negateResult;
4680 terminx 731
 
1857 terminx 732
badindex:
3000 helixhorne 733
    CON_ERRPRINTF("Gv_GetVar(): invalid array index (%s[%d])\n", aGameArrays[id].szLabel,iActor);
1857 terminx 734
    return -1;
735
 
2016 terminx 736
badplayer:
3000 helixhorne 737
    CON_ERRPRINTF("Gv_GetVar(): invalid player ID %d\n", iPlayer);
2016 terminx 738
    return -1;
739
 
740
badsprite:
5069 terminx 741
    CON_ERRPRINTF("Gv_GetVar(): invalid sprite ID %d\n", iActor);
2016 terminx 742
    return -1;
743
 
2381 helixhorne 744
badsector:
3000 helixhorne 745
    CON_ERRPRINTF("Gv_GetVar(): invalid sector ID %d\n", iPlayer);
2381 helixhorne 746
    return -1;
747
 
748
badwall:
3000 helixhorne 749
    CON_ERRPRINTF("Gv_GetVar(): invalid wall ID %d\n", iPlayer);
2381 helixhorne 750
    return -1;
398 terminx 751
}
1179 terminx 752
 
5069 terminx 753
void __fastcall Gv_SetVar(int32_t const id, int32_t const lValue, int32_t const iActor, int32_t const iPlayer)
398 terminx 754
{
4680 terminx 755
    if (EDUKE32_PREDICT_FALSE((unsigned)id >= (unsigned)g_gameVarCount)) goto badvarid;
1440 terminx 756
 
4895 terminx 757
    int f;
758
    f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
1189 terminx 759
 
4895 terminx 760
    if (!f) aGameVars[id].val.lValue=lValue;
761
    else if (f == GAMEVAR_PERPLAYER)
782 terminx 762
    {
4895 terminx 763
        if (EDUKE32_PREDICT_FALSE((unsigned) iPlayer > MAXPLAYERS-1)) goto badindex;
782 terminx 764
        // for the current player
1189 terminx 765
        aGameVars[id].val.plValues[iPlayer]=lValue;
4895 terminx 766
    }
767
    else if (f == GAMEVAR_PERACTOR)
768
    {
769
        if (EDUKE32_PREDICT_FALSE((unsigned) iActor > MAXSPRITES-1)) goto badindex;
1189 terminx 770
        aGameVars[id].val.plValues[iActor]=lValue;
1143 terminx 771
    }
4895 terminx 772
    else
773
    {
774
        switch (f)
775
        {
776
            case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) = (int32_t)lValue; break;
777
            case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) = (int16_t)lValue; break;
778
            case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) = (uint8_t)lValue; break;
779
        }
780
    }
781
    return;
1440 terminx 782
 
783
badvarid:
3000 helixhorne 784
    CON_ERRPRINTF("Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n",
3238 hendricks2 785
                  id,vm.g_i,TrackerCast(sprite[vm.g_i].picnum),vm.g_p);
1440 terminx 786
    return;
787
 
1820 terminx 788
badindex:
3000 helixhorne 789
    CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s from sprite %d, player %d\n",
1820 terminx 790
               aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? iActor : iPlayer,
791
               aGameVars[id].szLabel,vm.g_i,vm.g_p);
1189 terminx 792
}
1143 terminx 793
 
4631 terminx 794
enum {
795
    GVX_BADVARID = 0,
796
    GVX_BADPLAYER,
797
    GVX_BADSPRITE,
798
    GVX_BADSECTOR,
799
    GVX_BADWALL,
800
    GVX_BADINDEX,
4707 terminx 801
};
4631 terminx 802
 
4895 terminx 803
static const char *gvxerrs[] = {
804
    "Gv_GetVarX(): invalid gamevar ID",
805
    "Gv_GetVarX(): invalid player ID",
806
    "Gv_GetVarX(): invalid sprite ID",
807
    "Gv_GetVarX(): invalid sector ID",
808
    "Gv_GetVarX(): invalid wall ID",
809
    "Gv_GetVarX(): invalid array index",
4631 terminx 810
};
811
 
812
int32_t __fastcall Gv_GetVarX(int32_t id)
1189 terminx 813
{
1440 terminx 814
    if (id == g_iThisActorID)
815
        return vm.g_i;
816
 
1189 terminx 817
    if (id == MAXGAMEVARS)
4895 terminx 818
        return *insptr++;
1189 terminx 819
 
5069 terminx 820
    int const negateResult = !!(id & (MAXGAMEVARS << 1));
821
    int rv = -1;
4895 terminx 822
 
4680 terminx 823
    if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && negateResult == 0))
4631 terminx 824
        goto nastyhacks;
5069 terminx 825
    else
826
    {
827
        id &= MAXGAMEVARS-1;
4631 terminx 828
 
5069 terminx 829
        int const f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
4631 terminx 830
 
5069 terminx 831
        if (!f) rv = aGameVars[id].val.lValue;
832
        else if (f == GAMEVAR_PERPLAYER)
833
        {
834
            if (EDUKE32_PREDICT_FALSE((unsigned) vm.g_p >= MAXPLAYERS))
835
                goto perr;
836
            rv = aGameVars[id].val.plValues[vm.g_p];
837
        }
838
        else if (f == GAMEVAR_PERACTOR)
839
            rv = aGameVars[id].val.plValues[vm.g_i];
840
        else switch (f)
841
        {
842
            case GAMEVAR_INTPTR:
843
                rv = (*((int32_t *) aGameVars[id].val.lValue)); break;
844
            case GAMEVAR_SHORTPTR:
845
                rv = (*((int16_t *) aGameVars[id].val.lValue)); break;
846
            case GAMEVAR_CHARPTR:
847
                rv = (*((uint8_t *) aGameVars[id].val.lValue)); break;
848
        }
4895 terminx 849
 
5069 terminx 850
        return (rv ^ -negateResult) + negateResult;
4631 terminx 851
    }
1189 terminx 852
 
4631 terminx 853
nastyhacks:
4895 terminx 854
    if (id & (MAXGAMEVARS << 2))  // array
4631 terminx 855
    {
5069 terminx 856
        int const index = Gv_GetVarX(*insptr++);
1189 terminx 857
 
4895 terminx 858
        id &= (MAXGAMEVARS - 1);  // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
3274 hendricks2 859
 
5069 terminx 860
        int const siz = (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) ?
861
            Gv_GetVarX(aGameArrays[id].size) : aGameArrays[id].size;
1857 terminx 862
 
5069 terminx 863
        if (EDUKE32_PREDICT_FALSE((unsigned)index >= (unsigned)siz))
4631 terminx 864
        {
4839 helixhorne 865
            CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[id].szLabel, index);
4631 terminx 866
            return -1;
867
        }
1189 terminx 868
 
4631 terminx 869
        switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
870
        {
5069 terminx 871
            case 0: rv = (aGameArrays[id].plValues)[index]; break;
872
            case GAMEARRAY_OFINT: rv = ((int32_t *)aGameArrays[id].plValues)[index]; break;
873
            case GAMEARRAY_OFSHORT: rv = ((int16_t *)aGameArrays[id].plValues)[index]; break;
874
            case GAMEARRAY_OFCHAR: rv = ((uint8_t *)aGameArrays[id].plValues)[index]; break;
4631 terminx 875
        }
876
    }
5069 terminx 877
    else if (id & (MAXGAMEVARS << 3))  // struct shortcut vars
4631 terminx 878
    {
5069 terminx 879
        int indexvar = *insptr;
880
        int index = Gv_GetVarX(*insptr++);
1204 terminx 881
 
5069 terminx 882
        switch ((id & (MAXGAMEVARS - 1)) - g_iSpriteVarID)
4631 terminx 883
        {
5069 terminx 884
            case 0:  // if (id == g_iSpriteVarID)
885
            {
886
                int const label = *insptr++;
1215 terminx 887
 
5069 terminx 888
                /*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/
889
                indexvar = (EDUKE32_PREDICT_FALSE(ActorLabels[label].flags & LABEL_HASPARM2)) ?
890
                            Gv_GetVarX(*insptr++) : 0;
2016 terminx 891
 
5069 terminx 892
                if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSPRITES))
893
                {
894
                    id = index;
895
                    CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], id);
896
                    return -1;
897
                }
898
 
899
                rv = VM_AccessSpriteX(index, label, indexvar);
900
                break;
901
            }
902
 
903
            case 3:  // else if (id == g_iPlayerVarID)
4631 terminx 904
            {
5069 terminx 905
                int const label = *insptr++;
906
 
907
                if (indexvar == g_iThisActorID)
908
                    index = vm.g_p;
909
 
910
                indexvar = (EDUKE32_PREDICT_FALSE(PlayerLabels[label].flags & LABEL_HASPARM2)) ?
911
                    Gv_GetVarX(*insptr++) : 0;
912
 
913
                if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXPLAYERS))
914
                {
915
                    id = index;
916
                    CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
917
                    return -1;
918
                }
919
 
920
                rv = VM_AccessPlayerX(index, label, indexvar);
921
                break;
4631 terminx 922
            }
1204 terminx 923
 
5069 terminx 924
            case 4:  // else if (id == g_iActorVarID)
925
                rv = Gv_GetVar(*insptr++, index, vm.g_p);
926
                break;
1204 terminx 927
 
5069 terminx 928
            case 1:  // else if (id == g_iSectorVarID)
929
                if (indexvar == g_iThisActorID)
930
                    index = sprite[vm.g_i].sectnum;
2016 terminx 931
 
5069 terminx 932
                if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSECTORS))
933
                {
934
                    id = index;
935
                    insptr++;
936
                    CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSECTOR], id);
937
                    return -1;
938
                }
939
                rv = VM_AccessSectorX(index, *insptr++);
940
                break;
4631 terminx 941
 
5069 terminx 942
            case 2:  // else if (id == g_iWallVarID)
943
                if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXWALLS))
944
                {
945
                    id = index;
946
                    insptr++;
947
                    CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADWALL], id);
948
                    return -1;
949
                }
950
                rv = VM_AccessWallX(index, *insptr++);
951
                break;
952
 
953
            default: EDUKE32_UNREACHABLE_SECTION(return -1);
1189 terminx 954
        }
4631 terminx 955
    }
1857 terminx 956
 
5069 terminx 957
    return (rv ^ -negateResult) + negateResult;
958
 
959
perr:
960
    id = vm.g_p;
961
    CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
962
    return -1;
1189 terminx 963
}
502 terminx 964
 
5069 terminx 965
void __fastcall Gv_SetVarX(int32_t const id, int32_t const lValue)
1189 terminx 966
{
5069 terminx 967
    int const f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
4895 terminx 968
 
969
    if (!f) aGameVars[id].val.lValue = lValue;
970
    else if (f == GAMEVAR_PERPLAYER)
782 terminx 971
    {
4895 terminx 972
        if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p >= MAXPLAYERS)) goto badindex;
973
        aGameVars[id].val.plValues[vm.g_p] = lValue;
782 terminx 974
    }
4895 terminx 975
    else if (f == GAMEVAR_PERACTOR)
976
    {
977
        if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i >= MAXSPRITES)) goto badindex;
978
        aGameVars[id].val.plValues[vm.g_i] = lValue;
979
    }
5069 terminx 980
    else switch (f)
4895 terminx 981
    {
5069 terminx 982
        case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) = (int32_t)lValue; break;
983
        case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) = (int16_t)lValue; break;
984
        case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) = (uint8_t)lValue; break;
4895 terminx 985
    }
1657 terminx 986
 
4895 terminx 987
    return;
988
 
1820 terminx 989
badindex:
3000 helixhorne 990
    CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s\n",
1820 terminx 991
               aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? vm.g_i : vm.g_p,
992
               aGameVars[id].szLabel);
398 terminx 993
}
994
 
5069 terminx 995
int32_t Gv_GetVarByLabel(const char *szGameLabel, int32_t const lDefault, int32_t const iActor, int32_t const iPlayer)
398 terminx 996
{
5069 terminx 997
    int32_t const i = hash_find(&h_gamevars,szGameLabel);
4680 terminx 998
    return EDUKE32_PREDICT_FALSE(i < 0) ? lDefault : Gv_GetVar(i, iActor, iPlayer);
398 terminx 999
}
1000
 
1143 terminx 1001
static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel)
398 terminx 1002
{
5069 terminx 1003
    int32_t const i = hash_find(&h_gamevars,szGameLabel);
715 terminx 1004
 
4680 terminx 1005
    if (EDUKE32_PREDICT_FALSE(i < 0))
1179 terminx 1006
        return NULL;
1024 terminx 1007
 
1143 terminx 1008
    if (aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_PERPLAYER))
782 terminx 1009
    {
4680 terminx 1010
        if (EDUKE32_PREDICT_FALSE(!aGameVars[i].val.plValues))
3000 helixhorne 1011
            CON_ERRPRINTF("Gv_GetVarDataPtr(): INTERNAL ERROR: NULL array !!!\n");
1189 terminx 1012
        return aGameVars[i].val.plValues;
782 terminx 1013
    }
1179 terminx 1014
 
1189 terminx 1015
    return &(aGameVars[i].val.lValue);
398 terminx 1016
}
3789 helixhorne 1017
#endif  // !defined LUNATIC
398 terminx 1018
 
1143 terminx 1019
void Gv_ResetSystemDefaults(void)
398 terminx 1020
{
782 terminx 1021
    // call many times...
3459 helixhorne 1022
#if !defined LUNATIC
782 terminx 1023
    char aszBuf[64];
398 terminx 1024
 
782 terminx 1025
    //AddLog("ResetWeaponDefaults");
398 terminx 1026
 
5069 terminx 1027
    for (int i = 0; i < MAX_WEAPONS; ++i)
782 terminx 1028
    {
5069 terminx 1029
        for (int j = 0; j < MAXPLAYERS; ++j)
782 terminx 1030
        {
5069 terminx 1031
            Bsprintf(aszBuf, "WEAPON%d_CLIP", i);
1032
            aplWeaponClip[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1033
            Bsprintf(aszBuf, "WEAPON%d_RELOAD", i);
1034
            aplWeaponReload[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1035
            Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", i);
1036
            aplWeaponFireDelay[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1037
            Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", i);
1038
            aplWeaponTotalTime[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1039
            Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", i);
1040
            aplWeaponHoldDelay[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1041
            Bsprintf(aszBuf, "WEAPON%d_FLAGS", i);
1042
            aplWeaponFlags[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1043
            Bsprintf(aszBuf, "WEAPON%d_SHOOTS", i);
1044
            aplWeaponShoots[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
2268 helixhorne 1045
            if ((unsigned)aplWeaponShoots[i][j] >= MAXTILES)
1046
                aplWeaponShoots[i][j] = 0;
5069 terminx 1047
            Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", i);
1048
            aplWeaponSpawnTime[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1049
            Bsprintf(aszBuf, "WEAPON%d_SPAWN", i);
1050
            aplWeaponSpawn[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1051
            Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", i);
1052
            aplWeaponShotsPerBurst[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1053
            Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", i);
1054
            aplWeaponWorksLike[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1055
            Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", i);
1056
            aplWeaponInitialSound[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1057
            Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", i);
1058
            aplWeaponFireSound[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1059
            Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", i);
1060
            aplWeaponSound2Time[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1061
            Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", i);
1062
            aplWeaponSound2Sound[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1063
            Bsprintf(aszBuf, "WEAPON%d_RELOADSOUND1", i);
1064
            aplWeaponReloadSound1[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1065
            Bsprintf(aszBuf, "WEAPON%d_RELOADSOUND2", i);
1066
            aplWeaponReloadSound2[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1067
            Bsprintf(aszBuf, "WEAPON%d_SELECTSOUND", i);
1068
            aplWeaponSelectSound[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
1069
            Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", i);
1070
            aplWeaponFlashColor[i][j] = Gv_GetVarByLabel(aszBuf, 0, -1, j);
782 terminx 1071
        }
1072
    }
3415 helixhorne 1073
 
5069 terminx 1074
    g_iReturnVarID = Gv_GetVarIndex("RETURN");
1075
    g_iWeaponVarID = Gv_GetVarIndex("WEAPON");
1076
    g_iWorksLikeVarID = Gv_GetVarIndex("WORKSLIKE");
1077
    g_iZRangeVarID = Gv_GetVarIndex("ZRANGE");
1078
    g_iAngRangeVarID = Gv_GetVarIndex("ANGRANGE");
1079
    g_iAimAngleVarID = Gv_GetVarIndex("AUTOAIMANGLE");
1080
    g_iLoTagID = Gv_GetVarIndex("LOTAG");
1081
    g_iHiTagID = Gv_GetVarIndex("HITAG");
1082
    g_iTextureID = Gv_GetVarIndex("TEXTURE");
1083
    g_iThisActorID = Gv_GetVarIndex("THISACTOR");
398 terminx 1084
 
5069 terminx 1085
    g_iSpriteVarID = Gv_GetVarIndex("sprite");
1086
    g_iSectorVarID = Gv_GetVarIndex("sector");
1087
    g_iWallVarID = Gv_GetVarIndex("wall");
1088
    g_iPlayerVarID = Gv_GetVarIndex("player");
1089
    g_iActorVarID = Gv_GetVarIndex("actorvar");
3343 helixhorne 1090
#endif
1204 terminx 1091
 
4937 helixhorne 1092
    for (int i = 0; i <= MAXTILES - 1; i++)
4895 terminx 1093
        Bmemcpy(&ProjectileData[i], &g_tile[i].defproj, sizeof(projectile_t));
1094
 
4710 helixhorne 1095
#ifndef LUNATIC
4937 helixhorne 1096
    int i;
1097
 
4631 terminx 1098
    // hackhackhackhackhack
4895 terminx 1099
    if (i = hash_find(&h_arrays, "tilesizx"), i >= 0)
4631 terminx 1100
    {
4895 terminx 1101
        for (int j = 0; j < MAXTILES; j++)
4631 terminx 1102
            aGameArrays[i].plValues[j] = tilesiz[j].x;
1103
    }
1104
 
4895 terminx 1105
    if (i = hash_find(&h_arrays, "tilesizy"), i >= 0)
4631 terminx 1106
    {
4895 terminx 1107
        for (int j = 0; j < MAXTILES; j++)
4631 terminx 1108
            aGameArrays[i].plValues[j] = tilesiz[j].y;
1109
    }
4710 helixhorne 1110
#endif
4631 terminx 1111
 
782 terminx 1112
    //AddLog("EOF:ResetWeaponDefaults");
398 terminx 1113
}
1114
 
3848 helixhorne 1115
// Will set members that were overridden at CON translation time to 1.
1116
// For example, if
1117
//   gamevar WEAPON1_SHOOTS 2200 GAMEVAR_PERPLAYER
1118
// was specified at file scope, g_weaponOverridden[1].Shoots will be 1.
1119
weapondata_t g_weaponOverridden[MAX_WEAPONS];
1120
 
3327 helixhorne 1121
static weapondata_t weapondefaults[MAX_WEAPONS] = {
1122
    /*
1123
        WorksLike, Clip, Reload, FireDelay, TotalTime, HoldDelay,
1124
        Flags,
1125
        Shoots, SpawnTime, Spawn, ShotsPerBurst, InitialSound, FireSound, Sound2Time, Sound2Sound,
1126
        ReloadSound1, ReloadSound2, SelectSound, FlashColor
1127
    */
398 terminx 1128
 
3327 helixhorne 1129
    {
1130
        KNEE_WEAPON, 0, 0, 7, 14, 0,
1131
        WEAPON_NOVISIBLE | WEAPON_RANDOMRESTART | WEAPON_AUTOMATIC,
1132
        KNEE__STATIC, 0, 0, 0, 0, 0, 0,
3834 hendricks2 1133
        0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
3327 helixhorne 1134
    },
398 terminx 1135
 
3327 helixhorne 1136
    {
1137
        PISTOL_WEAPON, /*NAM?20:*/12, /*NAM?50:*/27, 2, 5, 0,
3375 helixhorne 1138
        /*(NAM?WEAPON_HOLSTER_CLEARS_CLIP:0) |*/ WEAPON_RELOAD_TIMING,
3834 hendricks2 1139
        SHOTSPARK1__STATIC, 2, SHELL__STATIC, 0, 0, PISTOL_FIRE__STATIC, 0, 0,
1140
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, INSERT_CLIP__STATIC, 255+(95<<8)
3327 helixhorne 1141
    },
398 terminx 1142
 
3327 helixhorne 1143
    {
1144
        SHOTGUN_WEAPON, 0, 13, 4, 30, 0,
1145
        WEAPON_CHECKATRELOAD,
3834 hendricks2 1146
        SHOTGUN__STATIC, 24, SHOTGUNSHELL__STATIC, 7, 0, SHOTGUN_FIRE__STATIC, 15, SHOTGUN_COCK__STATIC,
1147
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SHOTGUN_COCK__STATIC, 255+(95<<8)
3327 helixhorne 1148
    },
1315 terminx 1149
 
3327 helixhorne 1150
    {
1151
        CHAINGUN_WEAPON, 0, 0, 3, 12, 3,
1152
        WEAPON_AUTOMATIC | WEAPON_FIREEVERYTHIRD | WEAPON_AMMOPERSHOT | WEAPON_SPAWNTYPE3 | WEAPON_RESET,
3834 hendricks2 1153
        CHAINGUN__STATIC, 1, SHELL__STATIC, 0, 0, CHAINGUN_FIRE__STATIC, 0, 0,
1154
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
3327 helixhorne 1155
    },
398 terminx 1156
 
3327 helixhorne 1157
    {
1158
        RPG_WEAPON, 0, 0, 4, 20, 0,
1159
        0,
1160
        RPG__STATIC, 0, 0, 0, 0, 0, 0, 0,
3834 hendricks2 1161
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
3327 helixhorne 1162
    },
398 terminx 1163
 
3327 helixhorne 1164
    {
1165
        HANDBOMB_WEAPON, 0, 30, 6, 19, 12,
1166
        WEAPON_THROWIT,
1167
        HEAVYHBOMB__STATIC, 0, 0, 0, 0, 0, 0,
3834 hendricks2 1168
        0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
3327 helixhorne 1169
    },
398 terminx 1170
 
3327 helixhorne 1171
    {
1172
        SHRINKER_WEAPON, 0, 0, 10, /*NAM?30:*/12, 0,
1173
        WEAPON_GLOWS,
3834 hendricks2 1174
        SHRINKER__STATIC, 0, 0, 0, SHRINKER_FIRE__STATIC, 0, 0, 0,
1175
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 128+(255<<8)+(128<<16)
3327 helixhorne 1176
    },
398 terminx 1177
 
3327 helixhorne 1178
    {
1179
        DEVISTATOR_WEAPON, 0, 0, 3, 6, 5,
1180
        WEAPON_FIREEVERYOTHER | WEAPON_AMMOPERSHOT,
3834 hendricks2 1181
        RPG__STATIC, 0, 0, 2, CAT_FIRE__STATIC, 0, 0, 0,
1182
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
3327 helixhorne 1183
    },
398 terminx 1184
 
3327 helixhorne 1185
    {
1186
        TRIPBOMB_WEAPON, 0, 16, 3, 16, 7,
1187
        WEAPON_NOVISIBLE | WEAPON_STANDSTILL | WEAPON_CHECKATRELOAD,
1188
        HANDHOLDINGLASER__STATIC, 0, 0, 0, 0, 0, 0,
3834 hendricks2 1189
        0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
3327 helixhorne 1190
    },
398 terminx 1191
 
3327 helixhorne 1192
    {
1193
        FREEZE_WEAPON, 0, 0, 3, 5, 0,
1194
        WEAPON_RESET,
3834 hendricks2 1195
        FREEZEBLAST__STATIC, 0, 0, 0, CAT_FIRE__STATIC, CAT_FIRE__STATIC, 0, 0,
1196
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 128+(128<<8)+(255<<16)
3327 helixhorne 1197
    },
398 terminx 1198
 
3327 helixhorne 1199
    {
1200
        HANDREMOTE_WEAPON, 0, 10, 2, 10, 0,
1201
        WEAPON_BOMB_TRIGGER | WEAPON_NOVISIBLE,
1202
        0, 0, 0, 0, 0, 0, 0,
3834 hendricks2 1203
        0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
3327 helixhorne 1204
    },
398 terminx 1205
 
3327 helixhorne 1206
    {
1207
        GROW_WEAPON, 0, 0, 3, /*NAM?30:*/5, 0,
1208
        WEAPON_GLOWS,
3834 hendricks2 1209
        GROWSPARK__STATIC, /*NAM?2:*/0, /*NAM?SHELL:*/0, 0, 0, /*NAM?0:*/EXPANDERSHOOT__STATIC, 0, 0,
1210
        EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
3327 helixhorne 1211
    },
1212
};
398 terminx 1213
 
3327 helixhorne 1214
// KEEPINSYNC with what is contained above
1215
// XXX: ugly
5069 terminx 1216
static int32_t G_StaticToDynamicTile(int32_t const tile)
3327 helixhorne 1217
{
1218
    switch (tile)
1219
    {
1220
    case CHAINGUN__STATIC: return CHAINGUN;
1221
    case FREEZEBLAST__STATIC: return FREEZEBLAST;
1222
    case GROWSPARK__STATIC: return GROWSPARK;
1223
    case HANDHOLDINGLASER__STATIC: return HANDHOLDINGLASER;
1224
    case HEAVYHBOMB__STATIC: return HEAVYHBOMB;
1225
    case KNEE__STATIC: return KNEE;
1226
    case RPG__STATIC: return RPG;
1227
    case SHELL__STATIC: return SHELL;
1228
    case SHOTGUNSHELL__STATIC: return SHOTGUNSHELL;
1229
    case SHOTGUN__STATIC: return SHOTGUN;
1230
    case SHOTSPARK1__STATIC: return SHOTSPARK1;
1231
    case SHRINKER__STATIC: return SHRINKER;
1232
    default: return tile;
1233
    }
1234
}
4895 terminx 1235
 
5069 terminx 1236
static int32_t G_StaticToDynamicSound(int32_t const sound)
3834 hendricks2 1237
{
1238
    switch (sound)
1239
    {
1240
    case CAT_FIRE__STATIC: return CAT_FIRE;
1241
    case CHAINGUN_FIRE__STATIC: return CHAINGUN_FIRE;
1242
    case EJECT_CLIP__STATIC: return EJECT_CLIP;
1243
    case EXPANDERSHOOT__STATIC: return EXPANDERSHOOT;
1244
    case INSERT_CLIP__STATIC: return INSERT_CLIP;
1245
    case PISTOL_FIRE__STATIC: return PISTOL_FIRE;
1246
    case SELECT_WEAPON__STATIC: return SELECT_WEAPON;
1247
    case SHOTGUN_FIRE__STATIC: return SHOTGUN_FIRE;
1248
    case SHOTGUN_COCK__STATIC: return SHOTGUN_COCK;
1249
    case SHRINKER_FIRE__STATIC: return SHRINKER_FIRE;
1250
    default: return sound;
1251
    }
1252
}
398 terminx 1253
 
3848 helixhorne 1254
// Initialize WEAPONx_* gamevars. Since for Lunatic, they reside on the C side,
1255
// they're set directly. In C-CON, a new CON variable is defined together with
1256
// its initial value.
3328 helixhorne 1257
#ifdef LUNATIC
1258
# define ADDWEAPONVAR(Weapidx, Membname) do { \
1259
    int32_t j; \
1260
    for (j=0; j<MAXPLAYERS; j++) \
1261
        g_playerWeapon[j][Weapidx].Membname = weapondefaults[Weapidx].Membname; \
1262
} while (0)
1263
#else
1264
# define ADDWEAPONVAR(Weapidx, Membname) do { \
3327 helixhorne 1265
    Bsprintf(aszBuf, "WEAPON%d_" #Membname, Weapidx); \
1266
    Bstrupr(aszBuf); \
1267
    Gv_NewVar(aszBuf, weapondefaults[Weapidx].Membname, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM); \
1268
} while (0)
3328 helixhorne 1269
#endif
398 terminx 1270
 
3848 helixhorne 1271
// After CON translation, get not-overridden members from weapondefaults[] back
1272
// into the live arrays! (That is, g_playerWeapon[][] for Lunatic, WEAPONx_*
1273
// gamevars on the CON side in C-CON.)
1274
#ifdef LUNATIC
1275
# define POSTADDWEAPONVAR(Weapidx, Membname) ADDWEAPONVAR(Weapidx, Membname)
1276
#else
1277
// NYI
1278
# define POSTADDWEAPONVAR(Weapidx, Membname) do {} while (0)
1279
#endif
1280
 
1281
// Finish a default weapon member after CON translation. If it was not
1282
// overridden from CON itself (see example at g_weaponOverridden[]), we set
1283
// both the weapondefaults[] entry (probably dead by now) and the live value.
1284
#define FINISH_WEAPON_DEFAULT_X(What, i, Membname) do {  \
1285
    if (!g_weaponOverridden[i].Membname) \
1286
    { \
1287
        weapondefaults[i].Membname = G_StaticToDynamic##What(weapondefaults[i].Membname); \
1288
        POSTADDWEAPONVAR(i, Membname); \
1289
    } \
1290
} while (0)
1291
 
1292
#define FINISH_WEAPON_DEFAULT_TILE(i, Membname) FINISH_WEAPON_DEFAULT_X(Tile, i, Membname)
1293
#define FINISH_WEAPON_DEFAULT_SOUND(i, Membname) FINISH_WEAPON_DEFAULT_X(Sound, i, Membname)
1294
 
1295
// Process the dynamic {tile,sound} mappings after CON has been translated.
1296
// We cannot do this before, because the dynamic maps are not yet set up then.
1297
void Gv_FinalizeWeaponDefaults(void)
1298
{
5069 terminx 1299
    for (int i=0; i<MAX_WEAPONS; i++)
3848 helixhorne 1300
    {
1301
        FINISH_WEAPON_DEFAULT_TILE(i, Shoots);
1302
        FINISH_WEAPON_DEFAULT_TILE(i, Spawn);
1303
 
1304
        FINISH_WEAPON_DEFAULT_SOUND(i, InitialSound);
1305
        FINISH_WEAPON_DEFAULT_SOUND(i, FireSound);
1306
        FINISH_WEAPON_DEFAULT_SOUND(i, ReloadSound1);
1307
        FINISH_WEAPON_DEFAULT_SOUND(i, Sound2Sound);
1308
        FINISH_WEAPON_DEFAULT_SOUND(i, ReloadSound2);
1309
        FINISH_WEAPON_DEFAULT_SOUND(i, SelectSound);
1310
    }
1311
}
1312
#undef FINISH_WEAPON_DEFAULT_SOUND
1313
#undef FINISH_WEAPON_DEFAULT_TILE
1314
#undef FINISH_WEAPON_DEFAULT_X
1315
#undef POSTADDWEAPONVAR
1316
 
3961 helixhorne 1317
#if !defined LUNATIC
1318
static int32_t lastvisinc;
1319
#endif
1320
 
3327 helixhorne 1321
static void Gv_AddSystemVars(void)
1322
{
1323
    // only call ONCE
3328 helixhorne 1324
#if !defined LUNATIC
3327 helixhorne 1325
    char aszBuf[64];
3328 helixhorne 1326
#endif
3327 helixhorne 1327
 
1328
    if (NAM)
1329
    {
1330
        weapondefaults[PISTOL_WEAPON].Clip = 20;
1331
        weapondefaults[PISTOL_WEAPON].Reload = 50;
3367 hendricks2 1332
        weapondefaults[PISTOL_WEAPON].Flags |= WEAPON_HOLSTER_CLEARS_CLIP;
3327 helixhorne 1333
 
1334
        weapondefaults[SHRINKER_WEAPON].TotalTime = 30;
1335
 
1336
        weapondefaults[GROW_WEAPON].TotalTime = 30;
1337
        weapondefaults[GROW_WEAPON].SpawnTime = 2;
1338
        weapondefaults[GROW_WEAPON].Spawn = SHELL;
1339
        weapondefaults[GROW_WEAPON].FireSound = 0;
1340
    }
1341
 
5069 terminx 1342
    for (int i=0; i<MAX_WEAPONS; i++)
3327 helixhorne 1343
    {
1344
        ADDWEAPONVAR(i, WorksLike);
1345
        ADDWEAPONVAR(i, Clip);
1346
        ADDWEAPONVAR(i, Reload);
1347
        ADDWEAPONVAR(i, FireDelay);
1348
        ADDWEAPONVAR(i, TotalTime);
1349
        ADDWEAPONVAR(i, HoldDelay);
1350
        ADDWEAPONVAR(i, Flags);
1351
        ADDWEAPONVAR(i, Shoots);
1352
        ADDWEAPONVAR(i, SpawnTime);
1353
        ADDWEAPONVAR(i, Spawn);
1354
        ADDWEAPONVAR(i, ShotsPerBurst);
1355
        ADDWEAPONVAR(i, InitialSound);
1356
        ADDWEAPONVAR(i, FireSound);
1357
        ADDWEAPONVAR(i, Sound2Time);
1358
        ADDWEAPONVAR(i, Sound2Sound);
1359
        ADDWEAPONVAR(i, ReloadSound1);
1360
        ADDWEAPONVAR(i, ReloadSound2);
1361
        ADDWEAPONVAR(i, SelectSound);
1362
        ADDWEAPONVAR(i, FlashColor);
1363
    }
3409 helixhorne 1364
#ifdef LUNATIC
5069 terminx 1365
    for (int i=0; i<MAXPLAYERS; i++)
3409 helixhorne 1366
    {
1367
        DukePlayer_t *ps = g_player[i].ps;
1368
 
1369
        ps->pipebombControl = NAM ? PIPEBOMB_TIMER : PIPEBOMB_REMOTE;
1370
        ps->pipebombLifetime = NAM_GRENADE_LIFETIME;
1371
        ps->pipebombLifetimeVar = NAM_GRENADE_LIFETIME_VAR;
1372
 
1373
        ps->tripbombControl = TRIPBOMB_TRIPWIRE;
1374
        ps->tripbombLifetime = NAM_GRENADE_LIFETIME;
1375
        ps->tripbombLifetimeVar = NAM_GRENADE_LIFETIME_VAR;
1376
    }
1377
#else
1179 terminx 1378
    Gv_NewVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1379
    Gv_NewVar("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
398 terminx 1380
 
1179 terminx 1381
    Gv_NewVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1382
    Gv_NewVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
398 terminx 1383
 
1179 terminx 1384
    Gv_NewVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1385
    Gv_NewVar("PIPEBOMB_CONTROL", NAM?PIPEBOMB_TIMER:PIPEBOMB_REMOTE, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
398 terminx 1386
 
1179 terminx 1387
    Gv_NewVar("RESPAWN_MONSTERS", (intptr_t)&ud.respawn_monsters,GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1388
    Gv_NewVar("RESPAWN_ITEMS",(intptr_t)&ud.respawn_items, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1389
    Gv_NewVar("RESPAWN_INVENTORY",(intptr_t)&ud.respawn_inventory, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1390
    Gv_NewVar("MONSTERS_OFF",(intptr_t)&ud.monsters_off, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1391
    Gv_NewVar("MARKER",(intptr_t)&ud.marker, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1392
    Gv_NewVar("FFIRE",(intptr_t)&ud.ffire, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1393
    Gv_NewVar("LEVEL",(intptr_t)&ud.level_number, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1394
    Gv_NewVar("VOLUME",(intptr_t)&ud.volume_number, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
398 terminx 1395
 
1179 terminx 1396
    Gv_NewVar("COOP",(intptr_t)&ud.coop, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1397
    Gv_NewVar("MULTIMODE",(intptr_t)&ud.multimode, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
398 terminx 1398
 
1179 terminx 1399
    Gv_NewVar("WEAPON", 0, GAMEVAR_PERPLAYER | GAMEVAR_READONLY | GAMEVAR_SYSTEM);
1400
    Gv_NewVar("WORKSLIKE", 0, GAMEVAR_PERPLAYER | GAMEVAR_READONLY | GAMEVAR_SYSTEM);
1401
    Gv_NewVar("RETURN", 0, GAMEVAR_SYSTEM);
1402
    Gv_NewVar("ZRANGE", 4, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1403
    Gv_NewVar("ANGRANGE", 18, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1404
    Gv_NewVar("AUTOAIMANGLE", 0, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
1405
    Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM);
1406
    Gv_NewVar("HITAG", 0, GAMEVAR_SYSTEM);
1407
    Gv_NewVar("TEXTURE", 0, GAMEVAR_SYSTEM);
1408
    Gv_NewVar("THISACTOR", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM);
1204 terminx 1409
 
1410
    // special vars for struct access
1221 terminx 1411
    Gv_NewVar("sprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
1412
    Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
1413
    Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
1414
    Gv_NewVar("player", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
1415
    Gv_NewVar("actorvar", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
1204 terminx 1416
 
1857 terminx 1417
    Gv_NewVar("myconnectindex", (intptr_t)&myconnectindex, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1418
    Gv_NewVar("screenpeek", (intptr_t)&screenpeek, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
3408 helixhorne 1419
    Gv_NewVar("currentweapon",(intptr_t)&hudweap.cur, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1420
    Gv_NewVar("gs",(intptr_t)&hudweap.shade, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1421
    Gv_NewVar("looking_arc",(intptr_t)&hudweap.lookhoriz, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1422
    Gv_NewVar("gun_pos",(intptr_t)&hudweap.gunposy, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1423
    Gv_NewVar("weapon_xoffset",(intptr_t)&hudweap.gunposx, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1424
    Gv_NewVar("weaponcount",(intptr_t)&hudweap.count, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1425
    Gv_NewVar("looking_angSR1",(intptr_t)&hudweap.lookhalfang, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
1857 terminx 1426
    Gv_NewVar("xdim",(intptr_t)&xdim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1427
    Gv_NewVar("ydim",(intptr_t)&ydim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1428
    Gv_NewVar("windowx1",(intptr_t)&windowx1, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1429
    Gv_NewVar("windowx2",(intptr_t)&windowx2, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1430
    Gv_NewVar("windowy1",(intptr_t)&windowy1, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1431
    Gv_NewVar("windowy2",(intptr_t)&windowy2, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1432
    Gv_NewVar("totalclock",(intptr_t)&totalclock, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
1433
    Gv_NewVar("lastvisinc",(intptr_t)&lastvisinc, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1179 terminx 1434
    Gv_NewVar("numsectors",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
897 hnt_ts 1435
 
1179 terminx 1436
    Gv_NewVar("current_menu",(intptr_t)&g_currentMenu, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1437
    Gv_NewVar("numplayers",(intptr_t)&numplayers, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1857 terminx 1438
    Gv_NewVar("viewingrange",(intptr_t)&viewingrange, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1439
    Gv_NewVar("yxaspect",(intptr_t)&yxaspect, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1179 terminx 1440
    Gv_NewVar("gravitationalconstant",(intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1441
    Gv_NewVar("gametype_flags",(intptr_t)&GametypeFlags[ud.coop], GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1857 terminx 1442
    Gv_NewVar("framerate",(intptr_t)&g_currentFrameRate, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1179 terminx 1443
    Gv_NewVar("CLIPMASK0", CLIPMASK0, GAMEVAR_SYSTEM|GAMEVAR_READONLY);
1444
    Gv_NewVar("CLIPMASK1", CLIPMASK1, GAMEVAR_SYSTEM|GAMEVAR_READONLY);
502 terminx 1445
 
3405 helixhorne 1446
    Gv_NewVar("camerax",(intptr_t)&ud.camerapos.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1447
    Gv_NewVar("cameray",(intptr_t)&ud.camerapos.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1448
    Gv_NewVar("cameraz",(intptr_t)&ud.camerapos.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1857 terminx 1449
    Gv_NewVar("cameraang",(intptr_t)&ud.cameraang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1450
    Gv_NewVar("camerahoriz",(intptr_t)&ud.camerahoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1451
    Gv_NewVar("camerasect",(intptr_t)&ud.camerasect, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1452
    Gv_NewVar("cameradist",(intptr_t)&g_cameraDistance, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1453
    Gv_NewVar("cameraclock",(intptr_t)&g_cameraClock, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
502 terminx 1454
 
1857 terminx 1455
    Gv_NewVar("myx",(intptr_t)&my.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1456
    Gv_NewVar("myy",(intptr_t)&my.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1457
    Gv_NewVar("myz",(intptr_t)&my.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1458
    Gv_NewVar("omyx",(intptr_t)&omy.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1459
    Gv_NewVar("omyy",(intptr_t)&omy.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1460
    Gv_NewVar("omyz",(intptr_t)&omy.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1461
    Gv_NewVar("myvelx",(intptr_t)&myvel.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1462
    Gv_NewVar("myvely",(intptr_t)&myvel.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
1463
    Gv_NewVar("myvelz",(intptr_t)&myvel.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
508 terminx 1464
 
1857 terminx 1465
    Gv_NewVar("myhoriz",(intptr_t)&myhoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1466
    Gv_NewVar("myhorizoff",(intptr_t)&myhorizoff, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1467
    Gv_NewVar("omyhoriz",(intptr_t)&omyhoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1468
    Gv_NewVar("omyhorizoff",(intptr_t)&omyhorizoff, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1469
    Gv_NewVar("myang",(intptr_t)&myang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1470
    Gv_NewVar("omyang",(intptr_t)&omyang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1471
    Gv_NewVar("mycursectnum",(intptr_t)&mycursectnum, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
1472
    Gv_NewVar("myjumpingcounter",(intptr_t)&myjumpingcounter, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
508 terminx 1473
 
1857 terminx 1474
    Gv_NewVar("myjumpingtoggle",(intptr_t)&myjumpingtoggle, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
1475
    Gv_NewVar("myonground",(intptr_t)&myonground, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
1476
    Gv_NewVar("myhardlanding",(intptr_t)&myhardlanding, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
1477
    Gv_NewVar("myreturntocenter",(intptr_t)&myreturntocenter, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
522 terminx 1478
 
1857 terminx 1479
    Gv_NewVar("display_mirror",(intptr_t)&display_mirror, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
1179 terminx 1480
    Gv_NewVar("randomseed",(intptr_t)&randomseed, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
770 hnt_ts 1481
 
1179 terminx 1482
    Gv_NewVar("NUMWALLS",(intptr_t)&numwalls, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
1483
    Gv_NewVar("NUMSECTORS",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
2484 helixhorne 1484
    Gv_NewVar("Numsprites",(intptr_t)&Numsprites, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
1068 terminx 1485
 
1857 terminx 1486
    Gv_NewVar("lastsavepos",(intptr_t)&g_lastSaveSlot, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
3343 helixhorne 1487
# ifdef USE_OPENGL
1857 terminx 1488
    Gv_NewVar("rendmode",(intptr_t)&rendmode, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
3343 helixhorne 1489
# else
1857 terminx 1490
    Gv_NewVar("rendmode", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM);
3343 helixhorne 1491
# endif
3274 hendricks2 1492
 
4191 helixhorne 1493
    // SYSTEM_GAMEARRAY
4631 terminx 1494
    Gv_NewArray("tilesizx", NULL, MAXTILES, GAMEARRAY_READONLY);
1495
    Gv_NewArray("tilesizy", NULL, MAXTILES, GAMEARRAY_READONLY);
3343 helixhorne 1496
#endif
398 terminx 1497
}
1498
 
3848 helixhorne 1499
#undef ADDWEAPONVAR
1500
 
1143 terminx 1501
void Gv_Init(void)
398 terminx 1502
{
4937 helixhorne 1503
#if !defined LUNATIC
4895 terminx 1504
    // already initialized
1505
    if (aGameVars[0].dwFlags)
1942 helixhorne 1506
        return;
1507
 
1143 terminx 1508
    Gv_Clear();
4937 helixhorne 1509
#else
1510
    static int32_t inited=0;
1511
    if (inited)
1512
        return;
1513
    inited = 1;
3846 helixhorne 1514
#endif
4937 helixhorne 1515
 
3846 helixhorne 1516
    // Set up weapon defaults, g_playerWeapon[][].
1143 terminx 1517
    Gv_AddSystemVars();
3846 helixhorne 1518
#if !defined LUNATIC
1143 terminx 1519
    Gv_InitWeaponPointers();
3459 helixhorne 1520
#endif
1143 terminx 1521
    Gv_ResetSystemDefaults();
398 terminx 1522
}
1523
 
3354 helixhorne 1524
#if !defined LUNATIC
1143 terminx 1525
void Gv_InitWeaponPointers(void)
398 terminx 1526
{
782 terminx 1527
    char aszBuf[64];
1528
    // called from game Init AND when level is loaded...
398 terminx 1529
 
1143 terminx 1530
    //AddLog("Gv_InitWeaponPointers");
398 terminx 1531
 
5069 terminx 1532
    for (int i=(MAX_WEAPONS-1); i>=0; i--)
782 terminx 1533
    {
1534
        Bsprintf(aszBuf,"WEAPON%d_CLIP",i);
1143 terminx 1535
        aplWeaponClip[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1536
        if (!aplWeaponClip[i])
1537
        {
1143 terminx 1538
            initprintf("ERROR: NULL weapon!  WTF?!\n");
4502 hendricks2 1539
            // Bexit(0);
1143 terminx 1540
            G_Shutdown();
782 terminx 1541
        }
1542
        Bsprintf(aszBuf,"WEAPON%d_RELOAD",i);
1143 terminx 1543
        aplWeaponReload[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1544
        Bsprintf(aszBuf,"WEAPON%d_FIREDELAY",i);
1143 terminx 1545
        aplWeaponFireDelay[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1546
        Bsprintf(aszBuf,"WEAPON%d_TOTALTIME",i);
1143 terminx 1547
        aplWeaponTotalTime[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1548
        Bsprintf(aszBuf,"WEAPON%d_HOLDDELAY",i);
1143 terminx 1549
        aplWeaponHoldDelay[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1550
        Bsprintf(aszBuf,"WEAPON%d_FLAGS",i);
1143 terminx 1551
        aplWeaponFlags[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1552
        Bsprintf(aszBuf,"WEAPON%d_SHOOTS",i);
1143 terminx 1553
        aplWeaponShoots[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1554
        Bsprintf(aszBuf,"WEAPON%d_SPAWNTIME",i);
1143 terminx 1555
        aplWeaponSpawnTime[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1556
        Bsprintf(aszBuf,"WEAPON%d_SPAWN",i);
1143 terminx 1557
        aplWeaponSpawn[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1558
        Bsprintf(aszBuf,"WEAPON%d_SHOTSPERBURST",i);
1143 terminx 1559
        aplWeaponShotsPerBurst[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1560
        Bsprintf(aszBuf,"WEAPON%d_WORKSLIKE",i);
1143 terminx 1561
        aplWeaponWorksLike[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1562
        Bsprintf(aszBuf,"WEAPON%d_INITIALSOUND",i);
1143 terminx 1563
        aplWeaponInitialSound[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1564
        Bsprintf(aszBuf,"WEAPON%d_FIRESOUND",i);
1143 terminx 1565
        aplWeaponFireSound[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1566
        Bsprintf(aszBuf,"WEAPON%d_SOUND2TIME",i);
1143 terminx 1567
        aplWeaponSound2Time[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1568
        Bsprintf(aszBuf,"WEAPON%d_SOUND2SOUND",i);
1143 terminx 1569
        aplWeaponSound2Sound[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1570
        Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND1",i);
1143 terminx 1571
        aplWeaponReloadSound1[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1572
        Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND2",i);
1143 terminx 1573
        aplWeaponReloadSound2[i]=Gv_GetVarDataPtr(aszBuf);
1574
        Bsprintf(aszBuf,"WEAPON%d_SELECTSOUND",i);
1575
        aplWeaponSelectSound[i]=Gv_GetVarDataPtr(aszBuf);
1315 terminx 1576
        Bsprintf(aszBuf,"WEAPON%d_FLASHCOLOR",i);
1577
        aplWeaponFlashColor[i]=Gv_GetVarDataPtr(aszBuf);
782 terminx 1578
    }
398 terminx 1579
}
1580
 
1143 terminx 1581
void Gv_RefreshPointers(void)
534 terminx 1582
{
1189 terminx 1583
    aGameVars[Gv_GetVarIndex("RESPAWN_MONSTERS")].val.lValue = (intptr_t)&ud.respawn_monsters;
1584
    aGameVars[Gv_GetVarIndex("RESPAWN_ITEMS")].val.lValue = (intptr_t)&ud.respawn_items;
1585
    aGameVars[Gv_GetVarIndex("RESPAWN_INVENTORY")].val.lValue = (intptr_t)&ud.respawn_inventory;
1586
    aGameVars[Gv_GetVarIndex("MONSTERS_OFF")].val.lValue = (intptr_t)&ud.monsters_off;
1587
    aGameVars[Gv_GetVarIndex("MARKER")].val.lValue = (intptr_t)&ud.marker;
1588
    aGameVars[Gv_GetVarIndex("FFIRE")].val.lValue = (intptr_t)&ud.ffire;
1589
    aGameVars[Gv_GetVarIndex("LEVEL")].val.lValue = (intptr_t)&ud.level_number;
1590
    aGameVars[Gv_GetVarIndex("VOLUME")].val.lValue = (intptr_t)&ud.volume_number;
534 terminx 1591
 
1189 terminx 1592
    aGameVars[Gv_GetVarIndex("COOP")].val.lValue = (intptr_t)&ud.coop;
1593
    aGameVars[Gv_GetVarIndex("MULTIMODE")].val.lValue = (intptr_t)&ud.multimode;
534 terminx 1594
 
1189 terminx 1595
    aGameVars[Gv_GetVarIndex("myconnectindex")].val.lValue = (intptr_t)&myconnectindex;
1596
    aGameVars[Gv_GetVarIndex("screenpeek")].val.lValue = (intptr_t)&screenpeek;
3408 helixhorne 1597
    aGameVars[Gv_GetVarIndex("currentweapon")].val.lValue = (intptr_t)&hudweap.cur;
1598
    aGameVars[Gv_GetVarIndex("gs")].val.lValue = (intptr_t)&hudweap.shade;
1599
    aGameVars[Gv_GetVarIndex("looking_arc")].val.lValue = (intptr_t)&hudweap.lookhoriz;
1600
    aGameVars[Gv_GetVarIndex("gun_pos")].val.lValue = (intptr_t)&hudweap.gunposy;
1601
    aGameVars[Gv_GetVarIndex("weapon_xoffset")].val.lValue = (intptr_t)&hudweap.gunposx;
1602
    aGameVars[Gv_GetVarIndex("weaponcount")].val.lValue = (intptr_t)&hudweap.count;
1603
    aGameVars[Gv_GetVarIndex("looking_angSR1")].val.lValue = (intptr_t)&hudweap.lookhalfang;
1189 terminx 1604
    aGameVars[Gv_GetVarIndex("xdim")].val.lValue = (intptr_t)&xdim;
1605
    aGameVars[Gv_GetVarIndex("ydim")].val.lValue = (intptr_t)&ydim;
1606
    aGameVars[Gv_GetVarIndex("windowx1")].val.lValue = (intptr_t)&windowx1;
1607
    aGameVars[Gv_GetVarIndex("windowx2")].val.lValue = (intptr_t)&windowx2;
1608
    aGameVars[Gv_GetVarIndex("windowy1")].val.lValue = (intptr_t)&windowy1;
1609
    aGameVars[Gv_GetVarIndex("windowy2")].val.lValue = (intptr_t)&windowy2;
1610
    aGameVars[Gv_GetVarIndex("totalclock")].val.lValue = (intptr_t)&totalclock;
1611
    aGameVars[Gv_GetVarIndex("lastvisinc")].val.lValue = (intptr_t)&lastvisinc;
1612
    aGameVars[Gv_GetVarIndex("numsectors")].val.lValue = (intptr_t)&numsectors;
1613
    aGameVars[Gv_GetVarIndex("numplayers")].val.lValue = (intptr_t)&numplayers;
1614
    aGameVars[Gv_GetVarIndex("current_menu")].val.lValue = (intptr_t)&g_currentMenu;
1615
    aGameVars[Gv_GetVarIndex("viewingrange")].val.lValue = (intptr_t)&viewingrange;
1616
    aGameVars[Gv_GetVarIndex("yxaspect")].val.lValue = (intptr_t)&yxaspect;
1617
    aGameVars[Gv_GetVarIndex("gravitationalconstant")].val.lValue = (intptr_t)&g_spriteGravity;
1618
    aGameVars[Gv_GetVarIndex("gametype_flags")].val.lValue = (intptr_t)&GametypeFlags[ud.coop];
1619
    aGameVars[Gv_GetVarIndex("framerate")].val.lValue = (intptr_t)&g_currentFrameRate;
534 terminx 1620
 
3405 helixhorne 1621
    aGameVars[Gv_GetVarIndex("camerax")].val.lValue = (intptr_t)&ud.camerapos.x;
1622
    aGameVars[Gv_GetVarIndex("cameray")].val.lValue = (intptr_t)&ud.camerapos.y;
1623
    aGameVars[Gv_GetVarIndex("cameraz")].val.lValue = (intptr_t)&ud.camerapos.z;
1189 terminx 1624
    aGameVars[Gv_GetVarIndex("cameraang")].val.lValue = (intptr_t)&ud.cameraang;
1625
    aGameVars[Gv_GetVarIndex("camerahoriz")].val.lValue = (intptr_t)&ud.camerahoriz;
1626
    aGameVars[Gv_GetVarIndex("camerasect")].val.lValue = (intptr_t)&ud.camerasect;
1627
    aGameVars[Gv_GetVarIndex("cameradist")].val.lValue = (intptr_t)&g_cameraDistance;
1628
    aGameVars[Gv_GetVarIndex("cameraclock")].val.lValue = (intptr_t)&g_cameraClock;
534 terminx 1629
 
1208 terminx 1630
    aGameVars[Gv_GetVarIndex("myx")].val.lValue = (intptr_t)&my.x;
1631
    aGameVars[Gv_GetVarIndex("myy")].val.lValue = (intptr_t)&my.y;
1632
    aGameVars[Gv_GetVarIndex("myz")].val.lValue = (intptr_t)&my.z;
1633
    aGameVars[Gv_GetVarIndex("omyx")].val.lValue = (intptr_t)&omy.x;
1634
    aGameVars[Gv_GetVarIndex("omyy")].val.lValue = (intptr_t)&omy.y;
1635
    aGameVars[Gv_GetVarIndex("omyz")].val.lValue = (intptr_t)&omy.z;
1636
    aGameVars[Gv_GetVarIndex("myvelx")].val.lValue = (intptr_t)&myvel.x;
1637
    aGameVars[Gv_GetVarIndex("myvely")].val.lValue = (intptr_t)&myvel.y;
1638
    aGameVars[Gv_GetVarIndex("myvelz")].val.lValue = (intptr_t)&myvel.z;
534 terminx 1639
 
1189 terminx 1640
    aGameVars[Gv_GetVarIndex("myhoriz")].val.lValue = (intptr_t)&myhoriz;
1641
    aGameVars[Gv_GetVarIndex("myhorizoff")].val.lValue = (intptr_t)&myhorizoff;
1642
    aGameVars[Gv_GetVarIndex("omyhoriz")].val.lValue = (intptr_t)&omyhoriz;
1643
    aGameVars[Gv_GetVarIndex("omyhorizoff")].val.lValue = (intptr_t)&omyhorizoff;
1644
    aGameVars[Gv_GetVarIndex("myang")].val.lValue = (intptr_t)&myang;
1645
    aGameVars[Gv_GetVarIndex("omyang")].val.lValue = (intptr_t)&omyang;
1646
    aGameVars[Gv_GetVarIndex("mycursectnum")].val.lValue = (intptr_t)&mycursectnum;
1647
    aGameVars[Gv_GetVarIndex("myjumpingcounter")].val.lValue = (intptr_t)&myjumpingcounter;
534 terminx 1648
 
1189 terminx 1649
    aGameVars[Gv_GetVarIndex("myjumpingtoggle")].val.lValue = (intptr_t)&myjumpingtoggle;
1650
    aGameVars[Gv_GetVarIndex("myonground")].val.lValue = (intptr_t)&myonground;
1651
    aGameVars[Gv_GetVarIndex("myhardlanding")].val.lValue = (intptr_t)&myhardlanding;
1652
    aGameVars[Gv_GetVarIndex("myreturntocenter")].val.lValue = (intptr_t)&myreturntocenter;
534 terminx 1653
 
1189 terminx 1654
    aGameVars[Gv_GetVarIndex("display_mirror")].val.lValue = (intptr_t)&display_mirror;
1655
    aGameVars[Gv_GetVarIndex("randomseed")].val.lValue = (intptr_t)&randomseed;
770 hnt_ts 1656
 
1189 terminx 1657
    aGameVars[Gv_GetVarIndex("NUMWALLS")].val.lValue = (intptr_t)&numwalls;
1658
    aGameVars[Gv_GetVarIndex("NUMSECTORS")].val.lValue = (intptr_t)&numsectors;
2484 helixhorne 1659
    aGameVars[Gv_GetVarIndex("Numsprites")].val.lValue = (intptr_t)&Numsprites;
1143 terminx 1660
 
1189 terminx 1661
    aGameVars[Gv_GetVarIndex("lastsavepos")].val.lValue = (intptr_t)&g_lastSaveSlot;
3343 helixhorne 1662
# ifdef USE_OPENGL
1367 qbix79 1663
    aGameVars[Gv_GetVarIndex("rendmode")].val.lValue = (intptr_t)&rendmode;
3343 helixhorne 1664
# endif
3354 helixhorne 1665
}
1366 plagman 1666
#endif