/* =========================================================================== ARX FATALIS GPL Source Code Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company. This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code'). Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code. If not, see . In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ ////////////////////////////////////////////////////////////////////////////////////// // @@ @@@ @@@ @@ @@@@@ // // @@@ @@@@@@ @@@ @@ @@@@ @@@ @@@ // // @@@ @@@@@@@ @@@ @@@@ @@@@ @@ @@@@ // // @@@ @@ @@@@ @@@ @@@@@ @@@@@@ @@@ @@@ // // @@@@@ @@ @@@@ @@@ @@@@@ @@@@@@@ @@@ @ @@@ // // @@@@@ @@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@ @@@@@@@ // // @@ @@@ @@ @@@@ @@@@@@@ @@@ @@@ @@@@@@ @@ @@@@ // // @@@ @@@ @@@ @@@@ @@@@@ @@@@@@@@@ @@@@@@@ @@@ @@@@ // // @@@ @@@@ @@@@@@@ @@@@@@ @@@ @@@@ @@@ @@@ @@@ @@@@ // // @@@@@@@@ @@@@@ @@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ // // @@@ @@@@ @@@@ @@@ @@@@@@@ @@@ @@@ @@@@ @@@ @@@@ @@@@@ // //@@@ @@@@ @@@@@ @@@ @@@@@@ @@ @@@ @@@@ @@@@@@@ @@@@@ @@@@@ // //@@@ @@@@@ @@@@@ @@@@ @@@ @@ @@ @@@@ @@@@@@@ @@@@@@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ // //@@@ @@@@ @@@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@ // //@@@ @@@ @@@ @@@@@ @@ @@@ // // @@@ @@@ @@ @@ STUDIOS // ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// // HERMESMain ////////////////////////////////////////////////////////////////////////////////////// // // Description: // HUM...hum... // // Updates: (date) (person) (update) // // Code: Cyril Meynier // // Copyright (c) 1999 ARKANE Studios SA. All rights reserved ////////////////////////////////////////////////////////////////////////////////////// // Desc: HERMES main functionalities //FILES MEMORY #include #include #include #include #include #include #include // _getcwd #include "HERMESmain.h" #include "HERMESNet.h" #define _CRTDBG_MAP_ALLOC #include char HermesBufferWork[_MAX_PATH]; // Used by FileStandardize (avoid malloc/free per call) UINT GaiaWM = 0; HWND MAIN_PROGRAM_HANDLE = NULL; long DEBUGG = 1; void SAFEstrcpy(char * dest, char * src, unsigned long max) { if (strlen(src) > max) { memcpy(dest, src, max); } else { strcpy(dest, src); } } unsigned char IsIn(char * strin, char * str) { char * tmp; tmp = strstr(strin, str); if (tmp == NULL) return 0; return 1; } unsigned char NC_IsIn(char * strin, char * str) { char * tmp; char t1[4096]; char t2[4096]; strcpy(t1, strin); strcpy(t2, str); MakeUpcase(t1); MakeUpcase(t2); tmp = strstr(t1, t2); if (tmp == NULL) return 0; return 1; } void File_Standardize(char * from, char * to) { long pos = 0; long pos2 = 0; long size = strlen(from); char * temp = HermesBufferWork; while (pos < size) { if (((from[pos] == '\\') || (from[pos] == '/')) && (pos != 0)) { while ((pos < size - 1) && ((from[pos+1] == '\\') || (from[pos+1] == '/'))) pos++; } temp[pos2++] = ARX_CLEAN_WARN_CAST_CHAR(toupper(from[pos])); pos++; } temp[pos2] = 0; again: ; size = strlen(temp); pos = 0; while (pos < size - 2) { if ((temp[pos] == '\\') && (temp[pos+1] == '.') && (temp[pos+2] == '.')) { long fnd = pos; while (pos > 0) { pos--; if (temp[pos] == '\\') { strcpy(temp + pos, temp + fnd + 3); goto again; } } } pos++; } strcpy(to, temp); } long KillAllDirectory(char * path) { long idx; struct _finddata_t fl; char pathh[512]; sprintf(pathh, "%s*.*", path); if ((idx = _findfirst(pathh, &fl)) != -1) { do { if (fl.name[0] != '.') { if (fl.attrib & _A_SUBDIR) { sprintf(pathh, "%s%s\\", path, fl.name); KillAllDirectory(pathh); RemoveDirectory(pathh); } else { sprintf(pathh, "%s%s", path, fl.name); DeleteFile(pathh); } } } while (_findnext(idx, &fl) != -1); _findclose(idx); } RemoveDirectory(path); return 1; } void GetDate(HERMES_DATE_TIME * hdt) { struct tm * newtime; time_t long_time; time(&long_time); /* Get time as long integer. */ newtime = localtime(&long_time); /* Convert to local time. */ if (newtime) { hdt->secs = newtime->tm_sec; hdt->mins = newtime->tm_min; hdt->hours = newtime->tm_hour; hdt->months = newtime->tm_mon + 1; hdt->days = newtime->tm_mday; hdt->years = newtime->tm_year + 1900; } else { hdt->secs = 0; hdt->mins = 0; hdt->hours = 0; hdt->months = 5; hdt->days = 32; hdt->years = 2002; } } long DebugLvl[6]; void HERMES_InitDebug() { DebugLvl[0] = 1; DebugLvl[1] = 1; DebugLvl[2] = 1; DebugLvl[3] = 1; DebugLvl[4] = 1; DebugLvl[5] = 1; DEBUGG = 0; } void MakeUpcase(char * str) { strupr(str); } HKEY ConsoleKey = NULL; #define CONSOLEKEY_KEY TEXT("Software\\Arkane_Studios\\ASMODEE") void ConsoleSend(char * dat, long level, HWND source, long flag) { RegCreateKeyEx(HKEY_CURRENT_USER, CONSOLEKEY_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &ConsoleKey, NULL); WriteRegKey(ConsoleKey, "ConsInfo", dat); WriteRegKeyValue(ConsoleKey, "ConsHwnd", (DWORD)source); WriteRegKeyValue(ConsoleKey, "ConsLevel", (DWORD)level); WriteRegKeyValue(ConsoleKey, "ConsFlag", (DWORD)flag); RegCloseKey(ConsoleKey); } void SendConsole(char * dat, long level, long flag, HWND source) { if (GaiaWM != 0) { if (DebugLvl[0]) return; if (level < 1) return; if (level > 5) return; if (DebugLvl[level]) { ConsoleSend(dat, level, source, flag); SendMessage(HWND_BROADCAST, GaiaWM, 33, 33); } } } long FINAL_COMMERCIAL_DEMO_bis = 1; void ForceSendConsole(char * dat, long level, long flag, HWND source) { if (!FINAL_COMMERCIAL_DEMO_bis) { if (GaiaWM != 0) { ConsoleSend(dat, level, source, flag); SendMessage(HWND_BROADCAST, GaiaWM, 33, 33); } } } /////////////////////////////////////////////////////////////////////////////// HKEY ComKey = NULL; #define COMKEY_KEY TEXT("Software\\Arkane_Studios\\GaiaCom") char * HERMES_GaiaCOM_Receive() { static char dat[1024]; RegCreateKeyEx(HKEY_CURRENT_USER, COMKEY_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &ComKey, NULL); ReadRegKey(ComKey, "ComInfo", dat, 512, ""); RegCloseKey(ComKey); return dat; } //****************************************************************************** // MEMORY MANAGEMENT //****************************************************************************** #ifdef _DEBUG long HERMES_KEEP_MEMORY_TRACE = 0; #else long HERMES_KEEP_MEMORY_TRACE = 0; #endif #define SIZE_STRING_MEMO_TRACE 24 typedef struct { void * ptr; char string1[SIZE_STRING_MEMO_TRACE]; unsigned long size; } MEMO_TRACE; MEMO_TRACE * MemoTraces = NULL; long nb_MemoTraces = 0; void HERMES_UnRegister_Memory(void * adr) { long pos = -1; for (long i = 0; i < nb_MemoTraces; i++) { if (MemoTraces[i].ptr == adr) { pos = i; break; } } if (pos == -1) return; if (nb_MemoTraces == 1) { free(MemoTraces); MemoTraces = NULL; nb_MemoTraces = 0; return; } MEMO_TRACE * tempo = (MEMO_TRACE *)malloc(sizeof(MEMO_TRACE) * (nb_MemoTraces - 1)); if (tempo == NULL) { HERMES_KEEP_MEMORY_TRACE = 0; free(MemoTraces); return; } for (int i = 0; i < nb_MemoTraces - 1; i++) { if (i >= pos) { memcpy(&MemoTraces[i], &MemoTraces[i+1], sizeof(MEMO_TRACE)); } } memcpy(tempo, MemoTraces, sizeof(MEMO_TRACE)*(nb_MemoTraces - 1)); free(MemoTraces); MemoTraces = (MEMO_TRACE *)tempo; nb_MemoTraces--; } unsigned long MakeMemoryText(char * text) { if (HERMES_KEEP_MEMORY_TRACE == 0) { strcpy(text, "Memory Tracing OFF."); return 0; } BOOL * ignore; unsigned long TotMemory = 0; unsigned long TOTTotMemory = 0; char header[128]; char theader[128]; if (nb_MemoTraces == 0) { text[0] = 0; return 0; } ignore = (BOOL *)malloc(sizeof(BOOL) * nb_MemoTraces); for (long i = 0; i < nb_MemoTraces; i++) ignore[i] = FALSE; strcpy(text, ""); for (int i = 0; i < nb_MemoTraces; i++) { if (!ignore[i]) { TotMemory = MemoTraces[i].size; if (MemoTraces[i].string1[0] != 0) strcpy(header, MemoTraces[i].string1); else strcpy(header, ""); for (long j = i + 1; j < nb_MemoTraces; j++) { if (!ignore[j]) { if (MemoTraces[j].string1[0] != 0) strcpy(theader, MemoTraces[j].string1); else strcpy(theader, ""); if (!strcmp(header, theader)) { ignore[j] = TRUE; TotMemory += MemoTraces[j].size; } } } sprintf(theader, "%12u %s\r\n", TotMemory, header); if (strlen(text) + strlen(theader) + 4 < 64000) { strcat(text, theader); } TOTTotMemory += TotMemory; } } free(ignore); return TOTTotMemory; } void MemFree(void * adr) { if (HERMES_KEEP_MEMORY_TRACE) HERMES_UnRegister_Memory(adr); free(adr); } long HERMES_CreateFileCheck(const char * name, char * scheck, const long & size, const float & id) { WIN32_FILE_ATTRIBUTE_DATA attrib; FILE * file; long length(size >> 2), i = 7 * 4; if (!GetFileAttributesEx(name, GetFileExInfoStandard, &attrib)) return true; if (!(file = fopen(name, "rb"))) return true; fseek(file, 0, SEEK_END); memset(scheck, 0, size); ((float *)scheck)[0] = id; ((long *)scheck)[1] = size; memcpy(&((long *)scheck)[2], &attrib.ftCreationTime, sizeof(FILETIME)); memcpy(&((long *)scheck)[4], &attrib.ftLastWriteTime, sizeof(FILETIME)); ((long *)scheck)[6] = ftell(file); memcpy(&scheck[i], name, strlen(name) + 1); i += strlen(name) + 1; memset(&scheck[i], 0, i % 4); i += i % 4; i >>= 2; fseek(file, 0, SEEK_SET); while (i < length) { long crc = 0; for (long j(0); j < 256; j++) { char read; if (!fread(&read, 1, 1, file)) break; crc += read; } ((long *)scheck)[i++] = crc; if (feof(file)) { memset(&((long *)scheck)[i], 0, (length - i) << 2); break; } } fclose(file); return false; } //****************************************************************************** // FILES MANAGEMENT //****************************************************************************** char _drv[256]; char _dir[256]; char _name[256]; char _ext[256]; char * GetName(char * str) { _splitpath(str, _drv, _dir, _name, _ext); return _name; } char * GetExt(char * str) { _splitpath(str, _drv, _dir, _name, _ext); return _ext; } void SetExt(char * str, char * new_ext) { _splitpath(str, _drv, _dir, _name, _ext); _makepath(str, _drv, _dir, _name, new_ext); } void AddToName(char * str, char * cat) { _splitpath(str, _drv, _dir, _name, _ext); strcat(_name, cat); _makepath(str, _drv, _dir, _name, _ext); } void RemoveName(char * str) { _splitpath(str, _drv, _dir, _name, _ext); _makepath(str, _drv, _dir, NULL, NULL); } long DirectoryExist(char * name) { long idx; struct _finddata_t fd; if ((idx = _findfirst(name, &fd)) == -1) { _findclose(idx); char initial[256]; _getcwd(initial, 255); if (_chdir(name) == 0) // success { _chdir(initial); return 1; } _chdir(initial); return 0; } _findclose(idx); return 1; } BOOL CreateFullPath(char * path) { char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath(path, drive, dir, fname, ext); if (strlen(dir) == 0) return FALSE; char curpath[256]; strcpy(curpath, drive); strcat(curpath, "\\"); long start = 1; long pos = 1; long size = strlen(dir); while (pos < size) { if ((dir[pos] == '\\') || (dir[pos] == '/')) { dir[pos] = 0; memcpy(curpath + strlen(curpath), dir + start, pos - start + 1); strcat(curpath, "\\"); _mkdir(curpath); start = pos + 1; } pos++; } if (DirectoryExist(path)) return TRUE; return FALSE; } long FileExist(char * name) { long i; if ((i = FileOpenRead(name)) == 0) return 0; FileCloseRead(i); return 1; } long FileOpenRead(char * name) { long handle; handle = _open((const char *)name, (int)_O_BINARY | _O_RDONLY); if (handle < 0) return(0); return(handle + 1); } long FileSizeHandle(long handle) { return(_tell((int)handle - 1)); } long FileOpenWrite(char * name) { int handle; handle = _open((const char *)name, (int)_O_BINARY | _O_CREAT | _O_TRUNC, (int)_S_IWRITE); if (handle < 0) return(0); _close(handle); handle = _open((const char *)name, (int)_O_BINARY | _O_WRONLY); if (handle < 0) return(0); return(handle + 1); } long FileCloseRead(long handle) { return(_close((int)handle - 1)); } long FileCloseWrite(long handle) { _commit((int)handle - 1); return(_close((int)handle - 1)); } long FileRead(long handle, void * adr, long size) { return(_read(handle - 1, adr, size)); } long FileWrite(long handle, void * adr, long size) { return(_write(handle - 1, adr, size)); } long FileSeek(long handle, long offset, long mode) { return(_lseek((int)handle - 1, (long)offset, (int)mode)); } void ExitApp(int v) { if (MAIN_PROGRAM_HANDLE != NULL) SendMessage(MAIN_PROGRAM_HANDLE, WM_CLOSE, 0, 0); exit(v); } // Finishes by a 0 (for text) void * FileLoadMallocZero(char * name, long * SizeLoadMalloc) { long handle; long size1, size2; unsigned char * adr; retry: ; handle = FileOpenRead(name); if (!handle) { char str[256]; strcpy(str, name); int mb; mb = ShowError("FileLoadMalloc", str, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: goto retry; break; case IDIGNORE: if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(NULL); break; } } FileSeek(handle, 0, FILE_SEEK_END); size1 = FileSizeHandle(handle) + 2; adr = (unsigned char *)malloc(size1); if (!adr) { int mb; mb = ShowError("FileLoadMalloc", name, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: FileCloseRead(handle); goto retry; break; case IDIGNORE: FileCloseRead(handle); if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(0); break; } } FileSeek(handle, 0, FILE_SEEK_START); size2 = FileRead(handle, adr, size1 - 2); FileCloseRead(handle); if (size1 != size2 + 2) { free(adr); int mb; mb = ShowError("FileLoadMalloc", name, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: goto retry; break; case IDIGNORE: if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(0); break; } } if (SizeLoadMalloc != NULL) *SizeLoadMalloc = size1; adr[size1-1] = 0; adr[size1-2] = 0; return(adr); } void * FileLoadMalloc(char * name, long * SizeLoadMalloc) { long handle; long size1, size2; unsigned char * adr; retry: handle = FileOpenRead(name); if (!handle) { char str[256]; strcpy(str, name); int mb; mb = ShowError("FileLoadMalloc", str, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: goto retry; break; case IDIGNORE: if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(NULL); break; } } FileSeek(handle, 0, FILE_SEEK_END); size1 = FileSizeHandle(handle); adr = (unsigned char *)malloc(size1); if (!adr) { int mb; mb = ShowError("FileLoadMalloc", name, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: FileCloseRead(handle); goto retry; break; case IDIGNORE: FileCloseRead(handle); if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(0); break; } } FileSeek(handle, 0, FILE_SEEK_START); size2 = FileRead(handle, adr, size1); FileCloseRead(handle); if (size1 != size2) { free(adr); int mb; mb = ShowError("FileLoadMalloc", name, 4); switch (mb) { case IDABORT: ExitApp(1); break; case IDRETRY: goto retry; break; case IDIGNORE: if (SizeLoadMalloc != NULL) *SizeLoadMalloc = 0; return(0); break; } } if (SizeLoadMalloc != NULL) *SizeLoadMalloc = size1; return(adr); } //****************************************************************************** // OPEN/SAVE FILES DIALOGS //****************************************************************************** char LastFolder[_MAX_PATH]; // Last Folder used static OPENFILENAME ofn; bool HERMESFolderBrowse(char * str) { BROWSEINFO bi; LPITEMIDLIST liil; bi.hwndOwner = NULL;//MainFrameWindow; bi.pidlRoot = NULL; bi.pszDisplayName = LastFolder; bi.lpszTitle = str; bi.ulFlags = 0; bi.lpfn = NULL; bi.lParam = 0; bi.iImage = 0; liil = SHBrowseForFolder(&bi); if (liil) { if (SHGetPathFromIDList(liil, LastFolder)) return TRUE; else return FALSE; } else return FALSE; } bool HERMESFolderSelector(char * file_name, char * title) { if (HERMESFolderBrowse(title)) { sprintf(file_name, "%s\\", LastFolder); return TRUE; } else { strcpy(file_name, " "); return FALSE; } } BOOL HERMES_WFSelectorCommon(PSTR pstrFileName, PSTR pstrTitleName, char * filter, long flag, long flag_operation, long max_car, HWND hWnd) { LONG value; char cwd[_MAX_PATH]; ofn.lStructSize = sizeof(OPENFILENAME) ; ofn.hInstance = NULL ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFileTitle = NULL ; ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = "txt" ; ofn.lCustData = 0L ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; ofn.lpstrFilter = filter ; ofn.hwndOwner = hWnd; ofn.lpstrFile = pstrFileName ; ofn.lpstrTitle = pstrTitleName ; ofn.Flags = flag; _getcwd(cwd, _MAX_PATH); ofn.lpstrInitialDir = cwd; ofn.nMaxFile = max_car; if (flag_operation) { value = GetOpenFileName(&ofn); } else { value = GetSaveFileName(&ofn); } return value; } int HERMESFileSelectorOpen(PSTR pstrFileName, PSTR pstrTitleName, char * filter, HWND hWnd) { return HERMES_WFSelectorCommon(pstrFileName, pstrTitleName, filter, OFN_HIDEREADONLY | OFN_CREATEPROMPT, 1, _MAX_PATH, hWnd); } int HERMESFileSelectorSave(PSTR pstrFileName, PSTR pstrTitleName, char * filter, HWND hWnd) { return HERMES_WFSelectorCommon(pstrFileName, pstrTitleName, filter, OFN_OVERWRITEPROMPT, 0, _MAX_PATH, hWnd); } //////////////////////////////////////// PACKING //Always on for now... char WorkBuff[CMP_BUFFER_SIZE]; /* Routine to read uncompressed data. Used only by implode(). ** This routine reads the data that is to be compressed. */ unsigned int ReadUnCompressed(char * buff, unsigned int * size, void * Param) { PARAM * Ptr = (PARAM *) Param; if (Ptr->UnCompressedSize == 0L) { /* This will terminate the compression or extraction process */ return(0); } if (Ptr->UnCompressedSize < (unsigned long)*size) { *size = (unsigned int)Ptr->UnCompressedSize; } memcpy(buff, Ptr->pSource + Ptr->SourceOffset, *size); Ptr->SourceOffset += (unsigned long) * size; Ptr->UnCompressedSize -= (unsigned long) * size; return(*size); } /* Routine to read compressed data. Used only by explode(). ** This routine reads the compressed data that is to be uncompressed. */ unsigned int ReadCompressed(char * buff, unsigned int * size, void * Param) { PARAM * Ptr = (PARAM *) Param; if (Ptr->CompressedSize == 0L) { /* This will terminate the compression or extraction process */ return(0); } if (Ptr->CompressedSize < (unsigned long)*size) { *size = (unsigned int)Ptr->CompressedSize; } memcpy(buff, Ptr->pSource + Ptr->SourceOffset, *size); Ptr->SourceOffset += (unsigned long) * size; Ptr->CompressedSize -= (unsigned long) * size; return(*size); } /* Routime to write compressed data. Used only by implode(). ** This routine writes the compressed data to a memory buffer. */ void WriteCompressed(char * buff, unsigned int * size, void * Param) { PARAM * Ptr = (PARAM *) Param; if (Ptr->CompressedSize + (unsigned long)*size > Ptr->BufferSize) { Ptr->BufferSize = Ptr->CompressedSize + (unsigned long) * size; Ptr->pDestination = (char *)realloc(Ptr->pDestination, Ptr->BufferSize); } if (Ptr->pDestination) { memcpy(Ptr->pDestination + Ptr->DestinationOffset, buff, *size); Ptr->DestinationOffset += (unsigned long) * size; Ptr->CompressedSize += (unsigned long) * size; } } /* Routine to write uncompressed data. Used only by explode(). ** This routine writes the uncompressed data to a memory buffer. */ void WriteUnCompressed(char * buff, unsigned int * size, void * Param) { PARAM * Ptr = (PARAM *) Param; if (Ptr->UnCompressedSize + (unsigned long)*size > Ptr->BufferSize) { Ptr->BufferSize = Ptr->UnCompressedSize + ((unsigned long) * size) * 10; Ptr->pDestination = (char *)realloc(Ptr->pDestination, Ptr->BufferSize); } if (Ptr->pDestination) { memcpy(Ptr->pDestination + Ptr->DestinationOffset, buff, *size); Ptr->DestinationOffset += (unsigned long) * size; Ptr->UnCompressedSize += (unsigned long) * size; } } void WriteUnCompressedNoAlloc(char * buff, unsigned int * size, void * Param) { PARAM * Ptr = (PARAM *) Param; if (Ptr->UnCompressedSize + (unsigned long)*size > Ptr->BufferSize) { Ptr->BufferSize = Ptr->UnCompressedSize + ((unsigned long) * size) * 10; } if (Ptr->pDestination) { memcpy(Ptr->pDestination + Ptr->DestinationOffset, buff, *size); Ptr->DestinationOffset += (unsigned long) * size; Ptr->UnCompressedSize += (unsigned long) * size; } } char * STD_Implode(char * from, long from_size, long * to_size) { if (WorkBuff == NULL) { return NULL; } unsigned int type = CMP_BINARY; unsigned int dsize;// = 2048; if (from_size <= 32768) dsize = 1024; else if (from_size <= 131072) dsize = 2048; else dsize = 4096; PARAM Param; memset(&Param, 0, sizeof(PARAM)); Param.pSource = from; Param.pDestination = (char *)malloc(from_size); bool bFirst = true; while (1) { Param.CompressedSize = 0; Param.UnCompressedSize = from_size; Param.BufferSize = Param.UnCompressedSize; Param.SourceOffset = 0L; Param.DestinationOffset = 0L; Param.Crc = (unsigned long) - 1; long lResult = implode(ReadUnCompressed, WriteCompressed, WorkBuff, &Param, &type, &dsize); if (!lResult) { break; } if (bFirst) { bFirst = false; continue; } lResult = MessageBox(NULL, "Failed while saving...", "Save Error", MB_RETRYCANCEL | MB_ICONERROR); if (lResult == IDCANCEL) { break; } } *to_size = Param.CompressedSize; return Param.pDestination; } char * STD_Explode(char * from, long from_size, long * to_size) { if (WorkBuff == NULL) { return NULL; } PARAM Param; memset(&Param, 0, sizeof(PARAM)); Param.BufferSize = 0; Param.pSource = from; Param.pDestination = NULL; Param.CompressedSize = from_size; Param.Crc = (unsigned long) - 1; unsigned int error = explode(ReadCompressed, WriteUnCompressed, WorkBuff, &Param); if (error) { *to_size = 0; return NULL; } *to_size = Param.UnCompressedSize; return Param.pDestination; } void STD_ExplodeNoAlloc(char * from, long from_size, char * to, long * to_size) { if (WorkBuff == NULL) { return; } PARAM Param; memset(&Param, 0, sizeof(PARAM)); Param.BufferSize = 0; Param.pSource = from; Param.pDestination = to; Param.CompressedSize = from_size; Param.Crc = (unsigned long) - 1; unsigned int error = explode(ReadCompressed, WriteUnCompressedNoAlloc, WorkBuff, &Param); if (error) { *to_size = 0; return; } *to_size = Param.UnCompressedSize; } //------------------------------------------------------------------------------------- // SP funcs #define hrnd() (((FLOAT)rand() ) * 0.00003051850947599f) //------------------------------------------------------------------------------------- // Error Logging Funcs... char ERROR_Log_FIC[256]; long ERROR_Log_Write = 0; void ERROR_Log_Init(char * fich) { strcpy(ERROR_Log_FIC, fich); FILE * fic; if ((fic = fopen(ERROR_Log_FIC, "w")) != NULL) { ERROR_Log_Write = 1; fclose(fic); } else ERROR_Log_Write = 0; } bool ERROR_Log(char * fich) { FILE * fic; if (ERROR_Log_Write) { if ((fic = fopen(ERROR_Log_FIC, "a+")) != NULL) { fprintf(fic, "Error: %s\n", fich); fclose(fic); return true; } } return false; } char * HERMES_MEMORY_SECURITY = NULL; void HERMES_Memory_Security_On(long size) { if (size < 128000) size = 128000; HERMES_MEMORY_SECURITY = (char *)malloc(size); } void HERMES_Memory_Security_Off() { if (HERMES_MEMORY_SECURITY) free(HERMES_MEMORY_SECURITY); HERMES_MEMORY_SECURITY = NULL; } long HERMES_Memory_Emergency_Out(long size, char * info) { if (HERMES_MEMORY_SECURITY) free(HERMES_MEMORY_SECURITY); HERMES_MEMORY_SECURITY = NULL; char out[512]; if (info) { if (size > 0) sprintf(out, "FATAL ERROR: Unable To Allocate %d bytes... %s", size, info); else sprintf(out, "FATAL ERROR: Unable To Allocate Memory... %s", info); } else if (size > 0) sprintf(out, "FATAL ERROR: Unable To Allocate %d bytes...", size); else sprintf(out, "FATAL ERROR: Unable To Allocate Memory..."); int re = MessageBox(NULL, out, "ARX Fatalis", MB_RETRYCANCEL | MB_ICONSTOP); if ((re == IDRETRY) && (size > 0)) return 1; exit(0); return 0; } LARGE_INTEGER start_chrono; long NEED_BENCH = 0; void StartBench() { if (NEED_BENCH) { QueryPerformanceCounter(&start_chrono); } } unsigned long EndBench() { if (NEED_BENCH) { LARGE_INTEGER end_chrono; QueryPerformanceCounter(&end_chrono); unsigned long ret = (unsigned long)(end_chrono.QuadPart - start_chrono.QuadPart); return ret; } return 0; }