/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* * This file is based on WME Lite. * http://dead-code.org/redir.php?target=wmelite * Copyright (c) 2011 Jan Nedoma */ #include "engines/wintermute/dcgf.h" #include "utils.h" #include "engines/wintermute/PlatformSDL.h" #include "engines/wintermute/wintypes.h" #include "PathUtil.h" #include "engines/wintermute/Base/BGame.h" #include "common/str.h" #include "common/textconsole.h" #include "engines/wintermute/wintermute.h" namespace WinterMute { ////////////////////////////////////////////////////////////////////// static inline unsigned Sqr(int x) { return (x * x); } ////////////////////////////////////////////////////////////////////////////////// void CBUtils::Clip(int *DestX, int *DestY, RECT *SrcRect, RECT *DestRect) { // If it's partly off the right side of the screen if (*DestX + (SrcRect->right - SrcRect->left) > DestRect->right) SrcRect->right -= *DestX + (SrcRect->right - SrcRect->left) - DestRect->right; if (SrcRect->right < 0) SrcRect->right = 0; // Partly off the left side of the screen if (*DestX < DestRect->left) { SrcRect->left += DestRect->left - *DestX; *DestX = DestRect->left; } // Partly off the top of the screen if (*DestY < DestRect->top) { SrcRect->top += DestRect->top - *DestY; *DestY = DestRect->top; } // If it's partly off the bottom side of the screen if (*DestY + (SrcRect->bottom - SrcRect->top) > DestRect->bottom) SrcRect->bottom -= ((SrcRect->bottom - SrcRect->top) + *DestY) - DestRect->bottom; if (SrcRect->bottom < 0) SrcRect->bottom = 0; return; } ////////////////////////////////////////////////////////////////////////////////// // Swap - swaps two integers ////////////////////////////////////////////////////////////////////////////////// void CBUtils::Swap(int *a, int *b) { int Temp = *a; *a = *b; *b = Temp; } ////////////////////////////////////////////////////////////////////////// bool CBUtils::StrBeginsI(const char *String, const char *Fragment) { return (scumm_strnicmp(String, Fragment, strlen(Fragment)) == 0); } ////////////////////////////////////////////////////////////////////////// float CBUtils::NormalizeAngle(float Angle) { while (Angle > 360) Angle -= 360; while (Angle < 0) Angle += 360; return Angle; } //////////////////////////////////////////////////////////////////////////////// void CBUtils::CreatePath(const char *Path, bool PathOnly) { AnsiString path; if (!PathOnly) path = PathUtil::GetDirectoryName(Path); else path = Path; // try { warning("CBUtils::CreatePath - not implemented: %s", Path); // boost::filesystem::create_directories(path); // } catch (...) { return; // } } ////////////////////////////////////////////////////////////////////////// void CBUtils::DebugMessage(HWND hWnd, const char *Text) { //MessageBox(hWnd, Text, "WME", MB_OK|MB_ICONINFORMATION); } ////////////////////////////////////////////////////////////////////////// char *CBUtils::SetString(char **string, const char *value) { delete[] *string; *string = new char[strlen(value) + 1]; if (*string) strcpy(*string, value); return *string; } ////////////////////////////////////////////////////////////////////////// int CBUtils::StrNumEntries(const char *Str, const char Delim) { int NumEntries = 1; for (uint32 i = 0; i < strlen(Str); i++) { if (Str[i] == Delim) NumEntries++; } return NumEntries; } ////////////////////////////////////////////////////////////////////////// char *CBUtils::StrEntry(int Entry, const char *Str, const char Delim) { int NumEntries = 0; const char *Start = NULL; int Len = 0; for (uint32 i = 0; i <= strlen(Str); i++) { if (NumEntries == Entry) { if (!Start) Start = Str + i; else Len++; } if (Str[i] == Delim || Str[i] == '\0') { NumEntries++; if (Start) { char *Ret = new char[Len + 1]; memset(Ret, 0, Len + 1); strncpy(Ret, Start, Len); return Ret; } } } return NULL; } ////////////////////////////////////////////////////////////////////////// int CBUtils::RandomInt(int from, int to) { if (to < from) { int i = to; to = from; from = i; } return g_wintermute->randInt(from, to); // return (rand() % (to - from + 1)) + from; } ////////////////////////////////////////////////////////////////////////// float CBUtils::RandomFloat(float from, float to) { const uint32 randMax = RAND_MAX; float randNum = (float)g_wintermute->randInt(0, randMax) / (float)randMax; return from + (to - from) * randNum; } ////////////////////////////////////////////////////////////////////////// float CBUtils::RandomAngle(float From, float To) { while (To < From) { To += 360; } return NormalizeAngle(RandomFloat(From, To)); } ////////////////////////////////////////////////////////////////////////// bool CBUtils::MatchesPattern(const char *Pattern, const char *String) { char stringc, patternc; for (;; ++String) { stringc = toupper(*String); patternc = toupper(*Pattern++); switch (patternc) { case 0: return (stringc == 0); case '?': if (stringc == 0) return false; break; case '*': if (!*Pattern) return true; if (*Pattern == '.') { char *dot; if (Pattern[1] == '*' && Pattern[2] == 0) return true; dot = (char *)strchr(String, '.'); if (Pattern[1] == 0) return (dot == NULL || dot[1] == 0); if (dot != NULL) { String = dot; if (strpbrk(Pattern, "*?[") == NULL && strchr(String + 1, '.') == NULL) return(scumm_stricmp(Pattern + 1, String + 1) == 0); } } while (*String) if (CBUtils::MatchesPattern(Pattern, String++)) return true; return false; default: if (patternc != stringc) if (patternc == '.' && stringc == 0) return(CBUtils::MatchesPattern(Pattern, String)); else return false; break; } } } ////////////////////////////////////////////////////////////////////////// char *CBUtils::GetPath(const char *Filename) { AnsiString path = PathUtil::GetDirectoryName(Filename); //path = boost::filesystem::syste_complete(path).string(); warning("CBUtils::GetPath: (%s), not implemented", Filename); char *ret = new char[path.size() + 1]; strcpy(ret, path.c_str()); return ret; } ////////////////////////////////////////////////////////////////////////// char *CBUtils::GetFilename(const char *Filename) { AnsiString path = PathUtil::GetFileName(Filename); char *ret = new char[path.size() + 1]; strcpy(ret, path.c_str()); return ret; } ////////////////////////////////////////////////////////////////////////// void CBUtils::RGBtoHSL(uint32 RGBColor, byte *OutH, byte *OutS, byte *OutL) { float var_R = (D3DCOLGetR(RGBColor) / 255.0f); float var_G = (D3DCOLGetG(RGBColor) / 255.0f); float var_B = (D3DCOLGetB(RGBColor) / 255.0f); //Min. value of RGB float var_Min = MIN(var_R, var_G); var_Min = MIN(var_Min, var_B); //Max. value of RGB float var_Max = MAX(var_R, var_G); var_Max = MAX(var_Max, var_B); //Delta RGB value float del_Max = var_Max - var_Min; float H = 0.0f, S = 0.0f, L = 0.0f; L = (var_Max + var_Min) / 2.0f; //This is a gray, no chroma... if (del_Max == 0) { H = 0; S = 0; } //Chromatic data... else { if (L < 0.5f) S = del_Max / (var_Max + var_Min); else S = del_Max / (2.0f - var_Max - var_Min); float del_R = (((var_Max - var_R) / 6.0f) + (del_Max / 2.0f)) / del_Max; float del_G = (((var_Max - var_G) / 6.0f) + (del_Max / 2.0f)) / del_Max; float del_B = (((var_Max - var_B) / 6.0f) + (del_Max / 2.0f)) / del_Max; if (var_R == var_Max) H = del_B - del_G; else if (var_G == var_Max) H = (1.0f / 3.0f) + del_R - del_B; else if (var_B == var_Max) H = (2.0f / 3.0f) + del_G - del_R; if (H < 0) H += 1; if (H > 1) H -= 1; } *OutH = (byte)(H * 255); *OutS = (byte)(S * 255); *OutL = (byte)(L * 255); } ////////////////////////////////////////////////////////////////////////// uint32 CBUtils::HSLtoRGB(byte InH, byte InS, byte InL) { float H = InH / 255.0f; float S = InS / 255.0f; float L = InL / 255.0f; byte R, G, B; if (S == 0) { R = (byte)(L * 255); G = (byte)(L * 255); B = (byte)(L * 255); } else { float var_1, var_2; if (L < 0.5) var_2 = L * (1.0 + S); else var_2 = (L + S) - (S * L); var_1 = 2.0f * L - var_2; R = (byte)(255 * Hue2RGB(var_1, var_2, H + (1.0f / 3.0f))); G = (byte)(255 * Hue2RGB(var_1, var_2, H)); B = (byte)(255 * Hue2RGB(var_1, var_2, H - (1.0f / 3.0f))); } return DRGBA(255, R, G, B); } ////////////////////////////////////////////////////////////////////////// float CBUtils::Hue2RGB(float v1, float v2, float vH) { if (vH < 0.0f) vH += 1.0f; if (vH > 1.0f) vH -= 1.0f; if ((6.0f * vH) < 1.0f) return (v1 + (v2 - v1) * 6.0f * vH); if ((2.0f * vH) < 1.0f) return (v2); if ((3.0f * vH) < 2.0f) return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f); return (v1); } } // end of namespace WinterMute