// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 1993-2008 Raven Software // Copyright(C) 2005 Simon Howard // // This program 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 2 // of the License, or (at your option) any later version. // // This program 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 this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. // // DESCRIPTION: // Miscellaneous. // //----------------------------------------------------------------------------- #include #include #include #include #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #include #ifdef _MSC_VER #include #endif #else #include #include #endif #include "doomtype.h" #include "deh_str.h" #include "i_swap.h" #include "i_system.h" #include "i_video.h" #include "m_misc.h" #include "v_video.h" #include "w_wad.h" #include "z_zone.h" // // Create a directory // void M_MakeDirectory(char *path) { #ifdef _WIN32 mkdir(path); #else mkdir(path, 0755); #endif } // Check if a file exists boolean M_FileExists(char *filename) { FILE *fstream; fstream = fopen(filename, "r"); if (fstream != NULL) { fclose(fstream); return true; } else { // If we can't open because the file is a directory, the // "file" exists at least! return errno == EISDIR; } } // // Determine the length of an open file. // long M_FileLength(FILE *handle) { long savedpos; long length; // save the current position in the file savedpos = ftell(handle); // jump to the end and find the length fseek(handle, 0, SEEK_END); length = ftell(handle); // go back to the old location fseek(handle, savedpos, SEEK_SET); return length; } // // M_WriteFile // boolean M_WriteFile(char *name, void *source, int length) { FILE *handle; int count; handle = fopen(name, "wb"); if (handle == NULL) return false; count = fwrite(source, 1, length, handle); fclose(handle); if (count < length) return false; return true; } // // M_ReadFile // int M_ReadFile(char *name, byte **buffer) { FILE *handle; int count, length; byte *buf; handle = fopen(name, "rb"); if (handle == NULL) I_Error ("Couldn't read file %s", name); // find the size of the file by seeking to the end and // reading the current position length = M_FileLength(handle); buf = Z_Malloc (length, PU_STATIC, NULL); count = fread(buf, 1, length, handle); fclose (handle); if (count < length) I_Error ("Couldn't read file %s", name); *buffer = buf; return length; } // Returns the path to a temporary file of the given name, stored // inside the system temporary directory. // // The returned value must be freed with Z_Free after use. char *M_TempFile(char *s) { char *result; char *tempdir; #ifdef _WIN32 // Check the TEMP environment variable to find the location. tempdir = getenv("TEMP"); if (tempdir == NULL) { tempdir = "."; } #else // In Unix, just use /tmp. tempdir = "/tmp"; #endif result = Z_Malloc(strlen(tempdir) + strlen(s) + 2, PU_STATIC, 0); sprintf(result, "%s%c%s", tempdir, DIR_SEPARATOR, s); return result; } boolean M_StrToInt(const char *str, int *result) { return sscanf(str, " 0x%x", result) == 1 || sscanf(str, " 0X%x", result) == 1 || sscanf(str, " 0%o", result) == 1 || sscanf(str, " %d", result) == 1; } void M_ExtractFileBase(char *path, char *dest) { char *src; char *filename; int length; src = path + strlen(path) - 1; // back up until a \ or the start while (src != path && *(src - 1) != DIR_SEPARATOR) { src--; } filename = src; // Copy up to eight characters // Note: Vanilla Doom exits with an error if a filename is specified // with a base of more than eight characters. To remove the 8.3 // filename limit, instead we simply truncate the name. length = 0; memset(dest, 0, 8); while (*src != '\0' && *src != '.') { if (length >= 8) { printf("Warning: Truncated '%s' lump name to '%.8s'.\n", filename, dest); break; } dest[length++] = toupper((int)*src++); } } //--------------------------------------------------------------------------- // // PROC M_ForceUppercase // // Change string to uppercase. // //--------------------------------------------------------------------------- void M_ForceUppercase(char *text) { char *p; for (p = text; *p != '\0'; ++p) { *p = toupper(*p); } } // // M_StrCaseStr // // Case-insensitive version of strstr() // char *M_StrCaseStr(char *haystack, char *needle) { unsigned int haystack_len; unsigned int needle_len; unsigned int len; unsigned int i; haystack_len = strlen(haystack); needle_len = strlen(needle); if (haystack_len < needle_len) { return NULL; } len = haystack_len - needle_len; for (i = 0; i <= len; ++i) { if (!strncasecmp(haystack + i, needle, needle_len)) { return haystack + i; } } return NULL; } // // String replace function. // Returns a Z_Malloc()ed string. // char *M_StringReplace(char *haystack, char *needle, char *replacement) { char *result, *p, *dst; size_t needle_len = strlen(needle); int n; // Count number of occurrences of 'p': for (p = haystack, n = 0;; ++n) { p = strstr(p, needle); if (p == NULL) { break; } p += needle_len; } // Construct new string. result = Z_Malloc(strlen(haystack) + (strlen(replacement) - needle_len) * n + 1, PU_STATIC, NULL); dst = result; p = haystack; while (*p != '\0') { if (!strncmp(p, needle, needle_len)) { strcpy(dst, replacement); dst += strlen(replacement); p += needle_len; } else { *dst = *p; ++dst; ++p; } } *dst = '\0'; return result; } #ifdef _WIN32 char *M_OEMToUTF8(const char *oem) { unsigned int len = strlen(oem) + 1; wchar_t *tmp; char *result; tmp = malloc(len * sizeof(wchar_t)); MultiByteToWideChar(CP_OEMCP, 0, oem, len, tmp, len); result = malloc(len * 4); WideCharToMultiByte(CP_UTF8, 0, tmp, len, result, len * 4, NULL, NULL); free(tmp); return result; } #endif