Subversion Repositories eduke32

Rev

Rev 4941 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4941 Rev 5069
1
//-------------------------------------------------------------------------
1
//-------------------------------------------------------------------------
2
/*
2
/*
3
Copyright (C) 2010 EDuke32 developers and contributors
3
Copyright (C) 2010 EDuke32 developers and contributors
4

4

5
This file is part of EDuke32.
5
This file is part of EDuke32.
6

6

7
EDuke32 is free software; you can redistribute it and/or
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
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
9
as published by the Free Software Foundation.
10

10

11
This program is distributed in the hope that it will be useful,
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14

14

15
See the GNU General Public License for more details.
15
See the GNU General Public License for more details.
16

16

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