|
@@ -0,0 +1,680 @@
|
|
|
+#include <math.h>
|
|
|
+#include "Vector3D.h"
|
|
|
+#include "GameEngine.h"
|
|
|
+#include "Control.h"
|
|
|
+
|
|
|
+long tickCounter = 0;
|
|
|
+long renderTickCounter = 0;
|
|
|
+
|
|
|
+long tickSum = 0;
|
|
|
+long renderTickSum = 0;
|
|
|
+
|
|
|
+long tickTime = -1;
|
|
|
+long renderTickTime = -1;
|
|
|
+
|
|
|
+typedef struct GameField
|
|
|
+{
|
|
|
+ int id;
|
|
|
+ float r;
|
|
|
+ float g;
|
|
|
+ float b;
|
|
|
+ float a;
|
|
|
+} GameField;
|
|
|
+
|
|
|
+int amountGameFields = -1;
|
|
|
+GameField* gameFields = NULL;
|
|
|
+
|
|
|
+GLuint vbo = -1;
|
|
|
+GLuint vba = -1;
|
|
|
+
|
|
|
+int fieldSize = 0;
|
|
|
+int quality = 0;
|
|
|
+int vertices = 0;
|
|
|
+GLsizeiptr size = 0;
|
|
|
+GLfloat* data = NULL;
|
|
|
+
|
|
|
+Vector3D oldCamera;
|
|
|
+Vector3D camera;
|
|
|
+float oldLengthAngle;
|
|
|
+float lengthAngle;
|
|
|
+float oldWidthAngle;
|
|
|
+float widthAngle;
|
|
|
+
|
|
|
+float mouseX = 0.0f;
|
|
|
+float mouseY = 0.0f;
|
|
|
+
|
|
|
+Vector3D front;
|
|
|
+Vector3D back;
|
|
|
+Vector3D right;
|
|
|
+Vector3D left;
|
|
|
+Vector3D up;
|
|
|
+Vector3D down;
|
|
|
+
|
|
|
+int selectedIndex = -1;
|
|
|
+int selectedLayer = -1;
|
|
|
+
|
|
|
+GameField* getGameField(int layer, int index)
|
|
|
+{
|
|
|
+ if(layer == 0)
|
|
|
+ {
|
|
|
+ return &gameFields[0];
|
|
|
+ }
|
|
|
+ else if(layer == 1 + fieldSize)
|
|
|
+ {
|
|
|
+ return &gameFields[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ index += (layer - 1) * fieldSize + 2;
|
|
|
+ if(index < 2 || index >= amountGameFields)
|
|
|
+ {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ return &gameFields[index];
|
|
|
+}
|
|
|
+
|
|
|
+float interpolate(float lag, float old, float new)
|
|
|
+{
|
|
|
+ return old + lag * (new - old);
|
|
|
+}
|
|
|
+
|
|
|
+void colorField(GameField* field)
|
|
|
+{
|
|
|
+ if(field->id)
|
|
|
+ {
|
|
|
+ field->r = 1.0f;
|
|
|
+ field->g = 0.0f;
|
|
|
+ field->b = 0.0f;
|
|
|
+ field->a = 1.0f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ field->r = 1.0f;
|
|
|
+ field->g = 1.0f;
|
|
|
+ field->b = 1.0f;
|
|
|
+ field->a = 1.0f;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void generateSphere()
|
|
|
+{
|
|
|
+ int triangles = fieldSize * quality;
|
|
|
+ int layers = (2 + fieldSize) * quality;
|
|
|
+
|
|
|
+ if(gameFields == NULL)
|
|
|
+ {
|
|
|
+ amountGameFields = 2 + fieldSize * fieldSize;
|
|
|
+ gameFields = malloc(sizeof(GameField) * amountGameFields);
|
|
|
+ for(int i = 0; i < amountGameFields; i++)
|
|
|
+ {
|
|
|
+ gameFields[i].id = (rand() < RAND_MAX / 2) ? 1 : 0;
|
|
|
+ colorField(&gameFields[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(data == NULL)
|
|
|
+ {
|
|
|
+ vertices = triangles * layers * 3 * 2;
|
|
|
+ size = sizeof(GLfloat) * 9 * vertices;
|
|
|
+ data = malloc(size);
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int l = 0; l < layers; l++)
|
|
|
+ {
|
|
|
+ float high1 = cos((M_PI * l) / layers);
|
|
|
+ float high2 = cos((M_PI * (l + 1)) / layers);
|
|
|
+
|
|
|
+ float texHigh1 = (l % quality) * (1.0f / quality);
|
|
|
+ float texHigh2 = texHigh1 + (1.0f / quality);
|
|
|
+
|
|
|
+ float r1 = sqrt(1 - high1 * high1);
|
|
|
+ float r2 = sqrt(1 - high2 * high2);
|
|
|
+
|
|
|
+ int flag = (l / quality) == 0;
|
|
|
+ if(flag)
|
|
|
+ {
|
|
|
+ texHigh1 = 1 - texHigh1;
|
|
|
+ texHigh2 = 1 - texHigh2;
|
|
|
+ }
|
|
|
+ flag |= (l / quality) >= fieldSize + 1;
|
|
|
+
|
|
|
+ for(int i = 0; i < triangles; i++)
|
|
|
+ {
|
|
|
+ float first = 2 * M_PI * i / triangles;
|
|
|
+ float second = 2 * M_PI * (i + 1) / triangles;
|
|
|
+
|
|
|
+ int off = 27 * 2 * i + l * triangles * 27 * 2;
|
|
|
+
|
|
|
+ float texWidth1 = (i % quality) * (1.0f / quality);
|
|
|
+ float texWidth2 = texWidth1 + (1.0f / quality);
|
|
|
+
|
|
|
+ float r = 0.0f;
|
|
|
+ float g = 0.0f;
|
|
|
+ float b = 0.0f;
|
|
|
+ float a = 0.0f;
|
|
|
+
|
|
|
+ GameField* field = getGameField(l / quality, i / quality);
|
|
|
+ if(field != NULL)
|
|
|
+ {
|
|
|
+ r = field->r;
|
|
|
+ g = field->g;
|
|
|
+ b = field->b;
|
|
|
+ a = field->a;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int j = 0; j < 54; j += 9)
|
|
|
+ {
|
|
|
+ data[3 + off + j] = r;
|
|
|
+ data[4 + off + j] = g;
|
|
|
+ data[5 + off + j] = b;
|
|
|
+ data[6 + off + j] = a;
|
|
|
+ }
|
|
|
+
|
|
|
+ data[0 + off] = r2 * cos(first);
|
|
|
+ data[1 + off] = high2;
|
|
|
+ data[2 + off] = r2 * sin(first);
|
|
|
+
|
|
|
+ data[9 + off] = r1 * cos(first);
|
|
|
+ data[10 + off] = high1;
|
|
|
+ data[11 + off] = r1 * sin(first);
|
|
|
+
|
|
|
+ data[18 + off] = r1 * cos(second);
|
|
|
+ data[19 + off] = high1;
|
|
|
+ data[20 + off] = r1 * sin(second);
|
|
|
+
|
|
|
+ if(flag)
|
|
|
+ {
|
|
|
+ data[7 + off] = texHigh2 * 0.5f;
|
|
|
+ data[8 + off] = texHigh2 * 0.5f;
|
|
|
+
|
|
|
+ data[16 + off] = texHigh1 * 0.5f;
|
|
|
+ data[17 + off] = texHigh1 * 0.5f;
|
|
|
+
|
|
|
+ data[25 + off] = texHigh1 * 0.5f;
|
|
|
+ data[26 + off] = texHigh1 * 0.5f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ data[7 + off] = texWidth1;
|
|
|
+ data[8 + off] = texHigh2;
|
|
|
+
|
|
|
+ data[16 + off] = texWidth1;
|
|
|
+ data[17 + off] = texHigh1;
|
|
|
+
|
|
|
+ data[25 + off] = texWidth2;
|
|
|
+ data[26 + off] = texHigh1;
|
|
|
+ }
|
|
|
+
|
|
|
+ data[27 + off] = r2 * cos(first);
|
|
|
+ data[28 + off] = high2;
|
|
|
+ data[29 + off] = r2 * sin(first);
|
|
|
+
|
|
|
+ data[36 + off] = r1 * cos(second);
|
|
|
+ data[37 + off] = high1;
|
|
|
+ data[38 + off] = r1 * sin(second);
|
|
|
+
|
|
|
+ data[45 + off] = r2 * cos(second);
|
|
|
+ data[46 + off] = high2;
|
|
|
+ data[47 + off] = r2 * sin(second);
|
|
|
+
|
|
|
+ if(flag)
|
|
|
+ {
|
|
|
+ data[34 + off] = texHigh2 * 0.5f;
|
|
|
+ data[35 + off] = texHigh2 * 0.5f;
|
|
|
+
|
|
|
+ data[43 + off] = texHigh1 * 0.5f;
|
|
|
+ data[44 + off] = texHigh1 * 0.5f;
|
|
|
+
|
|
|
+ data[52 + off] = texHigh2 * 0.5f;
|
|
|
+ data[53 + off] = texHigh2 * 0.5f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ data[34 + off] = texWidth1;
|
|
|
+ data[35 + off] = texHigh2;
|
|
|
+
|
|
|
+ data[43 + off] = texWidth2;
|
|
|
+ data[44 + off] = texHigh1;
|
|
|
+
|
|
|
+ data[52 + off] = texWidth2;
|
|
|
+ data[53 + off] = texHigh2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
|
|
+}
|
|
|
+
|
|
|
+void updateProjection(float aspect, int program)
|
|
|
+{
|
|
|
+ float fovY = 60.0f;
|
|
|
+ float nearClip = 0.1f;
|
|
|
+ float farClip = 1000;
|
|
|
+
|
|
|
+ float q = 1.0f / (float) tan((0.5f * fovY) * M_PI / 180.0f);
|
|
|
+ float a = q / aspect;
|
|
|
+ float b = (nearClip + farClip) / (nearClip - farClip);
|
|
|
+ float c = (2.0f * nearClip * farClip) / (nearClip - farClip);
|
|
|
+
|
|
|
+ GLfloat data[16];
|
|
|
+ data[0] = a;
|
|
|
+ data[1] = 0.0f;
|
|
|
+ data[2] = 0.0f;
|
|
|
+ data[3] = 0.0f;
|
|
|
+
|
|
|
+ data[4] = 0.0f;
|
|
|
+ data[5] = q;
|
|
|
+ data[6] = 0.0f;
|
|
|
+ data[7] = 0.0f;
|
|
|
+
|
|
|
+ data[8] = 0.0f;
|
|
|
+ data[9] = 0.0f;
|
|
|
+ data[10] = b;
|
|
|
+ data[11] = -1.0f;
|
|
|
+
|
|
|
+ data[12] = 0.0f;
|
|
|
+ data[13] = 0.0f;
|
|
|
+ data[14] = c;
|
|
|
+ data[15] = 0;
|
|
|
+
|
|
|
+ GLint loc = glGetUniformLocation(program, "projMatrix");
|
|
|
+ glUniformMatrix4fv(loc, 1, 0, data);
|
|
|
+}
|
|
|
+
|
|
|
+float chooseSmallerPositive(float a, float b)
|
|
|
+{
|
|
|
+ if(a < 0)
|
|
|
+ {
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+ else if(b < 0 || b > a)
|
|
|
+ {
|
|
|
+ return a;
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+}
|
|
|
+
|
|
|
+void updateView(int program, float lag)
|
|
|
+{
|
|
|
+
|
|
|
+ vectorSetAngles(&front, interpolate(lag, oldLengthAngle, lengthAngle), interpolate(lag, oldWidthAngle, widthAngle));
|
|
|
+
|
|
|
+
|
|
|
+ float a = camera.x * camera.x + camera.y * camera.y + camera.z * camera.z - 1;
|
|
|
+ float b = 2 * (camera.x * front.x + camera.y * front.y + camera.z * front.z);
|
|
|
+ float c = front.x * front.x + front.y * front.y + front.z * front.z;
|
|
|
+
|
|
|
+ float p = b / c;
|
|
|
+ float q = a / c;
|
|
|
+
|
|
|
+ float det = p * p * 0.25f - q;
|
|
|
+ if(det >= 0)
|
|
|
+ {
|
|
|
+ float k = sqrt(det);
|
|
|
+ k = chooseSmallerPositive(-0.5f * p + k, -0.5f * p - k);
|
|
|
+ if(k >= 0)
|
|
|
+ {
|
|
|
+ Vector3D v;
|
|
|
+ vectorSetTo(&v, &camera);
|
|
|
+ vectorAddMul(&v, &front, k);
|
|
|
+
|
|
|
+ selectedLayer = (asin(-v.y) + M_PI_2) * M_1_PI * (2 + fieldSize);
|
|
|
+ if(selectedLayer == 2 + fieldSize)
|
|
|
+ {
|
|
|
+ selectedLayer = fieldSize + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ float tan = atan2(v.z, v.x) * M_1_PI * 0.5;
|
|
|
+ tan += (tan < 0);
|
|
|
+ selectedIndex = tan * fieldSize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&back, &front);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetTo(&right, &front);
|
|
|
+ vectorCross(&right, 0.0f, 1.0f, 0.0f);
|
|
|
+ vectorNormalize(&right);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&left, &right);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetTo(&up, &front);
|
|
|
+ vectorCrossWith(&up, &left);
|
|
|
+ vectorNormalize(&up);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&down, &up);
|
|
|
+
|
|
|
+ GLfloat data[16];
|
|
|
+ data[0] = right.x;
|
|
|
+ data[1] = up.x;
|
|
|
+ data[2] = back.x;
|
|
|
+ data[3] = 0.0f;
|
|
|
+
|
|
|
+ data[4] = right.y;
|
|
|
+ data[5] = up.y;
|
|
|
+ data[6] = back.y;
|
|
|
+ data[7] = 0.0f;
|
|
|
+
|
|
|
+ data[8] = right.z;
|
|
|
+ data[9] = up.z;
|
|
|
+ data[10] = back.z;
|
|
|
+ data[11] = 0.0f;
|
|
|
+
|
|
|
+ Vector3D interCam;
|
|
|
+ vectorSetTo(&interCam, &oldCamera);
|
|
|
+ vectorAddMul(&interCam, &camera, lag);
|
|
|
+ vectorAddMul(&interCam, &oldCamera, -lag);
|
|
|
+
|
|
|
+ data[12] = vectorDotInverse(&right, &interCam);
|
|
|
+ data[13] = vectorDotInverse(&up, &interCam);
|
|
|
+ data[14] = vectorDotInverse(&back, &interCam);
|
|
|
+ data[15] = 1.0f;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetAngles(&front, interpolate(lag, oldLengthAngle, lengthAngle), interpolate(lag, oldWidthAngle, widthAngle));
|
|
|
+ front.y = 0;
|
|
|
+ vectorNormalize(&front);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&back, &front);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetTo(&right, &front);
|
|
|
+ vectorCross(&right, 0.0f, 1.0f, 0.0f);
|
|
|
+ vectorNormalize(&right);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&left, &right);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSet(&up, 0.0f, 1.0f, 0.0f);
|
|
|
+
|
|
|
+
|
|
|
+ vectorSetToInverse(&down, &up);
|
|
|
+
|
|
|
+ GLint loc = glGetUniformLocation(program, "viewMatrix");
|
|
|
+ glUniformMatrix4fv(loc, 1, 0, data);
|
|
|
+}
|
|
|
+
|
|
|
+void init(int program)
|
|
|
+{
|
|
|
+ printf("Init\n");
|
|
|
+
|
|
|
+ glGenBuffers(1, &vbo);
|
|
|
+ glGenVertexArrays(1, &vba);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
|
+ glBindVertexArray(vba);
|
|
|
+
|
|
|
+ glVertexAttribPointer(0, 3, GL_FLOAT, 0, 36, (GLvoid*) 0);
|
|
|
+ glEnableVertexAttribArray(0);
|
|
|
+
|
|
|
+ glVertexAttribPointer(1, 4, GL_FLOAT, 0, 36, (GLvoid*) 12);
|
|
|
+ glEnableVertexAttribArray(1);
|
|
|
+
|
|
|
+ glVertexAttribPointer(2, 2, GL_FLOAT, 0, 36, (GLvoid*) 28);
|
|
|
+ glEnableVertexAttribArray(2);
|
|
|
+
|
|
|
+ generateSphere();
|
|
|
+
|
|
|
+ vectorSet(&camera, 0.0f, 0.0f, -5.0f);
|
|
|
+ lengthAngle = 0.0f;
|
|
|
+ widthAngle = 0.0f;
|
|
|
+
|
|
|
+ updateProjection(4.0f / 3.0f, program);
|
|
|
+}
|
|
|
+
|
|
|
+void invertField(int layer, int index)
|
|
|
+{
|
|
|
+ GameField* field = getGameField(layer, index);
|
|
|
+ if(field != NULL)
|
|
|
+ {
|
|
|
+ field->id = 1 - field->id;
|
|
|
+ colorField(field);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void invertAt(int layer, int index)
|
|
|
+{
|
|
|
+ if(layer == 0)
|
|
|
+ {
|
|
|
+ invertField(layer, index);
|
|
|
+ layer++;
|
|
|
+ for(int i = 0; i < fieldSize ; i++)
|
|
|
+ {
|
|
|
+ invertField(layer, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(layer == fieldSize + 1)
|
|
|
+ {
|
|
|
+ invertField(layer, index);
|
|
|
+ layer--;
|
|
|
+ for(int i = 0; i < fieldSize ; i++)
|
|
|
+ {
|
|
|
+ invertField(layer, i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ invertField(layer, index);
|
|
|
+ invertField(layer, (index + 1) % fieldSize);
|
|
|
+ invertField(layer, (index - 1 + fieldSize) % fieldSize);
|
|
|
+ invertField(layer + 1, index);
|
|
|
+ invertField(layer - 1, index);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void tick(int program)
|
|
|
+{
|
|
|
+ if(tickTime == -1)
|
|
|
+ {
|
|
|
+ tickTime = glfwGetTimerValue();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ long time = glfwGetTimerValue();
|
|
|
+ tickSum += time - tickTime;
|
|
|
+ tickTime = time;
|
|
|
+
|
|
|
+ tickCounter++;
|
|
|
+ }
|
|
|
+
|
|
|
+ vectorSetTo(&oldCamera, &camera);
|
|
|
+ oldLengthAngle = lengthAngle;
|
|
|
+ oldWidthAngle = widthAngle;
|
|
|
+
|
|
|
+ float factor = 0.05f;
|
|
|
+ if(keyIsDown(GLFW_KEY_A))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &left, factor);
|
|
|
+ }
|
|
|
+ if(keyIsDown(GLFW_KEY_D))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &right, factor);
|
|
|
+ }
|
|
|
+ if(keyIsDown(GLFW_KEY_W))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &front, factor);
|
|
|
+ }
|
|
|
+ if(keyIsDown(GLFW_KEY_S))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &back, factor);
|
|
|
+ }
|
|
|
+ if(keyIsDown(GLFW_KEY_SPACE))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &up, factor);
|
|
|
+ }
|
|
|
+ if(keyIsDown(GLFW_KEY_LEFT_SHIFT))
|
|
|
+ {
|
|
|
+ vectorAddMul(&camera, &down, factor);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(mouseIsJustDown(GLFW_MOUSE_BUTTON_1) && selectedLayer != -1 && selectedIndex != -1)
|
|
|
+ {
|
|
|
+ invertAt(selectedLayer, selectedIndex);
|
|
|
+ generateSphere();
|
|
|
+ selectedLayer = -1;
|
|
|
+ selectedIndex = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ widthAngle -= mouseY * 0.1f;
|
|
|
+ lengthAngle -= mouseX * 0.1f;
|
|
|
+
|
|
|
+ if(widthAngle >= 89.5)
|
|
|
+ {
|
|
|
+ widthAngle = 89.5f;
|
|
|
+ }
|
|
|
+ else if(widthAngle <= -89.5)
|
|
|
+ {
|
|
|
+ widthAngle = -89.5f;
|
|
|
+ }
|
|
|
+
|
|
|
+ mouseX = 0.0f;
|
|
|
+ mouseY = 0.0f;
|
|
|
+}
|
|
|
+
|
|
|
+void renderTick(int program, float lag)
|
|
|
+{
|
|
|
+ if(renderTickTime == -1)
|
|
|
+ {
|
|
|
+ renderTickTime = glfwGetTimerValue();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ long time = glfwGetTimerValue();
|
|
|
+ renderTickSum += time - renderTickTime;
|
|
|
+ renderTickTime = time;
|
|
|
+
|
|
|
+ renderTickCounter++;
|
|
|
+ }
|
|
|
+
|
|
|
+ updateView(program, lag);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
|
+ glBindVertexArray(vba);
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, vertices);
|
|
|
+}
|
|
|
+
|
|
|
+void onWindowResize(int width, int height)
|
|
|
+{
|
|
|
+ updateProjection((float) width / height, getProgram());
|
|
|
+}
|
|
|
+
|
|
|
+void onMouseMove(float x, float y)
|
|
|
+{
|
|
|
+ mouseX += x;
|
|
|
+ mouseY += y;
|
|
|
+}
|
|
|
+
|
|
|
+int readPositiveInt(int from, int to, char* message, int error)
|
|
|
+{
|
|
|
+ fputs(message, stdout);
|
|
|
+ fflush(stdout);
|
|
|
+
|
|
|
+ int size = 16;
|
|
|
+ int index = 0;
|
|
|
+ char* buffer = malloc(sizeof(char) * size);
|
|
|
+
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ int c = fgetc(stdin);
|
|
|
+ if(c == EOF)
|
|
|
+ {
|
|
|
+ free(buffer);
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+ else if(c == '\n')
|
|
|
+ {
|
|
|
+ int number = 0;
|
|
|
+ int i = 0;
|
|
|
+ while(i < index)
|
|
|
+ {
|
|
|
+ int n = buffer[i] - '0';
|
|
|
+ if(n < 0 || n > 9)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ number = number * 10 + n;
|
|
|
+ if(number > to)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(i >= index && number >= from)
|
|
|
+ {
|
|
|
+ free(buffer);
|
|
|
+ return number;
|
|
|
+ }
|
|
|
+
|
|
|
+ fputs(message, stdout);
|
|
|
+ fflush(stdout);
|
|
|
+ index = 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(index >= size)
|
|
|
+ {
|
|
|
+ size *= 2;
|
|
|
+ buffer = realloc(buffer, sizeof(char) * size);
|
|
|
+ }
|
|
|
+ buffer[index] = c;
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int main()
|
|
|
+{
|
|
|
+
|
|
|
+ if(fieldSize == 0)
|
|
|
+ {
|
|
|
+ printf("Cannot read from stdin\n");
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+ }
|
|
|
+ quality = readPositiveInt(1, 9, "Select a rendering quality from 1 to 9:\n", 0);
|
|
|
+ if(quality == 0)
|
|
|
+ {
|
|
|
+ printf("Cannot read from stdin\n");
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+ }*/
|
|
|
+ fieldSize = 5;
|
|
|
+ quality = 8;
|
|
|
+
|
|
|
+ if(startGame("Test Game", init, tick, renderTick, onWindowResize, onMouseMove))
|
|
|
+ {
|
|
|
+ fprintf(stderr, "Exited with error\n");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if(data != NULL)
|
|
|
+ {
|
|
|
+ free(data);
|
|
|
+ }
|
|
|
+ if(gameFields != NULL)
|
|
|
+ {
|
|
|
+ free(gameFields);
|
|
|
+ }
|
|
|
+
|
|
|
+ glDeleteBuffers(1, &vbo);
|
|
|
+ glDeleteVertexArrays(1, &vba);
|
|
|
+
|
|
|
+ printf("_______________TPS_______________\n");
|
|
|
+ printf("%ld %ld %ld\n", tickCounter, tickSum, tickTime);
|
|
|
+ printf("%lf\n", (double) tickSum / tickCounter);
|
|
|
+ printf("%lf\n", 1000000000.0 * tickCounter / tickSum);
|
|
|
+ printf("_______________FPS_______________\n");
|
|
|
+ printf("%ld %ld %ld\n", renderTickCounter, renderTickSum, renderTickTime);
|
|
|
+ printf("%lf\n", (double) renderTickSum / renderTickCounter);
|
|
|
+ printf("%lf\n", 1000000000.0 * renderTickCounter / renderTickSum);
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|