Merge dev Feature additions

* Allow for curly brackets on the same line as if statements and while loops (you need a space between the argument and bracket ex. `if 1 == 1 {`)
* Scaling sprites
* Different window scaling options, provided as an extra argument in ZS.Graphics.Init `ZS.Graphics.Init("Title of window", screenWidth, screenHeight, scalingAmount)`
* You can now use `include` to use the functions and variables from another Z# file inside of your script. use like so: `include "./path/to/script.zs"`
This commit is contained in:
sam-astro 2022-05-24 18:21:35 -04:00 committed by GitHub
commit b6eba24fbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 450 additions and 122 deletions

View File

@ -23,6 +23,7 @@
#include <unordered_map>
#include <stdio.h>
#include <codecvt>
#include <thread>
#if UNIX
#include <unistd.h>
@ -139,31 +140,36 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
// If no operations are applied, then return self
if ((countOutsideParenthesis(expression, '+') == 0 && countOutsideParenthesis(expression, '-') == 0 && countOutsideParenthesis(expression, '*') == 0 && countOutsideParenthesis(expression, '/') == 0 && countOutsideParenthesis(expression, '^') == 0) || split(expression, '.')[0] == "ZS")
{
bool isFunc = IsFunction(split(expression, '(')[0]);
//bool isFunc = IsFunction(split(expression, '(')[0]);
if (isFunc && !inQuotes)
{
//cout << split(expression, '(')[0] << endl;
string argContents = "";
int y = indexInStr(expression, '(') + 1;
while (y < expression.size() && expression[y] != ')')
{
argContents += expression[y];
y++;
}
return ExecuteFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues));
// start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true
cout << "[" << unWrapVec(argList) << "]" << endl;
#endif
vector<boost::any> funcArgs = VarValues(argList, variableValues);
return ExecuteFunction(trim(split(expression, '(')[0]), funcArgs);
}
else if (split(expression, '.')[0] == "ZS" && !inQuotes)
else if (isZS && !inQuotes)
{
string argContents = "";
int y = indexInStr(expression, '(') + 1;
while (y < expression.size() && expression[y] != ')')
{
argContents += expression[y];
y++;
}
return ZSFunction(split(expression, '(')[0], VarValues(split(argContents, ','), variableValues));
// start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true
cout << "[" << unWrapVec(argList) << "]" << endl;
#endif
vector<boost::any> funcArgs = VarValues(argList, variableValues);
return ZSFunction(trim(split(expression, '(')[0]), funcArgs);
}
else
return GetVariableValue(expression, variableValues);
@ -177,11 +183,11 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
if (expression[i] == '\"' && !isEscaped(newExpression, i))
inQuotes = !inQuotes;
if (isalpha(expression[i]))
if (isalpha(expression[i]) || expression[i] == '_')
{
string name = "";
while (i < expression.size() && (isalpha(expression[i]) || expression[i] == '.'))
while (i < expression.size() && (isalpha(expression[i]) || expression[i] == '.' || expression[i] == '_'))
{
name += expression[i];
i++;
@ -191,29 +197,34 @@ boost::any EvalExpression(const string& ex, unordered_map<string, boost::any>& v
bool isFunc = IsFunction(name);
if (isFunc && !inQuotes)
{
string argContents = "";
i++;
while (i < expression.size() && expression[i] != ')')
{
argContents += expression[i];
i++;
}
string returnVal = AnyAsString(ExecuteFunction(name, VarValues(split(argContents, ','), variableValues)));
// start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true
cout << unWrapVec(argList) << endl;
#endif
vector<boost::any> funcArgs = VarValues(argList, variableValues);
string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs));
newExpression += returnVal;
}
else if (split(name, '.')[0] == "ZS" && !inQuotes)
{
string argContents = "";
int y = indexInStr(expression, '(') + 1;
while (y < expression.size() && expression[y] != ')')
{
argContents += expression[y];
y++;
}
//cout << split(expression, '(')[0] << " " << argContents << endl;
string returnVal = AnyAsString(ZSFunction(split(name, '(')[0], VarValues(split(argContents, ','), variableValues)));
// start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(expression, '(', ')');
#if DEVELOPER_MESSAGES == true
cout << insideFunArgs << endl;
#endif
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
#if DEVELOPER_MESSAGES == true
cout << unWrapVec(argList) << endl;
#endif
vector<boost::any> funcArgs = VarValues(argList, variableValues);
string returnVal = AnyAsString(ExecuteFunction(trim(split(expression, '(')[0]), funcArgs));
newExpression += returnVal;
}
else
@ -371,7 +382,7 @@ int varOperation(const vector<string>& str, unordered_map<string, boost::any>& v
return 1;
}
boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unordered_map<string, boost::any>& variableValues)
boost::any ProcessLine(const vector<vector<string>>& words, int& lineNum, unordered_map<string, boost::any>& variableValues)
{
// Check if the first two chars are '//', which would make it a comment
if (words.at(lineNum).at(0)[0] == '/' && words.at(lineNum).at(0)[1] == '/')
@ -395,10 +406,34 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
// Check if it is function
else if (IsFunction(trim(split(words.at(lineNum).at(0), '(')[0])))
{
// No args provided
if (count(words.at(lineNum).at(0), '(') > 0 && count(words.at(lineNum).at(0), ')') > 0)
ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), vector<boost::any>());
else
ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), VarValues(split(RMParenthesis("(" + split(unWrapVec(rangeInVec(words.at(lineNum), 0, (int)words.at(lineNum).size() - 1)), '(')[1]), ','), variableValues));
{ // Args provided, parse them first
// start -> FuncCall(0, x, OtherFunc(a))
// changeto -> 0, x, OtherFunc(a)
string insideFunArgs = betweenChars(unWrapVec(words.at(lineNum)), '(', ')');
vector<string> argList = splitNoOverlap(insideFunArgs, ',', '(', ')');
vector<boost::any> funcArgs = VarValues(argList, variableValues);
ExecuteFunction(trim(split(words.at(lineNum).at(0), '(')[0]), funcArgs);
}
return nullType;
}
// Check if it is a SplitThread call
else if (startsWith(words.at(lineNum).at(0), "SplitThread"))
{
vector<string> lineContents = removeTabs(words.at(lineNum), 10);
cout << "New Thread: " << words.at(lineNum).at(0) << endl;
//lineContents.at(0) = betweenChars(lineContents.at(0), '(', ')');
//cout << "debug: " << lineContents.at(0) << endl;
//if (betweenChars(lineContents.at(0), '(', ')') == "")
// std::thread thread_obj(ExecuteFunction, trim(split(lineContents.at(0), '(')[0]), vector<boost::any>());
//else
// std::thread thread_obj(ExecuteFunction, trim(split(lineContents.at(0), '(')[0]), VarValues(split(RMParenthesis("(" + split(unWrapVec(rangeInVec(lineContents, 0, (int)lineContents.size() - 2)), '(')[1]), ','), variableValues));
return nullType;
}
@ -413,6 +448,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
// re-inits a variable then store it with it's value
else if (countInVector(types, trim(words.at(lineNum).at(0))) > 0)
{
//cout << words.at(lineNum).at(1) << "=" << unWrapVec(slice(words.at(lineNum), 3, -1)) << "=" << AnyAsString(EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues)) << endl;
variableValues[words.at(lineNum).at(1)] = EvalExpression(unWrapVec(slice(words.at(lineNum), 3, -1)), variableValues);
return nullType;
}
@ -426,7 +462,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
return nullType;
}
// Check existing variables: To see if accessign class sub component
// Check existing variables: To see if accessing class sub component
else if (count(words.at(lineNum).at(0), '.') > 0 && IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues) || IsVar(split(words.at(lineNum).at(0), '.')[0], globalVariableValues))
{
if (IsVar(split(words.at(lineNum).at(0), '.')[0], variableValues))
@ -442,17 +478,28 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
vector<vector<string>> whileContents;
vector<string> whileParameters;
for (int w = 1; w < (int)words.at(lineNum).size(); w++)
whileParameters.push_back(words.at(lineNum)[w]);
int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') == 0)
whileParameters.push_back(words.at(lineNum)[w]);
else
{
whileParameters.push_back(replace(words.at(lineNum)[w], "{", ""));
numOfBrackets = 1;
break;
}
}
int numOfBrackets = 1;
for (int p = lineNum + 2; p < (int)words.size(); p++)
lineNum += 1;
while (lineNum < (int)words.size())
{
numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}");
numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}");
if (numOfBrackets == 0)
break;
whileContents.push_back(words.at(p));
whileContents.push_back(words.at(lineNum));
lineNum++;
}
whileContents = removeTabsWdArry(whileContents, 1);
while (BooleanLogic(whileParameters.at(0), whileParameters.at(1), whileParameters.at(2), variableValues))
@ -474,11 +521,19 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
vector<vector<string>> ifContents;
vector<string> ifParameters;
for (int w = 1; w < (int)words.at(lineNum).size(); w++)
ifParameters.push_back(words.at(lineNum).at(w));
int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') == 0)
ifParameters.push_back(words.at(lineNum)[w]);
else
{
ifParameters.push_back(replace(words.at(lineNum)[w], "{", ""));
numOfBrackets = 1;
break;
}
}
int numOfBrackets = 1;
lineNum += 2;
lineNum++;
while (lineNum < (int)words.size())
{
numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}");
@ -487,6 +542,7 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
ifContents.push_back(words.at(lineNum));
lineNum++;
}
ifContents = removeTabsWdArry(ifContents, 1);
if (BooleanLogic(ifParameters.at(0), ifParameters.at(1), ifParameters.at(2), variableValues))
@ -499,39 +555,44 @@ boost::any ProcessLine(const vector<vector<string>>& words, int lineNum, unorder
return returnVal;
}
}
//else if (words.size() > lineNum + 1)
// if (words[lineNum + 1][0] == "else")
// {
// lineNum += 1;
else if (words.size() > lineNum + 1)
{
if (words[lineNum + 1].at(0) == "else")
{
vector<vector<string>> elseContents;
vector<string> elseParameters;
// vector<string> elseContents;
int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') != 0)
{
numOfBrackets = 1;
break;
}
}
// int numOfBrackets = 1;
// while (lineNum < (int)words.size())
// {
// numOfBrackets += countInVector(words[lineNum], "{") - countInVector(words[lineNum], "}");
// if (numOfBrackets == 0)
// break;
// elseContents.push_back("");
// for (int w = 0; w < (int)words[lineNum].size(); w++)
// {
// elseContents[(int)elseContents.size() - 1] += words[lineNum][w] + " ";
// }
// lineNum++;
// }
// elseContents = removeTabs(elseContents, 2);
lineNum++;
while (lineNum < (int)words.size())
{
numOfBrackets += countInVector(words.at(lineNum), "{") - countInVector(words.at(lineNum), "}");
if (numOfBrackets == 0)
break;
elseContents.push_back(words.at(lineNum));
lineNum++;
}
// vector<vector<string>> innerWords;
// for (int i = 0; i < (int)elseContents.size(); i++)
// innerWords.push_back(split(elseContents[i], ' '));
elseContents = removeTabsWdArry(elseContents, 1);
// //Iterate through all lines in else statement
// for (int lineNum = 0; lineNum < (int)elseContents.size(); lineNum++)
// {
// ProcessLine(innerWords, lineNum, variableValues);
// }
// return nullType;
// }
//Iterate through all lines in if statement
for (int l = 0; l < (int)elseContents.size(); l++)
{
boost::any returnVal = ProcessLine(elseContents, l, variableValues);
if (!returnVal.empty())
return returnVal;
}
}
}
return nullType;
}
//// Gathers else statement contents
@ -582,7 +643,7 @@ boost::any ExecuteFunction(const string& functionName, const vector<boost::any>&
int parseZSharp(string script)
{
script = replace(script, " ", "\t"); // Replace spaces with tabs (not really required, and will break purposefull whitespace in strings etc.)
#if DEVELOPER_MESSAGES
#if DEVELOPER_MESSAGES
InterpreterLog("Contents:\n" + script);
#endif
@ -613,14 +674,22 @@ int parseZSharp(string script)
if (indexInStr(unWrapVec(words.at(lineNum)), ')') - indexInStr(unWrapVec(words.at(lineNum)), '(') > 1)
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), "(", " "), ")", "");
if (count(words.at(lineNum).at(w), '{') == 0)
args += replace(replace(words.at(lineNum).at(w), "(", " "), ")", "");
}
args = trim(replace(args, functName + " ", ""));
functionContents.push_back(split(args, ','));
int numOfBrackets = 1;
for (int p = lineNum + 2; p < (int)words.size(); p++)
int numOfBrackets = 0;
for (int w = 1; w < (int)words.at(lineNum).size(); w++) {
if (count(words.at(lineNum).at(w), '{') != 0) {
numOfBrackets = 1;
break;
}
}
for (int p = lineNum + 1; p < (int)words.size(); p++)
{
numOfBrackets += countInVector(words.at(p), "{") - countInVector(words.at(p), "}");
if (numOfBrackets == 0)
@ -631,7 +700,37 @@ int parseZSharp(string script)
}
else
{
if (words.at(lineNum).at(0) == "string") {
if (words.at(lineNum).at(0) == "include")
{
string scriptPath = StringRaw(words.at(lineNum).at(1));
string scriptTextContents;
#if DEVELOPER_MESSAGES == true
InterpreterLog("Including from " + words.at(lineNum).at(1) + "...");
#endif
#if UNIX
// Get script contents as single string
auto ss = ostringstream{};
ifstream input_file(scriptPath);
ss << input_file.rdbuf();
scriptTextContents = ss.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#elif WINDOWS
// Get script contents as single string
ifstream script(scriptPath);
stringstream scriptString;
scriptString << script.rdbuf();
scriptTextContents = scriptString.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
parseZSharp(scriptTextContents);
}
else if (words.at(lineNum).at(0) == "string") {
globalVariableValues[words.at(lineNum).at(1)] = StringRaw(words.at(lineNum).at(3));
#if DEVELOPER_MESSAGES == true
InterpreterLog("Load script variable " + words.at(lineNum).at(1) + "...");
@ -660,12 +759,6 @@ int parseZSharp(string script)
}
}
#if DEVELOPER_MESSAGES
InterpreterLog("Start Main()");
#endif
// Executes main, which is the entry point function
ExecuteFunction("Main", vector<boost::any> {});
return 0;
}
@ -693,6 +786,8 @@ int main(int argc, char* argv[])
#if DEVELOPER_MESSAGES
cout << scriptPath << endl;
#endif
if (!fileExists(scriptPath))
LogCriticalError("Failed to load script from path: \"" + scriptPath + "\"");
std::string projectDirectory = scriptPath.substr(0, scriptPath.find_last_of("/\\"));
#if UNIX
@ -703,16 +798,17 @@ int main(int argc, char* argv[])
scriptTextContents = ss.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
// Change the current working directory to that of the script
chdir(projectDirectory.c_str());
int chErr = chdir(projectDirectory.c_str());
if (chErr < 0)
LogCriticalError("Failed to change directory to: \"" + projectDirectory.c_str() + "\", error num: " + chErr);
#if DEVELOPER_MESSAGES
InterpreterLog("Change directory to " + projectDirectory + "...");
InterpreterLog("Changed directory to " + projectDirectory + "...");
#endif
#if DEVELOPER_MESSAGES
string newPath = filesystem::current_path();
InterpreterLog("Current working directory is " + newPath);
#endif
#elif WINDOWS
// Get script contents as single string
@ -722,15 +818,15 @@ int main(int argc, char* argv[])
scriptTextContents = scriptString.str();
#if DEVELOPER_MESSAGES
InterpreterLog("Gather script contents...");
#endif
#endif
// Change the current working directory to that of the script
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes(projectDirectory);
LPCWSTR s = wide.c_str();
SetCurrentDirectory(s);
#if DEVELOPER_MESSAGES
InterpreterLog("Change directory to " + projectDirectory + "...");
InterpreterLog("Changed directory to " + projectDirectory + "...");
#endif
#endif
}
@ -742,30 +838,41 @@ int main(int argc, char* argv[])
exit(1);
}
#if DEVELOPER_MESSAGES
#if DEVELOPER_MESSAGES
InterpreterLog("Parsing...");
#endif
// Start running the script
#endif
// Parse the script
parseZSharp(scriptTextContents);
#if DEVELOPER_MESSAGES
InterpreterLog("Start Main()");
#endif
try
{
// Executes main, which is the entry point function
ExecuteFunction("Main", vector<boost::any> {});
}
catch (const std::exception&)
{
//Failed with error
}
// Entire script has been run, exit.
#if DEVELOPER_MESSAGES // If built with developer messages, then verify exit
cout << "Press Enter to Continue";
cin.ignore();
exit(1);
#else
if(argc > 2)
if (argc > 2)
{
string a = argv[2];
std::transform(a.begin(), a.end(), a.begin(),
[](unsigned char c){ return std::tolower(c); });
if(a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit
[](unsigned char c) { return std::tolower(c); });
if (a == "-ve") // If the '-ve' (verify exit) option is used, ask for verification on exit
{
cout << "Press Enter to Continue";
cin.ignore();
exit(1);
exit(1);
}
}
#endif // Else exit automatically

View File

@ -137,5 +137,10 @@ func GetKey(keyName)
bool b = ZS.Input.GetKey(keyName)
return b
}
//func SplitThread(function)
//{
// ZS.System.SplitThread(function)
//}
)"
;

View File

@ -12,6 +12,7 @@
#include <SDL.h>
#include <ctime>
#include <math.h>
#include <sys/stat.h>
#include "strops.h"
#include "graphics.h"
@ -86,6 +87,10 @@ 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)
{
@ -197,8 +202,11 @@ int LogCriticalError(const string& errorText)
PrintColored("ZSharp: ", yellowFGColor, "", true);
PrintColored(errorText, redFGColor, "", true);
cerr << std::endl;
cout << "Press Enter to Continue";
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);
//exit(EXIT_FAILURE);
return 2;
}
@ -314,7 +322,7 @@ int GetBuiltins(std::string s)
}
builtinFunctionValues[functName] = functionContents;
//cout << functName << " is \n" << Vec2Str(functionContents) << endl << endl;
}
}
else
{
if (words.at(lineNum).at(0) == "string")
@ -351,7 +359,7 @@ int GetBuiltins(std::string s)
}
return 0;
}
}
// Executes
boost::any ZSFunction(const string& name, const vector<boost::any>& args)
@ -373,10 +381,16 @@ boost::any ZSFunction(const string& name, const vector<boost::any>& args)
#if DEVELOPER_MESSAGES == true
InterpreterLog("Init graphics");
#endif
initGraphics(StringRaw(AnyAsString(args.at(0))), AnyAsInt(args.at(1)), AnyAsInt(args.at(2)));
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<Vec2>(args.at(1)), any_cast<Vec2>(args.at(2)), AnyAsFloat(args.at(3)));
return s;
}
@ -386,6 +400,9 @@ boost::any ZSFunction(const string& name, const vector<boost::any>& args)
any_cast<Sprite>(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))) + "\"");
Text t(StringRaw(AnyAsString(args.at(0))), StringRaw(AnyAsString(args.at(1))), any_cast<Vec2>(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)));
return t;
}

View File

@ -26,6 +26,7 @@ using namespace boost;
int WINDOW_WIDTH = 1280;
int WINDOW_HEIGHT = 720;
int PIXEL_SCALE = 1;
unordered_map<string, int> KEYS =
{
@ -191,7 +192,7 @@ public:
{
x *= rhs;
y *= rhs;
return *this;
}
@ -391,6 +392,8 @@ public:
{
SDL_RenderCopy(gRenderer, texture, NULL, &rect);
// Centers
rect.w = scale.x;
rect.h = scale.y;
rect.x = position.x - (rect.w / 2);
rect.y = position.y - (rect.h / 2);
return 0;
@ -501,6 +504,8 @@ public:
scale.y /= AnyAsFloat(otherVal);
}
// Centers
rect.w = scale.x;
rect.h = scale.y;
rect.x = position.x - (rect.w / 2);
rect.y = position.y - (rect.h / 2);
return *this;
@ -523,7 +528,7 @@ public:
{
rect.x = position.x;
rect.y = position.y;
font = TTF_OpenFont(pathToFont.c_str(), fontSize);
Load();
@ -1017,17 +1022,21 @@ int updateLoop()
return 0;
}
int initGraphics(std::string windowTitle, int width, int height)
int initGraphics(std::string windowTitle, int width, int height, int pixelScale)
{
WINDOW_WIDTH = width;
WINDOW_HEIGHT = height;
PIXEL_SCALE = pixelScale;
// Initialize SDL components
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
gWindow = SDL_CreateWindow(windowTitle.c_str(), 40, 40, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
gWindow = SDL_CreateWindow(windowTitle.c_str(), 40, 40, WINDOW_WIDTH * PIXEL_SCALE, WINDOW_HEIGHT * PIXEL_SCALE, SDL_WINDOW_SHOWN | SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
SDL_RenderSetLogicalSize(gRenderer, WINDOW_WIDTH * PIXEL_SCALE, WINDOW_HEIGHT * PIXEL_SCALE);
SDL_RenderSetScale(gRenderer, PIXEL_SCALE, PIXEL_SCALE);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0);
//Get window surface
gScreenSurface = SDL_GetWindowSurface(gWindow);

View File

@ -150,6 +150,76 @@ int countNoOverlap(const string& str, const char& searchFor, const char& ch1, co
return cnt;
}
vector<string> splitNoOverlap(const string& str, const char& splitBy, const char& openChar, const char& closeChar)
{
vector<string> newStr;
int openCount = 0;
string tmpStr = "";
for (int i = 0; i < (int)str.size(); i++)
{
if (i == (int)str.size() - 1)
{
newStr.push_back(trim(tmpStr + str[i]));
break;
}
if (str[i] == splitBy && openCount == 0)
{
newStr.push_back(trim(tmpStr));
tmpStr = "";
continue;
}
else if (str[i] == openChar) {
tmpStr += str[i];
openCount += 1;
}
else if (str[i] == closeChar) {
tmpStr += str[i];
openCount -= 1;
}
else
tmpStr += str[i];
}
return newStr;
}
string betweenChars(const string& str, const char& openChar, const char& closeChar)
{
string content = "";
int waitingForClose = 0;
for (int i = 0; i < (int)str.size(); i++)
{
if (waitingForClose > 0 && !(str[i] == closeChar && waitingForClose == 1))
content += str[i];
if (str[i] == openChar)
waitingForClose++;
else if (str[i] == closeChar)
waitingForClose--;
}
return content;
}
bool startsWith(const string& str, const string& lookFor)
{
if (str.empty() || lookFor.size() > str.size())
return false;
for (int i = 0; i < (int)lookFor.size(); i++)
{
if (str[i] != lookFor[i])
return false;
}
return true;
}
int countOutsideParenthesis(const string& str, const char& searchFor)
{
int cnt = 0;
@ -350,4 +420,4 @@ bool isEscaped(const string& str, int curChar)
return true;
return false;
}
}

View File

@ -34,6 +34,8 @@ int count(const string& str, const char& ch);
int countNoOverlap(const string& str, const char& searchFor, const char& ch1, const char& ch2);
string betweenChars(const string& str, const char& openChar, const char& closeChar);
int countOutsideParenthesis(const string& str, const char& searchFor);
int indexInStr(const string& str, const char& ch);
@ -62,4 +64,8 @@ string replace(const string& str, const string& strToReplace, const string& repl
bool isEscaped(const string& str, int curChar);
bool startsWith(const string& str, const string& lookFor);
vector<string> splitNoOverlap(const string& str, const char& splitBy, const char& openChar, const char& closeChar);
#endif

Binary file not shown.

View File

@ -0,0 +1,5 @@
func TestInclude()
{
print "Hello World!"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

View File

@ -0,0 +1,109 @@
int g_screenw = 256
int g_screenh = 224
int g_resolutionScale = 3
float g_playerWalkSpeed = 400
float g_playerRunSpeed = 700
float g_jumpHeight = 20
float g_currPlayerSpeed = 400
bool g_running = false
float g_gravitySpeed = -86
include "./extra-include.zs"
func Main()
{
//SplitThread(ThreadedFunction())
// Immediately creates the window, then Start(), then the game loop. The game loop calls Update() every frame
ZS.Graphics.Init("Platformer game", g_screenw, g_screenh, g_resolutionScale)
}
func ThreadedFunction()
{
print "threaded:"
}
func Start()
{
float centerX = g_screenw / 2
float centerY = g_screenh / 2
global Vec2 g_screencenter = NVec2(centerX, centerY)
Vec2 playerPos = g_screencenter
Vec2 playerScale = NVec2(16, 16)
global Sprite g_playerSprite = ZS.Graphics.Sprite("./mariostill.png", playerPos, playerScale, 0)
Vec2 groundPos = NVec2(g_screencenter.x, 192)
Vec2 groundScale = NVec2(256, 16)
global Sprite g_groundSprite = ZS.Graphics.Sprite("./square.png", groundPos, groundScale, 0)
Vec2 instructionsPos = NVec2(centerOfScreen.x, centerOfScreen.y)
global Text g_instructionsText = ZS.Graphics.Text("Use Arrow Keys or WASD to Move, and Spacebar to Jump", "./arial.ttf", instructionsPos, 20, 0, 255, 255, 255)
global Vec2 g_playerTargetPosition = playerPos
int i = 0
while i < 10 {
i += 1
print "while iter : " + i
}
}
func Update(deltaTime) {
float fps = 1 / deltaTime
print "FPS: " + fps
//TestInclude()
//// Test automatic conversion from bool to int
//int c = GetKey("A")
//print "Test: " + c
// Shift key lets you sprint
g_running = GetKey("SHIFT_L")
if g_running == true{
g_currPlayerSpeed = g_playerRunSpeed
}
if g_running == false
{
g_currPlayerSpeed = g_playerWalkSpeed
}
// Move Left And Right
if GetKey("A") == true
{
float newY = g_playerSprite.position.y
float newX = g_playerTargetPosition.x - g_currPlayerSpeed * deltaTime
g_playerTargetPosition = NVec2(newX, newY)
}
if GetKey("D") == true
{
float newY = g_playerSprite.position.y
float newX = g_playerTargetPosition.x + g_currPlayerSpeed * deltaTime
g_playerTargetPosition = NVec2(newX, newY)
}
// Lerps from old position to destination smoothly
float oldX = g_playerSprite.position.x
float newX = g_playerTargetPosition.x
float stopSpeed = deltaTime * 7
float lerpedX = Lerp(oldX, newX, stopSpeed)
g_playerSprite.position = NVec2(lerpedX, newY)
// Finally draws all of the sprites
ZS.Graphics.Draw(g_playerSprite)
ZS.Graphics.Draw(g_groundSprite)
ZS.Graphics.DrawText(g_instructionsText)
}
func Colliding(a, b)
{
bool b = ZS.Physics.AxisAlignedCollision(a, b)
return b
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B