2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * Licensed under the BSD license, see LICENSE in OpenBOR root for details.
6 * Copyright (c) 2004 - 2011 OpenBOR Team
17 #include "stringptr.h"
32 #define MKDIR(x) mkdir(x, 0777)
35 #define CHECK_LOGFILE(type) type ? fileExists("d:\\Logs\\OpenBorLog.txt") : fileExists("d:\\Logs\\ScriptLog.txt")
36 #define OPEN_LOGFILE(type) type ? fopen("d:\\Logs\\OpenBorLog.txt", "wt") : fopen("d:\\Logs\\ScriptLog.txt", "wt")
37 #define APPEND_LOGFILE(type) type ? fopen("d:\\Logs\\OpenBorLog.txt", "at") : fopen("d:\\Logs\\ScriptLog.txt", "at")
38 #define READ_LOGFILE(type) type ? fopen("d:\\Logs\\OpenBorLog.txt", "rt") : fopen("d:\\Logs\\ScriptLog.txt", "rt")
39 #define COPY_ROOT_PATH(buf, name) strncpy(buf, "d:\\", 3); strncat(buf, name, strlen(name)); strncat(buf, "\\", 1)
40 #define COPY_PAKS_PATH(buf, name) strncpy(buf, "d:\\Paks\\", 8); strncat(buf, name, strlen(name))
42 #define CHECK_LOGFILE(type) type ? fileExists(getFullPath("Logs/OpenBorLog.txt")) : fileExists(getFullPath("Logs/ScriptLog.txt"))
43 #define OPEN_LOGFILE(type) type ? fopen(getFullPath("Logs/OpenBorLog.txt"), "wt") : fopen(getFullPath("Logs/ScriptLog.txt"), "wt")
44 #define APPEND_LOGFILE(type) type ? fopen(getFullPath("Logs/OpenBorLog.txt"), "at") : fopen(getFullPath("Logs/ScriptLog.txt"), "at")
45 #define READ_LOGFILE(type) type ? fopen(getFullPath("Logs/OpenBorLog.txt"), "rt") : fopen(getFullPath("Logs/ScriptLog.txt"), "rt")
46 #define COPY_ROOT_PATH(buf, name) strcpy(buf, rootDir); strncat(buf, name, strlen(name)); strncat(buf, "/", 1);
47 #define COPY_PAKS_PATH(buf, name) strncpy(buf, paksDir, strlen(paksDir)); strncat(buf, "/", 1); strncat(buf, name, strlen(name));
49 #define CHECK_LOGFILE(type) type ? fileExists("sd:/apps/OpenBOR/Logs/OpenBorLog.txt") : fileExists("sd:/apps/OpenBOR/Logs/ScriptLog.txt")
50 #define OPEN_LOGFILE(type) type ? fopen("sd:/apps/OpenBOR/Logs/OpenBorLog.txt", "wt") : fopen("sd:/apps/OpenBOR/Logs/ScriptLog.txt", "wt")
51 #define APPEND_LOGFILE(type) type ? fopen("sd:/apps/OpenBOR/Logs/OpenBorLog.txt", "at") : fopen("sd:/apps/OpenBOR/Logs/ScriptLog.txt", "at")
52 #define READ_LOGFILE(type) type ? fopen("sd:/apps/OpenBOR/Logs/OpenBorLog.txt", "rt") : fopen("sd:/apps/OpenBOR/Logs/ScriptLog.txt", "rt")
53 #define COPY_ROOT_PATH(buf, name) strncpy(buf, "sd:/apps/OpenBOR/", 17); strncat(buf, name, strlen(name)); strncat(buf, "/", 1);
54 #define COPY_PAKS_PATH(buf, name) strncpy(buf, "sd:/apps/OpenBOR/Paks/", 22); strncat(buf, name, strlen(name));
56 #define CHECK_LOGFILE(type) type ? fileExists("./Logs/OpenBorLog.txt") : fileExists("./Logs/ScriptLog.txt")
57 #define OPEN_LOGFILE(type) type ? fopen("./Logs/OpenBorLog.txt", "wt") : fopen("./Logs/ScriptLog.txt", "wt")
58 #define APPEND_LOGFILE(type) type ? fopen("./Logs/OpenBorLog.txt", "at") : fopen("./Logs/ScriptLog.txt", "at")
59 #define READ_LOGFILE(type) type ? fopen("./Logs/OpenBorLog.txt", "rt") : fopen("./Logs/ScriptLog.txt", "rt")
60 #define COPY_ROOT_PATH(buf, name) strncpy(buf, "./", 2); strncat(buf, name, strlen(name)); strncat(buf, "/", 1);
61 #define COPY_PAKS_PATH(buf, name) strncpy(buf, "./Paks/", 7); strncat(buf, name, strlen(name));
64 void debugBuf(unsigned char *buf
, size_t size
, int columns
) {
68 for(i
= 0; i
< columns
; i
++) {
71 printf("%02x", buf
[pos
]);
78 //lowercases a buffer inplace
79 void lc(char *buf
, size_t size
) {
81 for(i
= 0; i
< size
; i
++)
82 buf
[i
] = tolower((int) buf
[i
]);
85 // returns position after next newline in buf
86 size_t getNewLineStart(char *buf
) {
88 while(buf
[res
] && buf
[res
] != '\n' && buf
[res
] != '\r')
90 while(buf
[res
] && (buf
[res
] == '\n' || buf
[res
] == '\r'))
95 void freeAndNull(void** data
) {
102 int is_dir(char* fn
) {
104 if(stat(fn
, &st
) != -1 && S_ISDIR(st
.st_mode
))
109 FILE *openborLog
= NULL
;
110 FILE *scriptLog
= NULL
;
111 char debug_msg
[2048];
112 unsigned long debug_time
= 0xFFFFFFFF;
114 void getBasePath(char *newName
, char *name
, int type
) {
115 char buf
[128] = { "" };
117 snprintf(buf
, sizeof(buf
) - 1, "%s/%s", paksDir
, name
);
119 snprintf(buf
, sizeof(buf
) - 1, "%s/", name
);
123 strncpy(newName
, buf
, sizeof(buf
));
129 int dirExists(char *dname
, int create
) {
130 char realName
[128] = { "" };
132 getBasePath(realName
, dname
, 0);
133 return CreateDirectory(realName
, NULL
);
137 strncpy(realName
, dname
, 128);
138 fd1
= opendir(realName
);
144 fd2
= MKDIR(realName
);
148 chmod(realName
, 0777);
156 int fileExists(char *fnam
) {
158 if((handle
= fopen(fnam
, "rb")) == NULL
)
165 void debug_printf(char *format
, ...) {
168 va_start(arglist
, format
);
169 vsprintf(debug_msg
, format
, arglist
);
172 debug_time
= 0xFFFFFFFF;
175 const char* savefile_exts
[] = {
177 [ST_HISCORE
] = ".hi",
178 [ST_SCRIPT
] = ".scr",
183 int packfile_is_dir(void) {
184 return packfile
[strlen(packfile
) - 1] == '/';
187 void getSaveFileName(char name
[256], savefile_type type
) {
189 char mod
[256] = { "" };
190 const char* ext
= "";
195 ext
= savefile_exts
[type
];
198 if(memcmp(packfile
, paksDir
, l
))
202 if(paksDir
[l
- 1] != '/')
206 l
= strlen(packfile
) - s
;
207 if(!packfile_is_dir())
208 l
-= 4; // strip off ".pak"
210 l
-=1; // strip off "/"
213 memcpy(mod
, packfile
+ s
, l
);
214 memcpy(mod
+ l
, ext
, strlen(ext
));
216 if((fn
= strrchr(mod
, '/')) || (fn
= strrchr(mod
, '\\')))
217 strcpy(name
, fn
+ 1);
222 void screenshot(s_screen
* vscreen
, unsigned char *pal
, int ingame
) {
224 char shotname
[128] = { "" };
225 char modname
[128] = { "" };
227 getSaveFileName(modname
, 99);
229 sprintf(shotname
, "./ScreenShots/%s - %04u.png", modname
, shotnum
);
231 } while(fileExists(shotname
) && shotnum
< 100);
234 savepng(shotname
, vscreen
, pal
);
236 debug_printf("Saved %s", shotname
);
239 unsigned readlsb32(const unsigned char *src
) {
241 ((((unsigned) (src
[0])) & 0xFF) << 0) |
242 ((((unsigned) (src
[1])) & 0xFF) << 8) |
243 ((((unsigned) (src
[2])) & 0xFF) << 16) | ((((unsigned) (src
[3])) & 0xFF) << 24);
246 // Optimized search in an arranged string table, return the index
247 int searchList(const char *list
[], const char *value
, int length
) {
254 // We must convert uppercase values to lowercase,
255 // since this is how every command is written in
256 // our source. Refer to an ASCII Chart
257 if(v
>= 0x41 && v
<= 0x5A)
260 // Index value equals middle value,
261 // Lets search starting from center.
262 if(v
== list
[b
][0]) {
263 if(stricmp(list
[b
], value
) == 0)
266 // Search Down the List.
267 if(v
== list
[b
- 1][0]) {
268 for(i
= b
- 1; i
>= 0; i
--) {
269 if(stricmp(list
[i
], value
) == 0)
271 if(v
!= list
[i
- 1][0])
275 // Search Up the List.
276 if(v
== list
[b
+ 1][0]) {
277 for(i
= b
+ 1; i
< length
; i
++) {
278 if(stricmp(list
[i
], value
) == 0)
280 if(v
!= list
[i
+ 1][0])
284 // No match, return failure.
285 goto searchListFailed
;
287 // Define the starting point.
288 if(v
>= list
[b
+ 1][0])
290 else if(v
<= list
[b
- 1][0])
293 goto searchListFailed
;
295 // Search Up from starting point.
296 for(i
= a
; i
<= c
; i
++) {
297 if(v
== list
[i
][0]) {
298 if(stricmp(list
[i
], value
) == 0)
300 if(v
!= list
[i
+ 1][0])
307 // The search failed!
308 // On five reasons for failure!
309 // 1. Is the list in alphabetical order?
310 // 2. Is the first letter lowercase in list?
311 // 3. Does the value exist in the list?
313 // 5. Is it a text file error?
317 char *commaprint(u64 n
) {
318 static int comma
= '\0';
319 static char retbuf
[30];
320 char *p
= &retbuf
[sizeof(retbuf
) - 1];
324 struct lconv
*lcp
= localeconv();
326 if(lcp
->thousands_sep
!= NULL
&& *lcp
->thousands_sep
!= '\0')
327 comma
= *lcp
->thousands_sep
;
336 if(i
% 3 == 0 && i
!= 0)
346 //! Increase or Decrease an array à la \e vector
348 \param f_caller : name of the calling function for logging purpose
349 \param array : the array to consider
350 \param new_size : new size needed for the array (in BYTE) :
351 -# if new_size <= 0 : Deallocation of the array
352 -# new_size < \a curr_size_allocated - \a grow_step => Decrease of the array
353 -# new_size >= \a curr_size_allocated => Increase of the array
354 \param curr_size_allocated : current allocated size to the array (in BYTE)
355 \param grow_step : bloc size of expansion of the array (in BYTE)
357 void Array_Check_Size(const char *f_caller
, char **array
, int new_size
, int *curr_size_allocated
, int grow_step
) {
364 *curr_size_allocated
= 0;
367 else if(*array
== NULL
) {
368 *curr_size_allocated
= grow_step
;
369 *array
= malloc(*curr_size_allocated
);
371 shutdown(1, "Out Of Memory! Failed in %s\n", f_caller
);
372 memset(*array
, 0, *curr_size_allocated
);
375 // No need to decrease or increase the array
376 else if(new_size
> (*curr_size_allocated
- grow_step
) && new_size
<= *curr_size_allocated
)
379 //-------------------------------------------
380 // Must increase or decrease the array size
382 int old_size
= *curr_size_allocated
;
384 // Recompute needed size
385 *curr_size_allocated
= ((int) ceil((float) new_size
/ (float) grow_step
)) * grow_step
;
388 void *copy
= malloc(*curr_size_allocated
);
390 shutdown(1, "Out Of Memory! Failed in %s\n", f_caller
);
392 // Copy the previous content of the array
393 memcpy(copy
, *array
, ((old_size
< new_size
) ? old_size
: new_size
));
395 // Init the new allocations
396 if(old_size
< *curr_size_allocated
)
397 memset(copy
+ old_size
, 0, *curr_size_allocated
- old_size
);
399 // Free previous array memory
402 // ReAssign the new allocated array
406 void char_to_lower(char *dst
, char *src
, size_t maxlen
) {
408 for(i
= 0; i
< maxlen
; i
++) {
409 dst
[i
] = tolower(src
[i
]);
417 void int_min_max(int* candidate
, int min
, int max
) {
420 else if (*candidate
> max
)
424 void short_min_max(short* candidate
, short min
, short max
) {
427 else if (*candidate
> max
)