Subversion Repositories eduke32

Rev

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

Rev 4895 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
#ifndef gamevars_h_
23
#ifndef gamevars_h_
24
#define gamevars_h_
24
#define gamevars_h_
25
25
26
#include "gamedef.h"
26
#include "gamedef.h"
27
27
28
#define MAXGAMEVARS 2048 // must be a power of two
28
#define MAXGAMEVARS 2048 // must be a power of two
29
#define MAXVARLABEL 26
29
#define MAXVARLABEL 26
30
30
31
// store global game definitions
31
// store global game definitions
32
enum GamevarFlags_t {
32
enum GamevarFlags_t {
33
    GAMEVAR_PERPLAYER  = 0x00000001, // per-player variable
33
    GAMEVAR_PERPLAYER  = 0x00000001, // per-player variable
34
    GAMEVAR_PERACTOR   = 0x00000002, // per-actor variable
34
    GAMEVAR_PERACTOR   = 0x00000002, // per-actor variable
35
    GAMEVAR_USER_MASK  = (GAMEVAR_PERPLAYER|GAMEVAR_PERACTOR),
35
    GAMEVAR_USER_MASK  = (GAMEVAR_PERPLAYER|GAMEVAR_PERACTOR),
36
    GAMEVAR_RESET      = 0x00000008, // INTERNAL, don't use
36
    GAMEVAR_RESET      = 0x00000008, // INTERNAL, don't use
37
    GAMEVAR_DEFAULT    = 0x00000100, // UNUSED, but always cleared for user-defined gamevars
37
    GAMEVAR_DEFAULT    = 0x00000100, // UNUSED, but always cleared for user-defined gamevars
38
    GAMEVAR_SECRET     = 0x00000200, // don't dump...
38
    GAMEVAR_SECRET     = 0x00000200, // don't dump...
39
    GAMEVAR_NODEFAULT  = 0x00000400, // don't reset on actor spawn
39
    GAMEVAR_NODEFAULT  = 0x00000400, // don't reset on actor spawn
40
    GAMEVAR_SYSTEM     = 0x00000800, // cannot change mode flags...(only default value)
40
    GAMEVAR_SYSTEM     = 0x00000800, // cannot change mode flags...(only default value)
41
    GAMEVAR_READONLY   = 0x00001000, // values are read-only (no setvar allowed)
41
    GAMEVAR_READONLY   = 0x00001000, // values are read-only (no setvar allowed)
42
    GAMEVAR_INTPTR     = 0x00002000, // plValues is a pointer to an int32_t
42
    GAMEVAR_INTPTR     = 0x00002000, // plValues is a pointer to an int32_t
43
    GAMEVAR_SHORTPTR   = 0x00008000, // plValues is a pointer to a short
43
    GAMEVAR_SHORTPTR   = 0x00008000, // plValues is a pointer to a short
44
    GAMEVAR_CHARPTR    = 0x00010000, // plValues is a pointer to a char
44
    GAMEVAR_CHARPTR    = 0x00010000, // plValues is a pointer to a char
45
    GAMEVAR_PTR_MASK   = (GAMEVAR_INTPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR),
45
    GAMEVAR_PTR_MASK   = (GAMEVAR_INTPTR|GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR),
46
    GAMEVAR_NORESET    = 0x00020000, // var values are not reset when restoring map state
46
    GAMEVAR_NORESET    = 0x00020000, // var values are not reset when restoring map state
47
    GAMEVAR_SPECIAL    = 0x00040000, // flag for structure member shortcut vars
47
    GAMEVAR_SPECIAL    = 0x00040000, // flag for structure member shortcut vars
48
    GAMEVAR_NOMULTI    = 0x00080000, // don't attach to multiplayer packets
48
    GAMEVAR_NOMULTI    = 0x00080000, // don't attach to multiplayer packets
49
};
49
};
50
50
51
#if !defined LUNATIC
51
#if !defined LUNATIC
52
52
53
// Alignments for per-player and per-actor variables.
53
// Alignments for per-player and per-actor variables.
54
#define PLAYER_VAR_ALIGNMENT (sizeof(intptr_t))
54
#define PLAYER_VAR_ALIGNMENT (sizeof(intptr_t))
55
#define ACTOR_VAR_ALIGNMENT 16
55
#define ACTOR_VAR_ALIGNMENT 16
56
56
57
# define MAXGAMEARRAYS (MAXGAMEVARS>>2) // must be strictly smaller than MAXGAMEVARS
57
# define MAXGAMEARRAYS (MAXGAMEVARS>>2) // must be strictly smaller than MAXGAMEVARS
58
# define MAXARRAYLABEL MAXVARLABEL
58
# define MAXARRAYLABEL MAXVARLABEL
59
59
60
enum GamearrayFlags_t {
60
enum GamearrayFlags_t {
61
61
62
    GAMEARRAY_READONLY = 0x00001000,
62
    GAMEARRAY_READONLY = 0x00001000,
63
    GAMEARRAY_WARN = 0x00002000,
63
    GAMEARRAY_WARN = 0x00002000,
64
64
65
    GAMEARRAY_NORMAL   = 0x00004000,
65
    GAMEARRAY_NORMAL   = 0x00004000,
66
    GAMEARRAY_OFCHAR   = 0x00000001,
66
    GAMEARRAY_OFCHAR   = 0x00000001,
67
    GAMEARRAY_OFSHORT  = 0x00000002,
67
    GAMEARRAY_OFSHORT  = 0x00000002,
68
    GAMEARRAY_OFINT    = 0x00000004,
68
    GAMEARRAY_OFINT    = 0x00000004,
69
    GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT,
69
    GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT,
70
70
71
    GAMEARRAY_VARSIZE = 0x00000020,
71
    GAMEARRAY_VARSIZE = 0x00000020,
72
72
73
    GAMEARRAY_RESET    = 0x00000008,
73
    GAMEARRAY_RESET    = 0x00000008,
74
///    GAMEARRAY_NORESET  = 0x00000001,
74
///    GAMEARRAY_NORESET  = 0x00000001,
75
};
75
};
76
76
77
#pragma pack(push,1)
77
#pragma pack(push,1)
78
typedef struct {
78
typedef struct {
79
    union {
79
    union {
80
        intptr_t lValue;
80
        intptr_t lValue;
81
        intptr_t *plValues;     // array of values when 'per-player', or 'per-actor'
81
        intptr_t *plValues;     // array of values when 'per-player', or 'per-actor'
82
    } val;
82
    } val;
83
    intptr_t lDefault;
83
    intptr_t lDefault;
84
    uintptr_t dwFlags;
84
    uintptr_t dwFlags;
85
    char *szLabel;
85
    char *szLabel;
86
} gamevar_t;
86
} gamevar_t;
87
87
88
typedef struct {
88
typedef struct {
89
    char *szLabel;
89
    char *szLabel;
90
    intptr_t *plValues;     // array of values
90
    intptr_t *plValues;     // array of values
91
    intptr_t size;
91
    intptr_t size;
92
    intptr_t dwFlags;
92
    intptr_t dwFlags;
93
} gamearray_t;
93
} gamearray_t;
94
#pragma pack(pop)
94
#pragma pack(pop)
95
95
96
# define GAR_ELTSZ (sizeof(aGameArrays[0].plValues[0]))
96
# define GAR_ELTSZ (sizeof(aGameArrays[0].plValues[0]))
97
97
98
extern gamevar_t aGameVars[MAXGAMEVARS];
98
extern gamevar_t aGameVars[MAXGAMEVARS];
99
extern gamearray_t aGameArrays[MAXGAMEARRAYS];
99
extern gamearray_t aGameArrays[MAXGAMEARRAYS];
100
extern int32_t g_gameVarCount;
100
extern int32_t g_gameVarCount;
101
extern int32_t g_gameArrayCount;
101
extern int32_t g_gameArrayCount;
102
102
103
int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer);
103
int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer);
104
void __fastcall Gv_SetVar(int32_t id, int32_t lValue, int32_t iActor, int32_t iPlayer);
104
void __fastcall Gv_SetVar(int32_t const id, int32_t const lValue, int32_t const iActor, int32_t const iPlayer);
105
int32_t __fastcall Gv_GetVarX(int32_t id);
105
int32_t __fastcall Gv_GetVarX(int32_t id);
106
void __fastcall Gv_SetVarX(int32_t id, int32_t lValue);
106
void __fastcall Gv_SetVarX(int32_t const id, int32_t const lValue);
107
107
108
int32_t Gv_GetVarByLabel(const char *szGameLabel,int32_t lDefault,int32_t iActor,int32_t iPlayer);
108
int32_t Gv_GetVarByLabel(const char *szGameLabel,int32_t const lDefault,int32_t const iActor,int32_t const iPlayer);
109
int32_t Gv_NewArray(const char *pszLabel,void *arrayptr,intptr_t asize,uint32_t dwFlags);
109
int32_t Gv_NewArray(const char *pszLabel,void *arrayptr,intptr_t asize,uint32_t dwFlags);
110
int32_t Gv_NewVar(const char *pszLabel,intptr_t lValue,uint32_t dwFlags);
110
int32_t Gv_NewVar(const char *pszLabel,intptr_t lValue,uint32_t dwFlags);
111
111
112
static inline void A_ResetVars(const int32_t iActor)
112
static inline void A_ResetVars(const int32_t iActor)
113
{
113
{
114
    for (int i = 0; i < g_gameVarCount; i++)
114
    for (int i = 0; i < g_gameVarCount; i++)
115
    {
115
    {
116
        if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
116
        if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
117
            aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault;
117
            aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault;
118
    }
118
    }
119
}
119
}
120
120
121
void Gv_DumpValues(void);
121
void Gv_DumpValues(void);
122
void Gv_InitWeaponPointers(void);
122
void Gv_InitWeaponPointers(void);
123
void Gv_RefreshPointers(void);
123
void Gv_RefreshPointers(void);
124
void Gv_ResetVars(void);
124
void Gv_ResetVars(void);
125
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
125
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
126
void Gv_WriteSave(FILE *fil,int32_t newbehav);
126
void Gv_WriteSave(FILE *fil,int32_t newbehav);
127
#else
127
#else
128
extern int32_t g_noResetVars;
128
extern int32_t g_noResetVars;
129
extern LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
129
extern LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
130
#endif
130
#endif
131
131
132
void Gv_ResetSystemDefaults(void);
132
void Gv_ResetSystemDefaults(void);
133
void Gv_Init(void);
133
void Gv_Init(void);
134
void Gv_FinalizeWeaponDefaults(void);
134
void Gv_FinalizeWeaponDefaults(void);
135
135
136
#if !defined LUNATIC
136
#if !defined LUNATIC
137
#define VM_GAMEVAR_OPERATOR(func, operator)                                                                            \
137
#define VM_GAMEVAR_OPERATOR(func, operator)                                                                            \
138
    static inline void __fastcall func(const int32_t id, const int32_t lValue)                                         \
138
    static inline void __fastcall func(const int32_t id, const int32_t lValue)                                         \
139
    {                                                                                                                  \
139
    {                                                                                                                  \
140
        switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))                                        \
140
        switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))                                        \
141
        {                                                                                                              \
141
        {                                                                                                              \
142
            default: aGameVars[id].val.lValue operator lValue; break;                                                  \
142
            default: aGameVars[id].val.lValue operator lValue; break;                                                  \
143
            case GAMEVAR_PERPLAYER:                                                                                    \
143
            case GAMEVAR_PERPLAYER:                                                                                    \
144
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p > MAXPLAYERS - 1))                                          \
144
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p > MAXPLAYERS - 1))                                          \
145
                    break;                                                                                             \
145
                    break;                                                                                             \
146
                aGameVars[id].val.plValues[vm.g_p] operator lValue;                                                    \
146
                aGameVars[id].val.plValues[vm.g_p] operator lValue;                                                    \
147
                break;                                                                                                 \
147
                break;                                                                                                 \
148
            case GAMEVAR_PERACTOR:                                                                                     \
148
            case GAMEVAR_PERACTOR:                                                                                     \
149
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i > MAXSPRITES - 1))                                          \
149
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i > MAXSPRITES - 1))                                          \
150
                    break;                                                                                             \
150
                    break;                                                                                             \
151
                aGameVars[id].val.plValues[vm.g_i] operator lValue;                                                    \
151
                aGameVars[id].val.plValues[vm.g_i] operator lValue;                                                    \
152
                break;                                                                                                 \
152
                break;                                                                                                 \
153
            case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) operator (int32_t) lValue; break;              \
153
            case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) operator (int32_t) lValue; break;              \
154
            case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) operator (int16_t) lValue; break;            \
154
            case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) operator (int16_t) lValue; break;            \
155
            case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) operator (uint8_t) lValue; break;             \
155
            case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) operator (uint8_t) lValue; break;             \
156
        }                                                                                                              \
156
        }                                                                                                              \
157
    }
157
    }
158
158
159
#if defined(__arm__) || defined(LIBDIVIDE_ALWAYS)
159
#if defined(__arm__) || defined(LIBDIVIDE_ALWAYS)
160
static inline void __fastcall Gv_DivVar(const int32_t id, const int32_t lValue)
160
static inline void __fastcall Gv_DivVar(const int32_t id, const int32_t lValue)
161
{
161
{
162
    static libdivide_s32_t sdiv;
162
    static libdivide_s32_t sdiv;
163
    static int32_t lastlValue;
163
    static int32_t lastlValue;
164
    libdivide_s32_t *dptr = &sdiv;
164
    libdivide_s32_t *dptr = &sdiv;
165
    intptr_t *iptr = &aGameVars[id].val.lValue;
165
    intptr_t *iptr = &aGameVars[id].val.lValue;
166
166
167
    if (EDUKE32_PREDICT_FALSE((aGameVars[id].dwFlags & GAMEVAR_PERPLAYER && (unsigned)vm.g_p > MAXPLAYERS - 1) ||
167
    if (EDUKE32_PREDICT_FALSE((aGameVars[id].dwFlags & GAMEVAR_PERPLAYER && (unsigned)vm.g_p > MAXPLAYERS - 1) ||
168
                              (aGameVars[id].dwFlags & GAMEVAR_PERACTOR && (unsigned)vm.g_i > MAXSPRITES - 1)))
168
                              (aGameVars[id].dwFlags & GAMEVAR_PERACTOR && (unsigned)vm.g_i > MAXSPRITES - 1)))
169
        return;
169
        return;
170
170
171
    if ((unsigned)lValue < DIVTABLESIZE)
171
    if ((unsigned)lValue < DIVTABLESIZE)
172
        dptr = (libdivide_s32_t *)&divtable32[lValue];
172
        dptr = (libdivide_s32_t *)&divtable32[lValue];
173
    else if (lValue != lastlValue)
173
    else if (lValue != lastlValue)
174
        sdiv = libdivide_s32_gen(lValue), lastlValue = lValue;
174
        sdiv = libdivide_s32_gen(lValue), lastlValue = lValue;
175
175
176
    switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
176
    switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
177
    {
177
    {
178
        case GAMEVAR_PERPLAYER: iptr = &aGameVars[id].val.plValues[vm.g_p];
178
        case GAMEVAR_PERPLAYER: iptr = &aGameVars[id].val.plValues[vm.g_p];
179
        default: break;
179
        default: break;
180
        case GAMEVAR_PERACTOR: iptr = &aGameVars[id].val.plValues[vm.g_i]; break;
180
        case GAMEVAR_PERACTOR: iptr = &aGameVars[id].val.plValues[vm.g_i]; break;
181
        case GAMEVAR_INTPTR:
181
        case GAMEVAR_INTPTR:
182
            *((int32_t *)aGameVars[id].val.lValue) =
182
            *((int32_t *)aGameVars[id].val.lValue) =
183
            (int32_t)libdivide_s32_do(*((int32_t *)aGameVars[id].val.lValue), dptr);
183
            (int32_t)libdivide_s32_do(*((int32_t *)aGameVars[id].val.lValue), dptr);
184
            return;
184
            return;
185
        case GAMEVAR_SHORTPTR:
185
        case GAMEVAR_SHORTPTR:
186
            *((int16_t *)aGameVars[id].val.lValue) =
186
            *((int16_t *)aGameVars[id].val.lValue) =
187
            (int16_t)libdivide_s32_do(*((int16_t *)aGameVars[id].val.lValue), dptr);
187
            (int16_t)libdivide_s32_do(*((int16_t *)aGameVars[id].val.lValue), dptr);
188
            return;
188
            return;
189
        case GAMEVAR_CHARPTR:
189
        case GAMEVAR_CHARPTR:
190
            *((uint8_t *)aGameVars[id].val.lValue) =
190
            *((uint8_t *)aGameVars[id].val.lValue) =
191
            (uint8_t)libdivide_s32_do(*((uint8_t *)aGameVars[id].val.lValue), dptr);
191
            (uint8_t)libdivide_s32_do(*((uint8_t *)aGameVars[id].val.lValue), dptr);
192
            return;
192
            return;
193
    }
193
    }
194
194
195
    *iptr = libdivide_s32_do(*iptr, dptr);
195
    *iptr = libdivide_s32_do(*iptr, dptr);
196
}
196
}
197
#else
197
#else
198
VM_GAMEVAR_OPERATOR(Gv_DivVar, /= )
198
VM_GAMEVAR_OPERATOR(Gv_DivVar, /= )
199
#endif
199
#endif
200
200
201
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)
201
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)
202
VM_GAMEVAR_OPERATOR(Gv_SubVar, -=)
202
VM_GAMEVAR_OPERATOR(Gv_SubVar, -=)
203
VM_GAMEVAR_OPERATOR(Gv_MulVar, *=)
203
VM_GAMEVAR_OPERATOR(Gv_MulVar, *=)
204
VM_GAMEVAR_OPERATOR(Gv_ModVar, %=)
204
VM_GAMEVAR_OPERATOR(Gv_ModVar, %=)
205
VM_GAMEVAR_OPERATOR(Gv_AndVar, &=)
205
VM_GAMEVAR_OPERATOR(Gv_AndVar, &=)
206
VM_GAMEVAR_OPERATOR(Gv_XorVar, ^=)
206
VM_GAMEVAR_OPERATOR(Gv_XorVar, ^=)
207
VM_GAMEVAR_OPERATOR(Gv_OrVar, |=)
207
VM_GAMEVAR_OPERATOR(Gv_OrVar, |=)
208
208
209
#undef VM_GAMEVAR_OPERATOR
209
#undef VM_GAMEVAR_OPERATOR
210
210
211
#endif
211
#endif
212
212
213
#endif
213
#endif
214
 
214