#ifndef BUILTIN_H #define BUILTIN_H #include #include #include #include #include #include #include #include #include #include #include #include #include "strops.h" #include "graphics.h" #include "anyops.h" #if WINDOWS #include "color.hpp" #endif //#define DEVELOPER_MESSAGES false using namespace std; using namespace boost; vector types = { "int", "float", "string", "bool", "void", "null", "Sprite", "Vec2", "Text" }; //unordered_map>> builtinFunctionValues; //unordered_map builtinVarVals; // Foreground colors const std::string blackFGColor = "\x1B[30m"; const std::string redFGColor = "\x1B[31m"; const std::string greenFGColor = "\x1B[32m"; const std::string yellowFGColor = "\x1B[33m"; const std::string blueFGColor = "\x1B[34m"; const std::string magentaFGColor = "\x1B[35m"; const std::string cyanFGColor = "\x1B[36m"; const std::string whiteFGColor = "\x1B[37m"; const std::string brightBlackFGColor = "\x1B[90m"; const std::string brightRedFGColor = "\x1B[91m"; const std::string brightGreenFGColor = "\x1B[92m"; const std::string brightYellowFGColor = "\x1B[93m"; const std::string brightBlueFGColor = "\x1B[94m"; const std::string brightMagentaFGColor = "\x1B[95m"; const std::string brightCyanFGColor = "\x1B[96m"; const std::string brightWhiteFGColor = "\x1B[97m"; //Background colors const std::string blackBGColor = "\x1B[40m"; const std::string redBGColor = "\x1B[41m"; const std::string greenBGColor = "\x1B[42m"; const std::string yellowBGColor = "\x1B[43m"; const std::string blueBGColor = "\x1B[44m"; const std::string magentaBGColor = "\x1B[45m"; const std::string cyanBGColor = "\x1B[46m"; const std::string whiteBGColor = "\x1B[47m"; const std::string brightBlackBGColor = "\x1B[100m"; const std::string brightRedBGColor = "\x1B[101m"; const std::string brightGreenBGColor = "\x1B[102m"; const std::string brightYellowBGColor = "\x1B[103m"; const std::string brightBlueBGColor = "\x1B[104m"; const std::string brightMagentaBGColor = "\x1B[105m"; const std::string brightCyanBGColor = "\x1B[106m"; const std::string brightWhiteBGColor = "\x1B[107m"; // Reset color const std::string resetColor = "\033[0m"; class NullType { public: string type = "NULL"; }; class BREAK { public: string type = "BREAK"; }; boost::any nullType; boost::any breakReOp; float clamp(float v, float min, float max) { if (v < min) return min; if (v > max) return max; return v; } float lerp(float a, float b, float f) { return a + f * (b - a); } inline bool fileExists(const std::string& name) { struct stat buffer; return (stat(name.c_str(), &buffer) == 0); } void PrintColored(std::string text, std::string fgColor, std::string bgColor, bool isError) { #if WINDOWS if (fgColor == blackFGColor) cerr << hue::black; else if (fgColor == redFGColor) cerr << hue::red; else if (fgColor == greenFGColor) cerr << hue::green; else if (fgColor == yellowFGColor) cerr << hue::yellow; else if (fgColor == blueFGColor) cerr << hue::blue; else if (fgColor == magentaFGColor) cerr << hue::purple; else if (fgColor == cyanFGColor) cerr << hue::aqua; else if (fgColor == whiteFGColor) cerr << hue::white; if (bgColor == blackBGColor) cerr << hue::on_black; else if (bgColor == redBGColor) cerr << hue::on_red; else if (bgColor == greenBGColor) cerr << hue::on_green; else if (bgColor == yellowBGColor) cerr << hue::on_yellow; else if (bgColor == blueBGColor) cerr << hue::on_blue; else if (bgColor == magentaBGColor) cerr << hue::on_purple; else if (bgColor == cyanBGColor) cerr << hue::on_aqua; else if (bgColor == whiteBGColor) cerr << hue::on_white; std::cerr << text << hue::reset; #else if (!isError) cout << fgColor + bgColor + text + resetColor; else cerr << fgColor + bgColor + text + resetColor; #endif } int LogWarning(const string& warningText) { PrintColored("WARNING: ", yellowFGColor, "", true); PrintColored(escaped(warningText), yellowFGColor, "", true); cerr << std::endl; //cout << "\x1B[33mWARNING: " << warningText << "\033[0m\t\t" << endl; return 1; } int InterpreterLog(const string& logText) { int Hour = 0; int Min = 0; int Sec = 0; time_t timer = time(0); tm bt{}; #if UNIX time_t currentTime; struct tm* localTime; time(¤tTime); // Get the current time localTime = localtime(¤tTime); // Convert the current time to the local time Hour = localTime->tm_hour; Min = localTime->tm_min; Sec = localTime->tm_sec; #elif WINDOWS localtime_s(&bt, &timer); Hour = bt.tm_hour; Min = bt.tm_min; Sec = bt.tm_sec; #else static mutex mtx; std::lock_guard lock(mtx); bt = *localtime(&timer); #endif PrintColored("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true); PrintColored(escaped(logText), greenFGColor, "", true); cout << std::endl; //cout << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[32m" << logText << "\033[0m\t\t" << endl; return 1; } int LogCriticalError(const string& errorText) { int Hour = 0; int Min = 0; int Sec = 0; time_t timer = time(0); tm bt{}; #if UNIX time_t currentTime; struct tm* localTime; time(¤tTime); // Get the current time localTime = localtime(¤tTime); // Convert the current time to the local time Hour = localTime->tm_hour; Min = localTime->tm_min; Sec = localTime->tm_sec; #elif WINDOWS localtime_s(&bt, &timer); Hour = bt.tm_hour; Min = bt.tm_min; Sec = bt.tm_sec; #else static mutex mtx; std::lock_guard lock(mtx); bt = *localtime(&timer); #endif PrintColored("[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] ", blueFGColor, "", true); PrintColored("ZSharp: ", yellowFGColor, "", true); PrintColored(escaped(errorText), redFGColor, "", true); cerr << std::endl; InterpreterLog("Press Enter to Exit..."); cin.ignore(); exit(1); //cerr << "\x1B[34m[" + to_string(Hour) + ":" + to_string(Min) + ":" + to_string(Sec) + "] \x1B[33mZSharp: \x1B[31mERROR: " << errorText << "\033[0m\t\t" << endl; //exit(EXIT_FAILURE); return 2; } boost::any GetClassSubComponent(boost::any value, string subComponentName) { // If a Sprite Class if (any_type(value) == 4) { return any_cast(value).SubComponent(subComponentName); } // If a Vec2 Class if (any_type(value) == 5) { return any_cast(value).SubComponent(subComponentName); } // If a Text Class if (any_type(value) == 6) { return any_cast(value).SubComponent(subComponentName); } return nullType; } boost::any EditClassSubComponent(boost::any value, string oper, boost::any otherVal, string subComponentName) { // If a Sprite Class if (any_type(value) == 4) { Sprite v = any_cast(value); v.EditSubComponent(subComponentName, oper, otherVal); return v; } // If a Vec2 Class if (any_type(value) == 5) { Vec2 v = any_cast(value); v.EditSubComponent(subComponentName, oper, otherVal); return v; } // If a Text Class if (any_type(value) == 6) { Text t = any_cast(value); t.EditSubComponent(subComponentName, oper, otherVal); return t; } return nullType; } bool AxisAlignedCollision(const Sprite& a, const Sprite& b) // AABB - AABB collision { // collision x-axis? bool collisionX = a.position.x + a.scale.x / 2 >= b.position.x - b.scale.x / 2 && b.position.x + b.scale.x / 2 >= a.position.x - a.scale.x; // collision y-axis? bool collisionY = a.position.y + a.scale.y / 2 >= b.position.y - b.scale.y / 2 && b.position.y + b.scale.y / 2 >= a.position.y - a.scale.y / 2; //// collision x-axis? //bool collisionX = a.position.x - a.scale.x / 2 >= b.position.x + b.scale.x / 2 || // a.position.x + a.scale.x / 2 <= b.position.x - b.scale.x / 2; //// collision y-axis? //bool collisionY = a.position.y - a.scale.y / 2 >= b.position.y + b.scale.y / 2 || // a.position.y + a.scale.y / 2 <= b.position.y - b.scale.y / 2; // collision only if on both axes return collisionX && collisionY; } //// Initial script processing, which loads variables and functions from builtin //int GetBuiltins(std::string s) //{ // std::string script = replace(s, " ", "\t"); // // vector lines = split(script, '\n'); // vector> words; // for (int i = 0; i < (int)lines.size(); i++) // { // words.push_back(split(lines.at(i), ' ')); // } // // // Go through entire script and iterate through all types to see if line is a // // function declaration, then store it with it's value // for (int lineNum = 0; lineNum < (int)words.size(); lineNum++) // { // //Checks if it is function // if (words.at(lineNum).at(0) == "func") // { // vector> functionContents; // // string functName = split(words.at(lineNum).at(1), '(')[0]; // //#if DEVELOPER_MESSAGES == true // InterpreterLog("Load builtin function " + functName + "..."); //#endif // // string args = ""; // for (int w = 1; w < (int)words.at(lineNum).size(); w++) // Get all words from the instantiation line: these are the args // { // args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", ""); // } // // args = replace(args, functName + " ", ""); // functionContents.push_back(split(args, ',')); // // int numOfBrackets = 1; // for (int p = lineNum + 2; p < (int)words.size(); p++) // { // numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}"); // if (numOfBrackets == 0) // break; // functionContents.push_back(removeTabs(words.at(p), 1)); // } // builtinFunctionValues[functName] = functionContents; // //cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl; // } // else // { // if (words.at(lineNum).at(0) == "string") // { // builtinVarVals[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3)); //#if DEVELOPER_MESSAGES == true // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); //#endif // } // else if (words.at(lineNum).at(0) == "int") // { // builtinVarVals[words.at(lineNum).at(1)] = stoi(words.at(lineNum).at(3)); //#if DEVELOPER_MESSAGES == true // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); //#endif // } // else if (words.at(lineNum).at(0) == "float") // { // builtinVarVals[words.at(lineNum).at(1)] = stof(words.at(lineNum).at(3)); //#if DEVELOPER_MESSAGES == true // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); //#endif // } // else if (words.at(lineNum).at(0) == "bool") // { // builtinVarVals[words.at(lineNum).at(1)] = stob(words.at(lineNum).at(3)); //#if DEVELOPER_MESSAGES == true // InterpreterLog("Load builtin variable " + words.at(lineNum).at(1) + "..."); //#endif // } // //else // // LogWarning("unrecognized type \'" + words[lineNum][0] + "\' on line: " + to_string(lineNum)); // } // } // // return 0; //} // Executes boost::any ZSFunction(const string& name, const vector& args) { if (name == "ZS.Math.Sin") return sin(AnyAsFloat(args.at(0))); else if (name == "ZS.Math.Cos") return cos(AnyAsFloat(args.at(0))); else if (name == "ZS.Math.Tan") return tan(AnyAsFloat(args.at(0))); else if (name == "ZS.Math.Round") return AnyAsInt(args.at(0)); else if (name == "ZS.Math.Lerp") return lerp(AnyAsFloat(args.at(0)), AnyAsFloat(args.at(1)), AnyAsFloat(args.at(2))); else if (name == "ZS.Math.Abs") return abs(AnyAsFloat(args.at(0))); else if (name == "ZS.Graphics.Init") { #if DEVELOPER_MESSAGES == true InterpreterLog("Init graphics"); #endif if (args.size() <= 3) initGraphics(StringRaw(AnyAsString(args.at(0))), AnyAsInt(args.at(1)), AnyAsInt(args.at(2)), 1); else initGraphics(StringRaw(AnyAsString(args.at(0))), AnyAsInt(args.at(1)), AnyAsInt(args.at(2)), AnyAsInt(args.at(3))); } else if (name == "ZS.Graphics.Sprite") { if (!fileExists(StringRaw(AnyAsString(args.at(0))))) LogCriticalError("Failed to create 'Sprite' object: \"" + StringRaw(AnyAsString(args.at(0))) + "\""); Sprite s(StringRaw(AnyAsString(args.at(0))), any_cast(args.at(1)), any_cast(args.at(2)), AnyAsFloat(args.at(3))); return s; } else if (name == "ZS.Graphics.Draw") any_cast(args.at(0)).Draw(); else if (name == "ZS.Graphics.Load") any_cast(args.at(0)).Load(); else if (name == "ZS.Graphics.Text") { if (!fileExists(StringRaw(AnyAsString(args.at(1))))) LogCriticalError("Failed to create 'Text' object: \"" + StringRaw(AnyAsString(args.at(1))) + "\""); if (args.size() <= 8) { Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast(args.at(2)), AnyAsFloat(args.at(3)), AnyAsFloat(args.at(4)), (Uint8)AnyAsFloat(args.at(5)), (Uint8)AnyAsFloat(args.at(6)), (Uint8)AnyAsFloat(args.at(7)), true); return t; } else { Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast(args.at(2)), AnyAsFloat(args.at(3)), AnyAsFloat(args.at(4)), (Uint8)AnyAsFloat(args.at(5)), (Uint8)AnyAsFloat(args.at(6)), (Uint8)AnyAsFloat(args.at(7)), AnyAsBool(args.at(8))); return t; } } else if (name == "ZS.Graphics.DrawText") any_cast(args.at(0)).Draw(); else if (name == "ZS.Graphics.LoadText") any_cast(args.at(0)).Load(); else if (name == "ZS.Physics.AxisAlignedCollision") { return AxisAlignedCollision(any_cast(args.at(0)), any_cast(args.at(1))); } else if (name == "ZS.Input.GetKey") return KEYS[StringRaw(any_cast(args.at(0)))] == 1; else if (name == "ZS.System.Print") cout << StringRaw(AnyAsString(args.at(0))) << StringRaw(AnyAsString(args.at(0))).length(); else if (name == "ZS.System.PrintLine") cout << StringRaw(AnyAsString(args.at(0))) << StringRaw(AnyAsString(args.at(0))).length() << endl; else if (name == "ZS.System.Vec2") { Vec2 v(AnyAsFloat(args.at(0)), AnyAsFloat(args.at(1))); return v; } else LogWarning("ZS function \'" + name + "\' does not exist."); return nullType; } #endif