1 #pragma once
2
3 #include <cstdint>
4 #include <limits>
5 #include <string>
6 namespace dvl {
7
8 // Note to self: Linker error => forgot a return value in cpp
9
10 // Storm API definition
11 #ifndef STORMAPI
12 #define STORMAPI
13 #endif
14
15 #ifdef __cplusplus
16 struct CCritSect {
17 SDL_mutex *m_critsect;
18
CCritSectCCritSect19 CCritSect()
20 {
21 m_critsect = SDL_CreateMutex();
22 if (m_critsect == NULL) {
23 ErrSdl();
24 }
25 }
~CCritSectCCritSect26 ~CCritSect()
27 {
28 SDL_DestroyMutex(m_critsect);
29 }
EnterCCritSect30 void Enter()
31 {
32 if (SDL_LockMutex(m_critsect) < 0) {
33 ErrSdl();
34 }
35 }
LeaveCCritSect36 void Leave()
37 {
38 if (SDL_UnlockMutex(m_critsect) < 0) {
39 ErrSdl();
40 }
41 }
42 };
43 #endif
44
45 // Game states
46 #define GAMESTATE_PRIVATE 0x01
47 #define GAMESTATE_FULL 0x02
48 #define GAMESTATE_ACTIVE 0x04
49 #define GAMESTATE_STARTED 0x08
50 #define GAMESTATE_REPLAY 0x80
51
52 #define PS_CONNECTED 0x10000
53 #define PS_TURN_ARRIVED 0x20000
54 #define PS_ACTIVE 0x40000
55
56 #define LEAVE_ENDING 0x40000004
57 #define LEAVE_DROP 0x40000006
58
59 #if defined(__GNUC__) || defined(__cplusplus)
60 extern "C" {
61 #endif
62
63 BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, char *GameTemplateData, int GameTemplateSize, int playerCount, const char *creatorName, const char *a11, int *playerID);
64 BOOL STORMAPI SNetDestroy();
65
66 /* SNetDropPlayer @ 106
67 *
68 * Drops a player from the current game.
69 *
70 * playerid: The player ID for the player to be dropped.
71 * flags:
72 *
73 * Returns TRUE if the function was called successfully and FALSE otherwise.
74 */
75 BOOL
76 STORMAPI
77 SNetDropPlayer(
78 int playerid,
79 DWORD flags);
80
81 /* SNetGetGameInfo @ 107
82 *
83 * Retrieves specific game information from Storm, such as name, password,
84 * stats, mode, game template, and players.
85 *
86 * type: The type of data to retrieve. See GAMEINFO_ flags.
87 * dst: The destination buffer for the data.
88 * length: The maximum size of the destination buffer.
89 *
90 * Returns TRUE if the function was called successfully and FALSE otherwise.
91 */
92 BOOL
93 STORMAPI
94 SNetGetGameInfo(
95 int type,
96 void *dst,
97 unsigned int length);
98
99 /* SNetGetTurnsInTransit @ 115
100 *
101 * Retrieves the number of turns (buffers) that have been queued
102 * before sending them over the network.
103 *
104 * turns: A pointer to an integer that will receive the value.
105 *
106 * Returns TRUE if the function was called successfully and FALSE otherwise.
107 */
108 BOOL
109 STORMAPI
110 SNetGetTurnsInTransit(
111 DWORD *turns);
112
113 // Network provider structures
114 typedef struct _client_info {
115 DWORD dwSize; // 60
116 char *pszName;
117 char *pszVersion;
118 DWORD dwProduct;
119 DWORD dwVerbyte;
120 DWORD dwUnk5;
121 DWORD dwMaxPlayers;
122 DWORD dwUnk7;
123 DWORD dwUnk8;
124 DWORD dwUnk9;
125 DWORD dwUnk10; // 0xFF
126 char *pszCdKey;
127 char *pszCdOwner;
128 DWORD dwIsShareware;
129 DWORD dwLangId;
130 } client_info;
131
132 typedef struct _user_info {
133 DWORD dwSize; // 16
134 char *pszPlayerName;
135 char *pszUnknown;
136 DWORD dwUnknown;
137 } user_info;
138
139 BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid);
140
141 /* SNetLeaveGame @ 119
142 *
143 * Notifies Storm that the player has left the game. Storm will
144 * notify all connected peers through the network provider.
145 *
146 * type: The leave type. It doesn't appear to be important, no documentation available.
147 *
148 * Returns TRUE if the function was called successfully and FALSE otherwise.
149 */
150 BOOL
151 STORMAPI
152 SNetLeaveGame(
153 int type);
154
155 BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus);
156 BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes);
157 BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, DWORD *arraydatabytes, DWORD *arrayplayerstatus);
158
159 typedef void(STORMAPI *SEVTHANDLER)(struct _SNETEVENT *);
160
161 /* SNetSendMessage @ 127
162 *
163 * Sends a message to a player given their player ID. Network message
164 * is sent using class 01 and is retrieved by the other client using
165 * SNetReceiveMessage().
166 *
167 * playerID: The player index of the player to receive the data.
168 * Conversely, this field can be one of the following constants:
169 * SNPLAYER_ALL | Sends the message to all players, including oneself.
170 * SNPLAYER_OTHERS | Sends the message to all players, except for oneself.
171 * data: A pointer to the data.
172 * databytes: The amount of bytes that the data pointer contains.
173 *
174 * Returns TRUE if the function was called successfully and FALSE otherwise.
175 */
176 BOOL
177 STORMAPI
178 SNetSendMessage(
179 int playerID,
180 void *data,
181 unsigned int databytes);
182
183 // Macro values to target specific players
184 #define SNPLAYER_ALL -1
185 #define SNPLAYER_OTHERS -2
186
187 #define MPQ_FLAG_READ_ONLY 1
188 #define SFILE_OPEN_FROM_MPQ 0
189 #define SFILE_OPEN_LOCAL_FILE 0xFFFFFFFF
190
191 /* SNetSendTurn @ 128
192 *
193 * Sends a turn (data packet) to all players in the game. Network data
194 * is sent using class 02 and is retrieved by the other client using
195 * SNetReceiveTurns().
196 *
197 * data: A pointer to the data.
198 * databytes: The amount of bytes that the data pointer contains.
199 *
200 * Returns TRUE if the function was called successfully and FALSE otherwise.
201 */
202 BOOL
203 STORMAPI
204 SNetSendTurn(
205 char *data,
206 unsigned int databytes);
207
208 BOOL STORMAPI SFileCloseArchive(HANDLE hArchive);
209 BOOL STORMAPI SFileCloseFile(HANDLE hFile);
210
211 LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);
212 BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq);
213
214 BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile);
215 BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile);
216
217 BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG *lpDistanceToMoveHigh);
218
219 /* SBmpLoadImage @ 323
220 *
221 * Load an image from an available archive into a buffer.
222 *
223 * pszFileName: The name of the graphic in an active archive.
224 * pPalette: An optional buffer that receives the image palette.
225 * pBuffer: A buffer that receives the image data.
226 * dwBuffersize: The size of the specified image buffer.
227 * pdwWidth: An optional variable that receives the image width.
228 * pdwHeight: An optional variable that receives the image height.
229 * pdwBpp: An optional variable that receives the image bits per pixel.
230 *
231 * Returns TRUE if the image was supported and loaded correctly, FALSE otherwise.
232 */
233 BOOL
234 STORMAPI
235 SBmpLoadImage(
236 const char *pszFileName,
237 SDL_Color *pPalette,
238 BYTE *pBuffer,
239 DWORD dwBuffersize,
240 DWORD *pdwWidth,
241 DWORD *pdwHeight,
242 DWORD *pdwBpp);
243
244 /* SMemAlloc @ 401
245 *
246 * Allocates a block of memory. This block is different
247 * from the standard malloc by including a header containing
248 * information about the block.
249 *
250 * amount: The amount of memory to allocate, in bytes.
251 * logfilename: The name of the file or object that this call belongs to.
252 * logline: The line in the file or one of the SLOG_ macros.
253 * defaultValue: The default value of a byte in the allocated memory.
254 *
255 * Returns a pointer to the allocated memory. This pointer does NOT include
256 * the additional storm header.
257 */
258 void *
259 STORMAPI
260 SMemAlloc(
261 unsigned int amount,
262 const char *logfilename,
263 int logline,
264 int defaultValue);
265
266 /* SMemFree @ 403
267 *
268 * Frees a block of memory that was created using SMemAlloc,
269 * includes the log file and line for debugging purposes.
270 *
271 * location: The memory location to be freed.
272 * logfilename: The name of the file or object that this call belongs to.
273 * logline: The line in the file or one of the SLOG_ macros.
274 * defaultValue:
275 *
276 * Returns TRUE if the call was successful and FALSE otherwise.
277 */
278 BOOL
279 STORMAPI
280 SMemFree(
281 void *location,
282 const char *logfilename,
283 int logline,
284 char defaultValue);
285
286 bool getIniBool(const char *sectionName, const char *keyName, bool defaultValue = false);
287 bool getIniValue(const char *sectionName, const char *keyName, char *string, int stringSize, const char *defaultString = "");
288 void setIniValue(const char *sectionName, const char *keyName, const char *value, int len = 0);
289 void SaveIni();
290 int getIniInt(const char *keyname, const char *valuename, int defaultValue);
291 void setIniInt(const char *keyname, const char *valuename, int value);
292
293 void SVidPlayBegin(const char *filename, int a2, int a3, int a4, int a5, int flags, HANDLE *video);
294 void SVidPlayEnd(HANDLE video);
295
296 /* SErrGetLastError @ 463
297 *
298 * Retrieves the last error that was specifically
299 * set for the Storm library.
300 *
301 * Returns the last error set within the Storm library.
302 */
303 DWORD
304 STORMAPI
305 SErrGetLastError();
306
307 /* SErrSetLastError @ 465
308 *
309 * Sets the last error for the Storm library and the Kernel32 library.
310 *
311 * dwErrCode: The error code that will be set.
312 */
313 void
314 STORMAPI
315 SErrSetLastError(
316 DWORD dwErrCode);
317
318 // Values for dwErrCode
319 #define STORM_ERROR_GAME_TERMINATED 0x85100069
320 #define STORM_ERROR_INVALID_PLAYER 0x8510006a
321 #define STORM_ERROR_NO_MESSAGES_WAITING 0x8510006b
322 #define STORM_ERROR_NOT_IN_GAME 0x85100070
323 #define STORM_ERROR_REQUIRES_UPGRADE 0x85100077
324
325 /* SStrCopy @ 501
326 *
327 * Copies a string from src to dest (including NULL terminator)
328 * until the max_length is reached.
329 *
330 * dest: The destination array.
331 * src: The source array.
332 * max_length: The maximum length of dest.
333 *
334 */
335 void
336 STORMAPI
337 SStrCopy(
338 char *dest,
339 const char *src,
340 int max_length);
341
342 BOOL SFileSetBasePath(const char *);
343 BOOL SVidPlayContinue(void);
344 BOOL SNetGetOwnerTurnsWaiting(DWORD *);
345 bool SNetUnregisterEventHandler(event_type, SEVTHANDLER);
346 bool SNetRegisterEventHandler(event_type, SEVTHANDLER);
347 BOOLEAN SNetSetBasePlayer(int);
348 int SNetInitializeProvider(unsigned long, struct _SNETPROGRAMDATA *, struct _SNETPLAYERDATA *, struct _SNETUIDATA *, struct _SNETVERSIONDATA *);
349 int SNetGetProviderCaps(struct _SNETCAPS *);
350 int SFileSetFilePointer(HANDLE, int, int*, int);
351 BOOL SFileEnableDirectAccess(BOOL enable);
352
353 #if defined(__GNUC__) || defined(__cplusplus)
354 }
355
356 // Additions to Storm API:
357
358 // Sets the file's 64-bit seek position.
SFileSetFilePointer(HANDLE hFile,std::int64_t offset,int whence)359 inline std::uint64_t SFileSetFilePointer(HANDLE hFile, std::int64_t offset, int whence)
360 {
361 int high = static_cast<std::uint64_t>(offset) >> 32;
362 int low = static_cast<int>(offset);
363 low = SFileSetFilePointer(hFile, low, &high, whence);
364 return (static_cast<std::uint64_t>(high) << 32) | low;
365 }
366
367 // Returns the current 64-bit file seek position.
SFileGetFilePointer(HANDLE hFile)368 inline std::uint64_t SFileGetFilePointer(HANDLE hFile)
369 {
370 // We use `SFileSetFilePointer` with offset 0 to get the current position
371 // because there is no `SFileGetFilePointer`.
372 return SFileSetFilePointer(hFile, 0, DVL_FILE_CURRENT);
373 }
374
375 #endif
376
377 } // namespace dvl
378