Subversion Repositories eduke32

Rev

Rev 4839 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4839 Rev 4895
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 id, int32_t lValue, int32_t iActor, int32_t 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 id, int32_t 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 lDefault,int32_t iActor,int32_t 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
    int i;
-
 
115
    for (i = 0; i < g_gameVarCount; i++)
114
    for (int i = 0; i < g_gameVarCount; i++)
116
    {
115
    {
117
        if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
116
        if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
118
            aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault;
117
            aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault;
119
    }
118
    }
120
}
119
}
121
120
122
void Gv_DumpValues(void);
121
void Gv_DumpValues(void);
123
void Gv_InitWeaponPointers(void);
122
void Gv_InitWeaponPointers(void);
124
void Gv_RefreshPointers(void);
123
void Gv_RefreshPointers(void);
125
void Gv_ResetVars(void);
124
void Gv_ResetVars(void);
126
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
125
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
127
void Gv_WriteSave(FILE *fil,int32_t newbehav);
126
void Gv_WriteSave(FILE *fil,int32_t newbehav);
128
#else
127
#else
129
extern int32_t g_noResetVars;
128
extern int32_t g_noResetVars;
130
extern LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
129
extern LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
131
#endif
130
#endif
132
131
133
void Gv_ResetSystemDefaults(void);
132
void Gv_ResetSystemDefaults(void);
134
void Gv_Init(void);
133
void Gv_Init(void);
135
void Gv_FinalizeWeaponDefaults(void);
134
void Gv_FinalizeWeaponDefaults(void);
136
135
137
#if !defined LUNATIC
136
#if !defined LUNATIC
138
#define VM_GAMEVAR_OPERATOR(func, operator)                                                                            \
137
#define VM_GAMEVAR_OPERATOR(func, operator)                                                                            \
139
    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)                                         \
140
    {                                                                                                                  \
139
    {                                                                                                                  \
141
        switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))                                        \
140
        switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))                                        \
142
        {                                                                                                              \
141
        {                                                                                                              \
143
            default: aGameVars[id].val.lValue operator lValue; break;                                                  \
142
            default: aGameVars[id].val.lValue operator lValue; break;                                                  \
144
            case GAMEVAR_PERPLAYER:                                                                                    \
143
            case GAMEVAR_PERPLAYER:                                                                                    \
145
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p > MAXPLAYERS - 1))                                          \
144
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p > MAXPLAYERS - 1))                                          \
146
                    break;                                                                                             \
145
                    break;                                                                                             \
147
                aGameVars[id].val.plValues[vm.g_p] operator lValue;                                                    \
146
                aGameVars[id].val.plValues[vm.g_p] operator lValue;                                                    \
148
                break;                                                                                                 \
147
                break;                                                                                                 \
149
            case GAMEVAR_PERACTOR:                                                                                     \
148
            case GAMEVAR_PERACTOR:                                                                                     \
150
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i > MAXSPRITES - 1))                                          \
149
                if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i > MAXSPRITES - 1))                                          \
151
                    break;                                                                                             \
150
                    break;                                                                                             \
152
                aGameVars[id].val.plValues[vm.g_i] operator lValue;                                                    \
151
                aGameVars[id].val.plValues[vm.g_i] operator lValue;                                                    \
153
                break;                                                                                                 \
152
                break;                                                                                                 \
154
            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;              \
155
            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;            \
156
            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;             \
157
        }                                                                                                              \
156
        }                                                                                                              \
158
    }
157
    }
159
158
160
#if defined(__arm__) || defined(LIBDIVIDE_ALWAYS)
159
#if defined(__arm__) || defined(LIBDIVIDE_ALWAYS)
161
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)
162
{
161
{
163
    static libdivide_s32_t sdiv;
162
    static libdivide_s32_t sdiv;
164
    static int32_t lastlValue;
163
    static int32_t lastlValue;
165
    libdivide_s32_t *dptr = &sdiv;
164
    libdivide_s32_t *dptr = &sdiv;
166
    intptr_t *iptr = &aGameVars[id].val.lValue;
165
    intptr_t *iptr = &aGameVars[id].val.lValue;
167
166
168
    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) ||
169
                              (aGameVars[id].dwFlags & GAMEVAR_PERACTOR && (unsigned)vm.g_i > MAXSPRITES - 1)))
168
                              (aGameVars[id].dwFlags & GAMEVAR_PERACTOR && (unsigned)vm.g_i > MAXSPRITES - 1)))
170
        return;
169
        return;
171
170
172
    if ((unsigned)lValue < DIVTABLESIZE)
171
    if ((unsigned)lValue < DIVTABLESIZE)
173
        dptr = (libdivide_s32_t *)&divtable32[lValue];
172
        dptr = (libdivide_s32_t *)&divtable32[lValue];
174
    else if (lValue != lastlValue)
173
    else if (lValue != lastlValue)
175
        sdiv = libdivide_s32_gen(lValue), lastlValue = lValue;
174
        sdiv = libdivide_s32_gen(lValue), lastlValue = lValue;
176
175
177
    switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
176
    switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
178
    {
177
    {
179
        case GAMEVAR_PERPLAYER: iptr = &aGameVars[id].val.plValues[vm.g_p];
178
        case GAMEVAR_PERPLAYER: iptr = &aGameVars[id].val.plValues[vm.g_p];
180
        default: break;
179
        default: break;
181
        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;
182
        case GAMEVAR_INTPTR:
181
        case GAMEVAR_INTPTR:
183
            *((int32_t *)aGameVars[id].val.lValue) =
182
            *((int32_t *)aGameVars[id].val.lValue) =
184
            (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);
185
            return;
184
            return;
186
        case GAMEVAR_SHORTPTR:
185
        case GAMEVAR_SHORTPTR:
187
            *((int16_t *)aGameVars[id].val.lValue) =
186
            *((int16_t *)aGameVars[id].val.lValue) =
188
            (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);
189
            return;
188
            return;
190
        case GAMEVAR_CHARPTR:
189
        case GAMEVAR_CHARPTR:
191
            *((uint8_t *)aGameVars[id].val.lValue) =
190
            *((uint8_t *)aGameVars[id].val.lValue) =
192
            (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);
193
            return;
192
            return;
194
    }
193
    }
195
194
196
    *iptr = libdivide_s32_do(*iptr, dptr);
195
    *iptr = libdivide_s32_do(*iptr, dptr);
197
}
196
}
198
#else
197
#else
199
VM_GAMEVAR_OPERATOR(Gv_DivVar, /= )
198
VM_GAMEVAR_OPERATOR(Gv_DivVar, /= )
200
#endif
199
#endif
201
200
202
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)
201
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)
203
VM_GAMEVAR_OPERATOR(Gv_SubVar, -=)
202
VM_GAMEVAR_OPERATOR(Gv_SubVar, -=)
204
VM_GAMEVAR_OPERATOR(Gv_MulVar, *=)
203
VM_GAMEVAR_OPERATOR(Gv_MulVar, *=)
205
VM_GAMEVAR_OPERATOR(Gv_ModVar, %=)
204
VM_GAMEVAR_OPERATOR(Gv_ModVar, %=)
206
VM_GAMEVAR_OPERATOR(Gv_AndVar, &=)
205
VM_GAMEVAR_OPERATOR(Gv_AndVar, &=)
207
VM_GAMEVAR_OPERATOR(Gv_XorVar, ^=)
206
VM_GAMEVAR_OPERATOR(Gv_XorVar, ^=)
208
VM_GAMEVAR_OPERATOR(Gv_OrVar, |=)
207
VM_GAMEVAR_OPERATOR(Gv_OrVar, |=)
209
208
210
#undef VM_GAMEVAR_OPERATOR
209
#undef VM_GAMEVAR_OPERATOR
211
210
212
#endif
211
#endif
213
212
214
#endif
213
#endif
215
 
214