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