-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInterpreter.cpp
More file actions
162 lines (147 loc) · 4.39 KB
/
Interpreter.cpp
File metadata and controls
162 lines (147 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "Interpreter.h"
#include <strstream>
#include "helperfunctions.h"
#include "Renderer.h"
#include "FlightSimulator.h"
using namespace std;
extern CFlightSimulator gFlightSimulator;
void SinopInterpreter::Parse(const std::string &txt)
{
strstream strm;
strm<<txt;
while (strm.good())
{
auto vec = ReadCommand(strm);
if (vec.size() >= 2 && vec[0] == "DrawImage") {
mCommands.push_back(new SinopDrawImageCommand());
mCommands.back()->Parse(vec);
}
else if (vec.size() >= 3 && vec[0] == "Translate") {
mCommands.push_back(new SinopTranslateMatrixCommand());
mCommands.back()->Parse(vec);
}
else if (vec[0] == "PushMatrix")
mCommands.push_back(new SinopPushMatrixCommand());
else if (vec[0] == "PopMatrix")
mCommands.push_back(new SinopPopMatrixCommand());
}
}
void SinopInterpreter::Run()
{
// run the operations of the script
for (auto& cmd : mCommands)
{
cmd->UpdateIdentifierValues();
cmd->DoOperation();
}
}
std::vector<std::string> SinopInterpreter::ReadCommand(strstream& strm)
{
std::vector<std::string> tokens;
tokens.push_back("");
char ch = '\0';
// get function name
strm>>ch;
if (ch == '#')
while (ch != '\n') strm>>ch;
while (strm.good() && ch != '(' ) {
tokens.back().push_back(ch);
strm>>ch;
}
// get parameters
strm>>ch;
while (strm.good() && ch != ')') {
if (tokens.size() <= 1) tokens.push_back("");
if (ch == ',') {
tokens.push_back("");
strm>>ch;
}
tokens.back().push_back(ch);
strm>>ch;
}
for (auto& token : tokens) trim(token);
return tokens;
}
void SinopDrawImageCommand::DoOperation()
{
if (!mTex) return;
CRenderer::DrawImage(mTex, mpSourceRect, mUsingBlendColor ? mBlendColor : 0xFFFFFFFF);
}
std::map<std::string, CTexture*> SinopDrawImageCommand::mTextures;
void SinopDrawImageCommand::Parse(std::vector<std::string> parameters)
{
if (parameters.size() <= 1) return;
// if new texture
if (mTextures.find(parameters[1]) == mTextures.end())
{
if (mTex) delete mTex;
mTex = new CTexture();
png_to_gl_texture(mTex, parameters[1].c_str());
mTextures[parameters[1]] = mTex;
}
else
mTex = mTextures[parameters[1]];
// sourcerect
if (parameters.size() <= 5) return;
{
mSourceRect.left = atof(parameters[2].c_str());
mSourceRect.top = atof(parameters[3].c_str());
mSourceRect.right = atof(parameters[4].c_str());
mSourceRect.bottom = atof(parameters[5].c_str());
mpSourceRect = &mSourceRect;
}
// blendcolor
if (parameters.size() <= 9) return;
{
uint32_t a = atoi(parameters[6].c_str());
uint32_t r = atoi(parameters[7].c_str());
uint32_t g = atoi(parameters[8].c_str());
uint32_t b = atoi(parameters[9].c_str());
mBlendColor = ((a<<24)&0xFF000000) | ((r<<16)&0xFF0000) | ((g<<8)&0xFF00) | (b&0xFF);
mUsingBlendColor = true;
}
}
void SinopPushMatrixCommand::DoOperation()
{
glPushMatrix();
}
void SinopPopMatrixCommand::DoOperation()
{
glPopMatrix();
}
void SinopTranslateMatrixCommand::DoOperation()
{
glTranslatef(mX, mY, 0);
}
void SinopTranslateMatrixCommand::Parse(std::vector<std::string> parameters)
{
if (parameters.size() < 3) return;
ParseFloatExpression(parameters[1], &mX); // mX = atof(parameters[1].c_str());
ParseFloatExpression(parameters[2], &mY);// mY = atof(parameters[2].c_str());
}
void SinopCommand::UpdateIdentifierValues()
{
if (mNamedVariableLinks.size() > 0)
int debug = 0;
// update all the values of referenced identifiers
for (auto& floatpair : mNamedVariableLinks){
*(floatpair.first) = *(floatpair.second);
int debug = 0;
}
}
void SinopCommand::ParseFloatExpression(std::string s, float *fp)
{
// if string contains a literal number
if (IsNumeric(s)) {
*fp = atof(s.c_str());
}
// else if the string is an identifier of a named variable
else if (s.find_first_of("<>()+-*/?:") == std::string::npos){
float* const ptr = gFlightSimulator.GetAddressOfNamedVariableFloat(s);
mNamedVariableLinks.emplace_back(fp, ptr);
}
// else it is a math expression
else{
// to be done
}
}