Skip to content

Instantly share code, notes, and snippets.

Created September 14, 2011 15:29
Show Gist options
  • Select an option

  • Save anonymous/1216872 to your computer and use it in GitHub Desktop.

Select an option

Save anonymous/1216872 to your computer and use it in GitHub Desktop.
#include "ssr.h"
#define SSR_FTORGB(r, g, b) ((DWORD)(255 << 24 | ((BYTE)(r * 255.0f)) << 16 | ((BYTE)(g * 255.0f)) << 8 | ((BYTE)(b * 255.0f))))
#define SSR_FTOARGB(a, r, g, b) ((DWORD)(((BYTE)(a * 255.0f)) << 24 | ((BYTE)(r * 255.0f)) << 16 | ((BYTE)(g * 255.0f)) << 8 | ((BYTE)(b * 255.0f))))
#define SSR_ARGB(a, r, g, b) ((DWORD)(((BYTE)a) << 24 | ((BYTE)(r)) << 16 | ((BYTE)(g)) << 8 | ((BYTE)(b))))
#define SSR_GETA(rgb) ((BYTE)((rgb & 0xFF000000) >> 24))
#define SSR_GETR(rgb) ((BYTE)((rgb & 0x00FF0000) >> 16))
#define SSR_GETG(rgb) ((BYTE)((rgb & 0x0000FF00) >> 8))
#define SSR_GETB(rgb) ((BYTE)((rgb & 0x000000FF)))
#define SSR_SQRTFUNC sqrtf
#define SSR_FLERP(l, r, p) (l + (p * (r - l)))
#define SSR_DEG_TO_RAD 0.0174532925f
#define SSR_RAD_TO_DEG 57.2957795f
#define SSR_MATRIX_MULTIPLY(m1, m2, result) \
result[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; \
result[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; \
result[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; \
result[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; \
result[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; \
result[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; \
result[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; \
result[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; \
result[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; \
result[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; \
result[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; \
result[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; \
result[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; \
result[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; \
result[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; \
result[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
#define SSR_DOT_PRODUCT(v1, v2, r) r = ((v1[0] * v2[0]) + (v1[1] * v2[1]) + (v1[2] * v2[2]));
#define SSR_CROSS_PRODUCT(side1, side2, normal);\
normal[0] = (side1[1] * side2[2]) - (side1[2] - side2[1]);\
normal[1] = (side1[2] * side2[0]) - (side1[0] - side2[2]);\
normal[2] = (side1[0] * side2[1]) - (side1[1] - side2[0]);
#define SSR_VECTOR_MATRIX_MULTIPLY(vector, matrix, output) \
output[0] = vector[0] * matrix[0] + vector[1] * matrix[4] + vector[2] * matrix[8] + matrix[12]; \
output[1] = vector[0] * matrix[1] + vector[1] * matrix[5] + vector[2] * matrix[9] + matrix[13]; \
output[2] = vector[0] * matrix[2] + vector[1] * matrix[6] + vector[2] * matrix[10] + matrix[14];
#define SSR_NORMALIZE(normal, scratch)\
scratch = sqrtf((normal[0] * normal[0]) + (normal[1] * normal[1]) + (normal[2] * normal[2]));\
normal[0] /= scratch;\
normal[1] /= scratch;\
normal[2] /= scratch;
#define SSR_VIEWPORT_LEFT 0
#define SSR_VIEWPORT_RIGHT 1
#define SSR_VIEWPORT_TOP 2
#define SSR_VIEWPORT_BOTTOM 3
#define SSR_VERTVEC_INCREMENT 3
typedef struct SSR_VERT_TYPE {
float x, y, z;
union {
struct { float r; };
struct { float usingUV; };
};
union {
struct { float g; };
struct { float u; };
};
union {
struct { float b; };
struct { float v; };
};
} SSRVERTEX, *PSSRVERTEX;
typedef struct SSR_MATRIX_COMPONENT_TYPE {
float projectionMatrixStack[8][16];
float modelviewMatrixStack[32][16];
int currentProjectionMatrix;
int currentModelviewMatrix;
int projectionMode;
int matrixMode;
} SSRMATRIXCOMPONENT, *PSSRMATRIXCOMPONENT;
typedef struct SSR_DISPLAY_COMPONENT_TYPE {
COLORREF* imageBuffer;
float* depthBuffer;
COLORREF clearColor;
SSRIMID boundImage;
} SSRDISPLAYCOMPONENT, *PSSRDISPLAYCOMPONENT;
typedef struct SSR_RENDERINFO_COMPONENT_TYPE {
int cullDirection;
int imageWrapMode;
int viewport[4];
float offset[4];
float perspectiveCompensate[2];
float normalizeValues[2];
} SSRRENDERINFOCOMPONENT, *PSSRRENDERINFOCOMPONENT;
typedef struct SSR_WINDOWSDISPLAY_COMPONENT_TYPE {
HDC hdcDisplay;
HDC hdcBitmap;
HBITMAP hbmBitmap;
HBITMAP hbmBitmapOld;
BITMAP bmBitmapInfo;
} SSRWINDOWDISPLAYCOMPONENT, *PSSRWINDOWDISPLAYCOMPONENT;
typedef struct SSR_BATCH_COMPONENT_TYPE {
vector<SSRVERTEX> masterVertexList;
int batchType;
} SSRBATCHCOMPONENT, *PSSRBATCHCOMPONENT;
typedef struct SSR_TEXT_TYPE {
string displayString;
int x, y;
COLORREF color;
} SSRTEXT, *PSSRTEXT;
typedef struct SSR_CONTEXT_TYPE {
SSRDISPLAYCOMPONENT displayComponent;
SSRMATRIXCOMPONENT matrixComponent;
SSRRENDERINFOCOMPONENT renderInfoComponent;
SSRWINDOWDISPLAYCOMPONENT windowsDisplayComponent;
SSRBATCHCOMPONENT batchComponent;
vector<SSRTEXT> textOutputComponent;
} SSRCONTEXT, *PSSRCONTEXT;
#pragma pack(1)
typedef struct TGA_H {
signed char identsize;
signed char colorMapType;
signed char imageType;
unsigned short colorMapStart;
unsigned short colorMapLength;
unsigned char colorMapBits;
unsigned short xstart;
unsigned short ystart;
unsigned short width;
unsigned short height;
signed char bits;
signed char descriptor;
} TGAHEADER;
#pragma pack(8)
void ssrMatrixMakeZRotation(float angle, float* matrix);
void ssrMatrixMakeYRotation(float angle, float* matrix);
void ssrMatrixMakeXRotation(float angle, float* matrix);
void ssrEndOnTriangle();
void ssrEndOnQuad();
void ssrEndOnTriangleStrip();
float* ssrClampToZeroOne(float* f);
float ssrClampToZeroOne(float f);
int ssrGet32(FILE *f);
int ssrGet16(FILE *f);
int ssrNextPowerOf2(int n);
void ssrDrawBlackLine(float x1, float x2, float z1, float z2, float y);
void ssrRenderBlackTriangle(float* verts);
void ssrDrawColoredLine(float x1, float x2, float y, float z1, float z2, float* color_left, float* color_right);
void ssrRenderColoredTriangle(float* verts, float (*colors)[3]);
void ssrSortSplitSubmitTexturedTriangle(float (*triangle)[3], float (*uvs)[2]);
void ssrRenderTexturedTriangle(float* verts, float * uvs);
bool ssrIsBackFacing(float* verts);
void ssrSortTriangle(float (*verts)[3], int* order);
void ssrSortSplitAndSumbitTriangle(float (*triangle)[3]);
void ssrSortSplitSubmitColoredTriangle(float (*triangle)[3], float (*colors)[3]);
void ssrTransformToScreenSpace();
void ssrDoProjectedClipping();
void ssrProjectedTriangleClip();
void ssrProjectedQuadClip();
void ssrProjectedStripClip();
void ssrDrawText();
void ssrBitmapHelper(char* imagePath, unsigned char (*videoArea[])[4]);
void ssrTargaHelper(char* imagePath, unsigned char (*videoArea[])[4]);
PSSRCONTEXT ssr_pCurrentRenderContext = NULL;
int ssr_nLastError = SSR_ERR_NONE;
int ssr_debugNumTriangles;
const char* ssrErrors[] = {
"No error",
"Render context is invalid",
"HDC is not attached to a HWND",
"Could not find window size",
"Global RC handle is null",
"Invalid argument",
"Projection matrix was not set up",
"Master vertex list is not initialized",
"Unknown primitive",
"Triangle strip needs at least 3 verts",
"Could not read in image file",
"Bitmap must be a 24 bit image",
"There is no image to delete!",
"Trying to bind to a null texture",
"No projection has ben set",
"Targa must be a 32 bit image!"
};
void ssrVertex(float x, float y, float z) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
SSRVERTEX v; v.x = x; v.y = y; v.z = z; v.r = -1.0f; v.g = -1.0f; v.b = -1.0f;
ssr_pCurrentRenderContext->batchComponent.masterVertexList.push_back(v);
}
void ssrColor(float r, float g, float b) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
int vertexIndex = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() - 1;
if (r < 0.0f) r = 0.0f;
if (g < 0.0f) g = 0.0f;
if (b < 0.0f) b = 0.0f;
if (r > 1.0f) r = 1.0f;
if (g > 1.0f) g = 1.0f;
if (b > 1.0f) b = 1.0f;
ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].r = r;
ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].g = g;
ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].b = b;
}
void ssrTexCoord(float u, float v) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
int vertexIndex = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() - 1;
if (ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode == SSR_REPEAT) {
while (u < 0.0f) u += 1.0f; while (u > 1.0f) u -= 1.0f;
while (v < 0.0f) v += 1.0f; while (v > 1.0f) v -= 1.0f;
} else {
if (u > 1.0f) u = 1.0f;
if (u < 0.0f) u = 0.0f;
if (v > 1.0f) v = 1.0f;
if (v < 0.0f) v = 0.0f;
}
ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].u = u;
ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].v = v;
}
void ssrBegin(int batchType) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (batchType != SSR_TRIANGLE && batchType != SSR_TRIANGLESTRIP && batchType != SSR_QUAD) {
ssr_nLastError = SSR_ERR_INVARG;
return;
}
ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear();
ssr_pCurrentRenderContext->batchComponent.batchType = batchType;
}
void ssrEnd() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
ssrTransformToScreenSpace();
if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_TRIANGLE) {
ssrEndOnTriangle();
} else if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_TRIANGLESTRIP) {
ssrEndOnTriangleStrip();
} else if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_QUAD) {
ssrEndOnQuad();
}
ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear();
}
void ssrBitmapHelper(char* imagePath, unsigned char (*videoArea[])[4]) {
FILE* bmp;
int fileSize, offsetToImage, headerSize, d;
unsigned int w, h;
int bpp, imageSize, xpels, ypels, lookupTableSize;
int impColors, compression;
if ((bmp = fopen(imagePath, "rb")) == NULL) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
return;
}
char buf[8];
if (fread(buf, 1, 2, bmp) != 2 || strncmp("BM", buf, 2) != 0) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
fclose(bmp);
return;
}
fileSize = ssrGet32(bmp);
ssrGet16(bmp); ssrGet16(bmp);
offsetToImage = ssrGet32(bmp);
headerSize = ssrGet32(bmp);
w = ssrGet32(bmp); h = ssrGet32(bmp); d = ssrGet16(bmp);
*videoArea = new unsigned char[w * h + 2][4]; // R G will contain width & height
(*videoArea)[0][0] = (w ) & 0xff;
(*videoArea)[0][1] = (w >> 8) & 0xff;
(*videoArea)[0][2] = (w >> 16) & 0xff;
(*videoArea)[0][3] = (w >> 24) & 0xff;
(*videoArea)[1][0] = (h ) & 0xff;
(*videoArea)[1][1] = (h >> 8) & 0xff;
(*videoArea)[1][2] = (h >> 16) & 0xff;
(*videoArea)[1][3] = (h >> 24) & 0xff;
if ((bpp = ssrGet16(bmp)) != 24) {
ssr_nLastError = SSR_ERR_BITMAPBITSOFF;
fclose(bmp);
return;
}
if ((compression = ssrGet32(bmp)) != 0) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
fclose(bmp);
return;
}
imageSize = ssrGet32(bmp);
xpels = ssrGet32(bmp);
ypels = ssrGet32(bmp);
if ((lookupTableSize = ssrGet32(bmp)) != 0) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
fclose(bmp);
return;
}
impColors = ssrGet32(bmp);
for (int j = (int)h - 1; j >= 0; --j) { // Read in reverse row order
for (int i = 0; i < (int)w; ++i) {
unsigned char bgr[3];
if (fread(bgr, 1, 3, bmp) != 3) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
fclose(bmp);
return;
}
int index = (j * w + i) + 2;
(*videoArea)[index][0] = bgr[2];
(*videoArea)[index][1] = bgr[1];
(*videoArea)[index][2] = bgr[0];
(*videoArea)[index][3] = 255;
}
}
fclose(bmp);
}
void ssrDrawBlackLine(float x1, float x2, float z1, float z2, float y) {
if (x1 > x2) {
float temp = x1;
x1 = x2;
x2 = temp;
temp = z1;
z1 = z2;
z2 = temp;
}
int earlyOutOnIndex = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight;
for (int x = (int)x1, xmax = (int)x2, width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; x < xmax; ++x) {
if (x > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1) continue;
if (x < 0) continue;
if (y < 0) continue;
if (y > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1) continue;
int index = (int)y * width + x;
if (index < 0) continue;
if (index > earlyOutOnIndex) continue;
float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1));
float z = SSR_FLERP(z1, z2, p);
if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue;
ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_FTORGB(0, 0, 0);
ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z;
}
}
void ssrRenderBlackTriangle(float* verts) {
#define x1 ((int)verts[0])
#define y1 ((int)verts[1])
#define z1 verts[2]
#define x2 ((int)verts[3])
#define y2 ((int)verts[4])
#define z2 verts[5]
#define x3 ((int)verts[6])
#define y3 ((int)verts[7])
#define z3 verts[8]
float slope_left, slope_right;
float left, right;
float height = (float)(y3 - y1);
if (height == 0)
return;
slope_left = (x2 - x1) / height;
slope_right = (x3 - x1) / height;
left = right = (float)x1;
float z_left;
float z_right;
z_left = z_right = z1;
float z_slope_left = (z2 - z1) / height;
float z_slope_right = (z3 - z1) / height;
if (y1 < y3) {
for (int y = (int)y1; y < (int)y3; ++y) {
ssrDrawBlackLine(left, right, z_left, z_right, (float)y);
left += slope_left;
right += slope_right;
z_left += z_slope_left;
z_right += z_slope_right;
}
} else {
for (int y = (int)y1; y >= (int)y3; --y) {
ssrDrawBlackLine(left, right, z_left, z_right, (float)y);
left -= slope_left;
right -= slope_right;
z_left -= z_slope_left;
z_right -= z_slope_right;
}
}
#undef x1
#undef x2
#undef x3
#undef y1
#undef y2
#undef y3
#undef z1
#undef z2
#undef z3
}
void ssrDrawColoredLine(float x1, float x2, float y, float z1, float z2, float* color_left, float* color_right) {
float c_l[3], c_r[3];
if (x1 > x2) {
float temp = x1;
x1 = x2;
x2 = temp;
temp = z1;
z1 = z2;
z2 = temp;
c_l[0] = color_right[0];
c_l[1] = color_right[1];
c_l[2] = color_right[2];
c_r[0] = color_left[0];
c_r[1] = color_left[1];
c_r[2] = color_left[2];
} else {
c_l[0] = color_left[0];
c_l[1] = color_left[1];
c_l[2] = color_left[2];
c_r[0] = color_right[0];
c_r[1] = color_right[1];
c_r[2] = color_right[2];
}
int earlyOutOnIndex = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight;
for (int x = (int)x1, xmax = (int)x2, width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; x < xmax; ++x) {
if (x > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1) continue;
if (x < 0) continue;
if (y < 0) continue;
if (y > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1) continue;
int index = (int)y * width + x;
if (index < 0) continue;
if (index > earlyOutOnIndex) continue;
float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1));
float z = SSR_FLERP(z1, z2, p);
if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue;
if (z <= 0.0f) continue;
float color[3];
color[0] = ssrClampToZeroOne(SSR_FLERP(c_l[0], c_r[0], p));
color[1] = ssrClampToZeroOne(SSR_FLERP(c_l[1], c_r[1], p));
color[2] = ssrClampToZeroOne(SSR_FLERP(c_l[2], c_r[2], p));
ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_FTORGB(color[0], color[1], color[2]);
ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z;
}
}
void ssrRenderColoredTriangle(float* verts, float (*colors)[3]) {
#define x1 ((int)verts[0])
#define y1 ((int)verts[1])
#define z1 verts[2]
#define x2 ((int)verts[3])
#define y2 ((int)verts[4])
#define z2 verts[5]
#define x3 ((int)verts[6])
#define y3 ((int)verts[7])
#define z3 verts[8]
float slope_left, slope_right;
float left, right;
float height = y3 - y1;
if (height == 0)
return;
slope_left = (x2 - x1) / height;
slope_right = (x3 - x1) / height;
left = right = x1;
float color_left[3] = {ssrClampToZeroOne(colors[0][0]), ssrClampToZeroOne(colors[0][1]), ssrClampToZeroOne(colors[0][2])};
float color_right[3] = {color_left[0], color_left[1], color_left[2]};
float color_left_slope[3] = {(colors[1][0] - colors[0][0]) / height, (colors[1][1] - colors[0][1]) / height, (colors[1][2] - colors[0][2]) / height};
float color_right_slope[3] = {(colors[2][0] - colors[0][0]) / height, (colors[2][1] - colors[0][1]) / height, (colors[2][2] - colors[0][2]) / height};
float z_left;
float z_right;
z_left = z_right = z1;
float z_slope_left = (z2 - z1) / height;
float z_slope_right = (z3 - z1) / height;
if (y1 < y3) {
for (int y = (int)y1; y < (int)y3; ++y) {
ssrDrawColoredLine(left, right, (float)y, z_left, z_right, ssrClampToZeroOne(color_left), ssrClampToZeroOne(color_right));
color_left[0] += color_left_slope[0];
color_left[1] += color_left_slope[1];
color_left[2] += color_left_slope[2];
color_right[0] += color_right_slope[0];
color_right[1] += color_right_slope[1];
color_right[2] += color_right_slope[2];
left += slope_left;
right += slope_right;
z_left += z_slope_left;
z_right += z_slope_right;
}
} else {
for (int y = (int)y1; y >= (int)y3; --y) {
ssrDrawColoredLine(left, right, (float)y, z_left, z_right, ssrClampToZeroOne(color_left), ssrClampToZeroOne(color_right));
color_left[0] -= color_left_slope[0];
color_left[1] -= color_left_slope[1];
color_left[2] -= color_left_slope[2];
color_right[0] -= color_right_slope[0];
color_right[1] -= color_right_slope[1];
color_right[2] -= color_right_slope[2];
left -= slope_left;
right -= slope_right;
z_left -= z_slope_left;
z_right -= z_slope_right;
}
}
#undef x1
#undef x2
#undef x3
#undef y1
#undef y2
#undef y3
#undef z1
#undef z2
#undef z3
}
void ssrEndOnTriangle() {
for (int i = 0, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; i += 3) {
float triangle[3][3]; float color[3][3]; float uvs[3][2];
triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x;
triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y;
triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z;
triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].x;
triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].y;
triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].z;
triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x;
triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y;
triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z;
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) {
ssrSortSplitAndSumbitTriangle(triangle);
} else {
uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u;
uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v;
uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].u;
uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].v;
uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u;
uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v;
ssrSortSplitSubmitTexturedTriangle(triangle, uvs);
}
} else {
color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r;
color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g;
color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b;
color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].r;
color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].g;
color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].b;
color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r;
color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g;
color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b;
ssrSortSplitSubmitColoredTriangle(triangle, color);
}
}
}
void ssrEndOnQuad() {
for (int i = 0, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; i += 4) {
float triangle[3][3]; float color[3][3]; float uvs[3][2];
triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x;
triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y;
triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z;
triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].x;
triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].y;
triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].z;
triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x;
triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y;
triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z;
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) {
ssrSortSplitAndSumbitTriangle(triangle);
} else {
uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u;
uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v;
uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].u;
uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].v;
uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u;
uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v;
ssrSortSplitSubmitTexturedTriangle(triangle, uvs);
}
} else {
color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r;
color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g;
color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b;
color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].r;
color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].g;
color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].b;
color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r;
color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g;
color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b;
ssrSortSplitSubmitColoredTriangle(triangle, color);
}
triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x;
triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y;
triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z;
triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x;
triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y;
triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z;
triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].x;
triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].y;
triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].z;
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) {
ssrSortSplitAndSumbitTriangle(triangle);
} else {
uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u;
uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v;
uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u;
uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v;
uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].u;
uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].v;
ssrSortSplitSubmitTexturedTriangle(triangle, uvs);
}
} else {
color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r;
color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g;
color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b;
color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r;
color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g;
color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b;
color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].r;
color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].g;
color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].b;
ssrSortSplitSubmitColoredTriangle(triangle, color);
}
}
}
void ssrEndOnTriangleStrip() {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() < 3) {
ssr_nLastError = SSR_ERR_TRISTRPMV;
return;
}
float init_triangle[3][3]; float init_color[3][3]; float init_uvs[3][2];
init_triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].x;
init_triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].y;
init_triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].z;
init_triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].x;
init_triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].y;
init_triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].z;
init_triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].x;
init_triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].y;
init_triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].z;
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].r == -1.0f) {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].u == -1.0f) {
ssrSortSplitAndSumbitTriangle(init_triangle);
} else {
init_uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].u;
init_uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].v;
init_uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].u;
init_uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].v;
init_uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].u;
init_uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].v;
ssrSortSplitSubmitTexturedTriangle(init_triangle, init_uvs);
}
} else {
init_color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].r;
init_color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].g;
init_color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].b;
init_color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].r;
init_color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].g;
init_color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].b;
init_color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].r;
init_color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].g;
init_color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].b;
ssrSortSplitSubmitColoredTriangle(init_triangle, init_color);
}
for (int i = 3, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; ++i) {
float triangle[3][3]; float color[3][3]; float uvs[3][2];
triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x;
triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y;
triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z;
triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].x;
triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].y;
triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].z;
triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].x;
triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].y;
triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].z;
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) {
if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) {
ssrSortSplitAndSumbitTriangle(triangle);
} else {
uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u;
uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v;
uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].u;
uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].v;
uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].u;
uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].v;
ssrSortSplitSubmitTexturedTriangle(triangle, uvs);
}
} else {
color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r;
color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g;
color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b;
color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].r;
color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].g;
color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].b;
color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].r;
color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].g;
color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].b;
ssrSortSplitSubmitColoredTriangle(triangle, color);
}
}
}
void ssrWriteText(char* text, int x, int y, COLORREF c) {
SSRTEXT display;
display.displayString = text;
display.x = x;
display.y = y;
display.color = c;
ssr_pCurrentRenderContext->textOutputComponent.push_back(display);
}
void ssrBindTexture(SSRIMID texToBindTo) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (texToBindTo == NULL) {
ssr_nLastError = SSR_ERR_BINDNULLTEX;
return;
}
ssr_pCurrentRenderContext->displayComponent.boundImage = texToBindTo;
}
SSRIMID ssrLoadBitmap(char* filePath) {
unsigned char (*imageBuffer)[4] = NULL;
ssrBitmapHelper(filePath, &imageBuffer);
return imageBuffer;
}
SSRIMID ssrLoadTarga(char* filePath) {
unsigned char (*imageBuffer)[4] = NULL;
ssrTargaHelper(filePath, &imageBuffer);
return imageBuffer;
}
void ssrUnloadIamge(SSRIMID imageId) {
unsigned char (*imageBuffer)[4] = (unsigned char(*)[4])imageId;
delete[] imageId;
}
SSRRC ssrCreateContext() {
ssr_nLastError = SSR_ERR_NONE;
PSSRCONTEXT context = new SSRCONTEXT();
context->displayComponent.imageBuffer = NULL;
context->displayComponent.depthBuffer = NULL;
context->displayComponent.clearColor = SSR_FTORGB(125, 125, 125);
context->displayComponent.boundImage = NULL;
context->windowsDisplayComponent.hdcDisplay = (HDC)NULL;
context->windowsDisplayComponent.hdcBitmap = (HDC)NULL;
context->matrixComponent.currentProjectionMatrix = 0;
context->matrixComponent.currentModelviewMatrix = 0;
context->matrixComponent.matrixMode = SSR_MODELVIEW;
for (int j = 0; j < 8; ++j) {
for (int i = 0; i < 16; ++i)
context->matrixComponent.projectionMatrixStack[j][i] = 0.0f;
context->matrixComponent.projectionMatrixStack[j][0] = context->matrixComponent.projectionMatrixStack[j][5] = 1.0f;
context->matrixComponent.projectionMatrixStack[j][10] = context->matrixComponent.projectionMatrixStack[j][15] = 1.0f;
}
for (int j = 0; j < 32; ++j) {
for (int i = 0; i < 16; ++i)
context->matrixComponent.modelviewMatrixStack[j][i] = 0.0f;
context->matrixComponent.modelviewMatrixStack[j][0] = context->matrixComponent.modelviewMatrixStack[j][5] = 1.0f;
context->matrixComponent.modelviewMatrixStack[j][10] = context->matrixComponent.modelviewMatrixStack[j][15] = 1.0f;
}
context->matrixComponent.projectionMode = 0;
context->renderInfoComponent.viewport[0] = context->renderInfoComponent.viewport[2] = 0;
context->renderInfoComponent.viewport[1] = 640; context->renderInfoComponent.viewport[3] = 320;
context->renderInfoComponent.cullDirection = SSR_BACK;
context->renderInfoComponent.imageWrapMode = SSR_CLAMP;
context->renderInfoComponent.perspectiveCompensate[0] = 0.0f;
context->renderInfoComponent.perspectiveCompensate[1] = 0.0f;
context->renderInfoComponent.normalizeValues[0] = 0.0f;
context->renderInfoComponent.normalizeValues[1] = 0.0f;
context->batchComponent.masterVertexList.clear();
context->batchComponent.batchType = SSR_TRIANGLE;
return context;
}
bool ssrDeleteContext(SSRRC ssrRc) {
if (ssrRc == NULL) {
ssr_nLastError = SSR_ERR_NORC;
return false;
}
if (((PSSRCONTEXT)ssrRc)->displayComponent.imageBuffer != NULL) {
ssr_nLastError = SSR_ERR_NORC;
return false;
}
ssr_nLastError = SSR_ERR_NONE;
((PSSRCONTEXT)ssrRc)->textOutputComponent.clear();
((PSSRCONTEXT)ssrRc)->batchComponent.masterVertexList.clear();
delete ssrRc;
return true;
}
bool ssrMakecurrent(HDC hDc, SSRRC ssrRc) {
if (ssrRc == NULL) {
if (ssr_pCurrentRenderContext != NULL) {
if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap != (HDC)NULL) {
SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld);
DeleteObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap);
DeleteDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap);
ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = (HDC)NULL;
if (ssr_pCurrentRenderContext->displayComponent.depthBuffer != NULL)
delete[] ssr_pCurrentRenderContext->displayComponent.depthBuffer;
ssr_pCurrentRenderContext->displayComponent.depthBuffer = NULL;
ssr_pCurrentRenderContext->displayComponent.imageBuffer = NULL;
}
}
return true;
}
if (ssrRc != NULL && ((PSSRCONTEXT)ssrRc)->windowsDisplayComponent.hdcDisplay != (HDC)NULL) {
ssr_nLastError = SSR_ERR_NORC;
return false;
}
if (ssrRc != NULL && ((PSSRCONTEXT)ssrRc)->displayComponent.imageBuffer != NULL) {
ssr_nLastError = SSR_ERR_NORC;
return false;
}
if (ssr_pCurrentRenderContext != NULL) {
if (ssr_pCurrentRenderContext->displayComponent.imageBuffer != NULL) {
if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap != (HDC)NULL) {
SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld);
DeleteObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap);
DeleteDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap);
ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = (HDC)NULL;
delete[] ssr_pCurrentRenderContext->displayComponent.depthBuffer;
ssr_pCurrentRenderContext->displayComponent.depthBuffer = NULL;
ssr_pCurrentRenderContext->displayComponent.imageBuffer = NULL;
}
}
}
((PSSRCONTEXT)ssrRc)->windowsDisplayComponent.hdcDisplay = hDc;
RECT clientRect;
if (WindowFromDC(hDc) == (HWND)NULL) {
ssr_nLastError = SSR_ERR_NOWND;
return false;
}
if (GetClientRect(WindowFromDC(hDc), &clientRect) == 0) {
ssr_nLastError = SSR_ERR_NOSIZE;
return false;
}
LONG width = (clientRect.right - clientRect.left);
LONG height = (clientRect.bottom - clientRect.top);
ssr_pCurrentRenderContext = (PSSRCONTEXT)ssrRc;
ssr_nLastError = SSR_ERR_NONE;
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmap.bmiHeader.biWidth = width;
bitmap.bmiHeader.biHeight = -1 * height;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 0;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
ssr_pCurrentRenderContext->displayComponent.depthBuffer = new float[width * height];
ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap = CreateDIBSection(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay, &bitmap, DIB_RGB_COLORS, (void**)&(ssr_pCurrentRenderContext->displayComponent.imageBuffer), NULL, 0);
if (ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap == 0)
cout << "Could not create device independent section\n";
ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = CreateCompatibleDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay);
if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap == 0)
cout << "Could not create compatible device context!";
ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld = (HBITMAP)SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap , ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap);
GetObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap , sizeof(BITMAP), &ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo);
if (ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap == 0)
cout << "Could not reselect bitmap";
return true;
}
SSRRC ssrGetCurrentContext() {
return ssr_pCurrentRenderContext;
}
HDC ssrGetCurrentDc() {
if (ssr_pCurrentRenderContext == NULL)
return (HDC)NULL;
return ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay;
}
void ssrMatrixMode(int matrixType) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (matrixType != SSR_MODELVIEW && SSR_MODELVIEW != SSR_PROJECTION) {
ssr_nLastError = SSR_ERR_INVARG;
return;
}
ssr_pCurrentRenderContext->matrixComponent.matrixMode = matrixType;
}
void ssrLoadIdentity() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = 0.0f;
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][0] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][5] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][10] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][15] = 1.0f;
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = 0.0f;
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][0] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][5] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][10] = 1.0f;
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][15] = 1.0f;
}
}
void ssrPushMatrix() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
++(ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix);
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
++(ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix);
}
}
void ssrPopMatrix() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
--(ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix);
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
--(ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix);
}
}
void ssrLoadMatrix(float* matrix) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = matrix[i];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = matrix[i];
}
}
void ssrMultMatrix(float* matrix) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
float scratch[16];
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], matrix, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], matrix, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i];
}
}
void ssrRotate(float* rotationVector) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
float accumulator[16];
float rotation[16];
float scratch[16];
for (int i = 0; i < 16; ++i) {
accumulator[i] = 0.0f;
scratch[i] = 0.0f;
}
accumulator[0] = accumulator[5] = accumulator[10] = accumulator[15] = 1.0f;
scratch[0] = scratch[5] = scratch[10] = scratch[15] = 1.0f;
if(rotationVector[0] != 0.0f) {
ssrMatrixMakeXRotation(rotationVector[0], rotation);
SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch);
for (int i = 0; i < 16; ++i)
accumulator[i] = scratch[i];
}
if(rotationVector[1] != 0.0f) {
ssrMatrixMakeYRotation(rotationVector[1], rotation);
SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch);
for (int i = 0; i < 16; ++i)
accumulator[i] = scratch[i];
}
if(rotationVector[2] != 0.0f) {
ssrMatrixMakeZRotation(rotationVector[2], rotation);
SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch);
for (int i = 0; i < 16; ++i)
accumulator[i] = scratch[i];
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], accumulator, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], accumulator, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i];
}
}
void ssrRotate(float x, float y, float z) {
float rotate[3] = {x, y, z};
ssrRotate(rotate);
}
void ssrScale(float* scaleVector) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
float scaleMatrix[16];
float scratch[16];
for (int i = 0; i < 16; ++i)
scaleMatrix[i] = 0.0f;
scaleMatrix[15] = 1.0f;
scaleMatrix[0] = scaleVector[0];
scaleMatrix[5] = scaleVector[1];
scaleMatrix[10] = scaleVector[2];
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], scaleMatrix, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], scaleMatrix, scratch);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i];
}
}
void ssrScale(float x, float y, float z) {
float scale[3] = {z, y, z};
ssrScale(scale);
}
void ssrTranslate(float x, float y, float z) {
float translate[3] = {x, y, z};
ssrTranslate(translate);
}
void ssrTranslate(float* translateVector) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][12] += translateVector[0];
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][13] += translateVector[1];
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][14] += translateVector[2];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][12] += translateVector[0];
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][13] += translateVector[1];
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][14] += translateVector[2];
}
}
void ssrMatrixMakeXRotation(float angle, float* matrix) {
while (angle > 360.0f)
angle -= 360.0f;
while (angle < 0)
angle += 360.0f;
angle *= SSR_DEG_TO_RAD;
for (int i = 0; i < 16; ++i)
matrix[i] = 0.0f;
matrix[0] = 1.0f;
matrix[5] = 1.0f;
matrix[10] = 1.0f;
matrix[15] = 1.0f;
matrix[5] = cosf(angle);
matrix[6] = sinf(angle);
matrix[9] = -1.0f * sinf(angle);
matrix[10] = cosf(angle);
}
void ssrMatrixMakeYRotation(float angle, float* matrix) {
while (angle > 360.0f)
angle -= 360.0f;
while (angle < 0)
angle += 360.0f;
angle *= SSR_DEG_TO_RAD;
for (int i = 0; i < 16; ++i)
matrix[i] = 0.0f;
matrix[0] = 1.0f;
matrix[5] = 1.0f;
matrix[10] = 1.0f;
matrix[15] = 1.0f;
matrix[0] = cosf(angle);
matrix[2] = -1.0f * sinf(angle);
matrix[8] = sinf(angle);
matrix[10] = cosf(angle);
}
void ssrMatrixMakeZRotation(float angle, float* matrix) {
while (angle > 360.0f)
angle -= 360.0f;
while (angle < 0)
angle += 360.0f;
angle *= SSR_DEG_TO_RAD;
for (int i = 0; i < 16; ++i)
matrix[i] = 0.0f;
matrix[0] = 1.0f;
matrix[5] = 1.0f;
matrix[10] = 1.0f;
matrix[15] = 1.0f;
matrix[0] = cosf(angle);
matrix[1] = sinf(angle);
matrix[4] = -1.0f * sinf(angle);
matrix[5] = cosf(angle);
}
void ssrTransformToScreenSpace() {
float modelViewProjectionMatrix[16];
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix], ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], modelViewProjectionMatrix);
int screenW = ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth;
int screenH = ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight;
int halfScreenW = (int)(ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * 0.5f);
int halfScreenH = (int)(ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight * 0.5);
for (int i = 0, imax = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < imax; ++i) {
float vertex[3] = { ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z };
float result[3];
SSR_VECTOR_MATRIX_MULTIPLY(vertex, modelViewProjectionMatrix, result);
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x = result[0];
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y = result[1];
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z = result[2];
}
for (int i = 0, imax = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < imax; ++i) {
float result[3] = { ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z };
if (ssr_pCurrentRenderContext->matrixComponent.projectionMode == SSR_ORTHO) { // Orthographic
result[0] = (result[0] + ssr_pCurrentRenderContext->renderInfoComponent.offset[0]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0];
result[1] = (result[1] + ssr_pCurrentRenderContext->renderInfoComponent.offset[1]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1];
} else if (ssr_pCurrentRenderContext->matrixComponent.projectionMode == SSR_PERSP) { // Perspective
result[0] = (result[0] * ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] / ((result[2] == 0.0f) ? -0.0001f : result[2]) + ssr_pCurrentRenderContext->renderInfoComponent.offset[0]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0];
result[1] = (-1.0f * result[1] * ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] / ((result[2] == 0.0f) ? -0.0001f : result[2]) + ssr_pCurrentRenderContext->renderInfoComponent.offset[1]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1];
} else {
ssr_nLastError = SSR_ERR_NOPROJSETUP;
return;
}
result[0] *= screenW;
result[1] *= screenH;
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x = result[0];
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y = result[1];
ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z = result[2];
}
}
void ssrPresentScene() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear();
int left = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_LEFT];
int top = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_TOP];
int right = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_RIGHT];
int bottom = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_BOTTOM];
int width = right - left; int height = bottom - top;
ssrDrawText();
BitBlt(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay, left, top, width, height, ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, 0, 0, SRCCOPY);
}
void ssrClear() {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
for (int j = 0; j < ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; ++j) {
for (int i = 0; i < ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; ++i) {
int index = (j * ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth + i);
ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = ssr_pCurrentRenderContext->displayComponent.clearColor;
ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = FLT_MAX;
}
}
}
void ssrCullFace(int cullMode) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (cullMode != SSR_FRONT && cullMode != SSR_BACK && cullMode != SSR_NOCULL) {
ssr_nLastError = SSR_ERR_INVARG;
return;
}
ssr_pCurrentRenderContext->renderInfoComponent.cullDirection = cullMode;
}
int ssrGetError() {
return ssr_nLastError;
}
void ssrWrapMode(int wrapMode) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode = wrapMode;
}
void ssrSortTriangle(float (*verts)[3], int* order) {
#define ay verts[0][1]
#define by verts[1][1]
#define cy verts[2][1]
// Find the lowest y
if (ay < by) {
if (ay < cy) {
order[0] = 0;
} else {
order[0] = 2;
}
} else {
if (by < cy) {
order[0] = 1;
} else {
order[0] = 2;
}
}
// Find the highest y
if (ay > by) {
if (ay > cy) {
order[2] = 0;
} else {
order[2] = 2;
}
} else {
if (by > cy) {
order[2] = 1;
} else {
order[2] = 2;
}
}
// Figure out middle y
order[1] = 3 - (order[0] + order[2]);
#undef ay
#undef by
#undef cy
}
bool ssrIsBackFacing(float* verts) {
#define x1 verts[0]
#define y1 verts[1]
#define z1 verts[2]
#define x2 verts[3]
#define y2 verts[4]
#define z2 verts[5]
#define x3 verts[6]
#define y3 verts[7]
#define z3 verts[8]
float d1x, d1y, d2x, d2y, z;
d1x = x3 - x1;
d1y = y3 - y1;
d2x = x3 - x2;
d2y = y3 - y2;
if (ssr_pCurrentRenderContext->renderInfoComponent.cullDirection == SSR_BACK) {
z = (d2x * d1y) - (d2y * d1x);
} else if (ssr_pCurrentRenderContext->renderInfoComponent.cullDirection == SSR_FRONT) {
z = (d1x * d2y) - (d1y * d2x);
} else {
return false;
}
return (z < 0.0f);
#undef x1
#undef x2
#undef x3
#undef y1
#undef y2
#undef y3
#undef z1
#undef z2
#undef z3
}
void ssrSortSplitAndSumbitTriangle(float (*triangle)[3]) {
int order[3]; float renderVerts[9];
renderVerts[0] = triangle[0][0];
renderVerts[1] = triangle[0][1];
renderVerts[2] = triangle[0][2];
renderVerts[3] = triangle[1][0];
renderVerts[4] = triangle[1][1];
renderVerts[5] = triangle[1][2];
renderVerts[6] = triangle[2][0];
renderVerts[7] = triangle[2][1];
renderVerts[8] = triangle[2][2];
if (ssrIsBackFacing(renderVerts))
return;
ssr_debugNumTriangles++;
ssrSortTriangle(triangle, order);
if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] &&
triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two
// new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1;
float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0];
float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2];
if (newX < triangle[order[1]][0]/* newX < x2 */) {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = newX;
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = newZ;
renderVerts[6] = triangle[firstBatch[1]][0];
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = triangle[firstBatch[1]][2];
ssrRenderBlackTriangle(renderVerts);
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
ssrRenderBlackTriangle(renderVerts);
} else {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = triangle[firstBatch[1]][0];
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = triangle[firstBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = newZ;
ssrRenderBlackTriangle(renderVerts);
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
ssrRenderBlackTriangle(renderVerts);
}
} else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat
if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2
int newOrder[3] = { order[2], order[1], order[0] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[2], order[0], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
ssrRenderBlackTriangle(renderVerts);
} else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat
if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3
int newOrder[3] = { order[0], order[1], order[2] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[0], order[2], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
ssrRenderBlackTriangle(renderVerts);
}
}
void ssrSortSplitSubmitColoredTriangle(float (*triangle)[3], float (*colors)[3]) {
int order[3]; float renderVerts[9];
renderVerts[0] = triangle[0][0];
renderVerts[1] = triangle[0][1];
renderVerts[2] = triangle[0][2];
renderVerts[3] = triangle[1][0];
renderVerts[4] = triangle[1][1];
renderVerts[5] = triangle[1][2];
renderVerts[6] = triangle[2][0];
renderVerts[7] = triangle[2][1];
renderVerts[8] = triangle[2][2];
if (ssrIsBackFacing(renderVerts))
return;
ssrSortTriangle(triangle, order); float color[3][3];
float nearPlane = ssr_pCurrentRenderContext->renderInfoComponent.offset[2];
if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] &&
triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two
// new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1;
float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0];
float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2];
float newColor[3]; float p;
if (newX < triangle[order[1]][0]/* newX < x2 */) {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = newX;
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = newZ;
renderVerts[6] = triangle[firstBatch[1]][0];
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = triangle[firstBatch[1]][2];
//////// Just figure out the new color....
float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]};
float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]};
float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]};
float whole = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ;
line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2];
float part = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
p = part / whole;
newColor[0] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][0], colors[secondBatch[0]][0], p));
newColor[1] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][1], colors[secondBatch[0]][1], p));
newColor[2] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][2], colors[secondBatch[0]][2], p));
//////// Found
color[0][0] = colors[firstBatch[0]][0];
color[0][1] = colors[firstBatch[0]][1];
color[0][2] = colors[firstBatch[0]][2];
color[1][0] = newColor[0];
color[1][1] = newColor[1];
color[1][2] = newColor[2];
color[2][0] = colors[firstBatch[1]][0];
color[2][1] = colors[firstBatch[1]][1];
color[2][2] = colors[firstBatch[1]][2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
color[0][0] = colors[secondBatch[0]][0];
color[0][1] = colors[secondBatch[0]][1];
color[0][2] = colors[secondBatch[0]][2];
color[1][0] = colors[secondBatch[1]][0];
color[1][1] = colors[secondBatch[1]][1];
color[1][2] = colors[secondBatch[1]][2];
color[2][0] = newColor[0];
color[2][1] = newColor[1];
color[2][2] = newColor[2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
} else {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
//////// Just figure out the new color....
float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]};
float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]};
float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]};
float whole = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ;
line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2];
float part = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
p = part / whole;
newColor[0] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][0], colors[secondBatch[0]][0], p));
newColor[1] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][1], colors[secondBatch[0]][1], p));
newColor[2] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][2], colors[secondBatch[0]][2], p));
//////// Found
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = triangle[firstBatch[1]][0];
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = triangle[firstBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = newZ;
color[0][0] = colors[firstBatch[0]][0];
color[0][1] = colors[firstBatch[0]][1];
color[0][2] = colors[firstBatch[0]][2];
color[1][0] = colors[firstBatch[1]][0];
color[1][1] = colors[firstBatch[1]][1];
color[1][2] = colors[firstBatch[1]][2];
color[2][0] = newColor[0];
color[2][1] = newColor[1];
color[2][2] = newColor[2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
color[0][0] = colors[secondBatch[0]][0];
color[0][1] = colors[secondBatch[0]][1];
color[0][2] = colors[secondBatch[0]][2];
color[1][0] = colors[secondBatch[1]][0];
color[1][1] = colors[secondBatch[1]][1];
color[1][2] = colors[secondBatch[1]][2];
color[2][0] = newColor[0];
color[2][1] = newColor[1];
color[2][2] = newColor[2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
}
} else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat
if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2
int newOrder[3] = { order[2], order[1], order[0] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[2], order[0], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
color[0][0] = colors[order[0]][0];
color[0][1] = colors[order[0]][1];
color[0][2] = colors[order[0]][2];
color[1][0] = colors[order[1]][0];
color[1][1] = colors[order[1]][1];
color[1][2] = colors[order[1]][2];
color[2][0] = colors[order[2]][0];
color[2][1] = colors[order[2]][1];
color[2][2] = colors[order[2]][2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
} else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat
if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3
int newOrder[3] = { order[0], order[1], order[2] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[0], order[2], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
color[0][0] = colors[order[0]][0];
color[0][1] = colors[order[0]][1];
color[0][2] = colors[order[0]][2];
color[1][0] = colors[order[1]][0];
color[1][1] = colors[order[1]][1];
color[1][2] = colors[order[1]][2];
color[2][0] = colors[order[2]][0];
color[2][1] = colors[order[2]][1];
color[2][2] = colors[order[2]][2];
if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) {
ssrRenderColoredTriangle(renderVerts, color);
}
}
}
void ssrSortSplitSubmitTexturedTriangle(float (*triangle)[3], float (*uvs)[2]) {
int order[3]; float renderVerts[9]; float sumbituvs[6];
renderVerts[0] = triangle[0][0];
renderVerts[1] = triangle[0][1];
renderVerts[2] = triangle[0][2];
renderVerts[3] = triangle[1][0];
renderVerts[4] = triangle[1][1];
renderVerts[5] = triangle[1][2];
renderVerts[6] = triangle[2][0];
renderVerts[7] = triangle[2][1];
renderVerts[8] = triangle[2][2];
if (ssrIsBackFacing(renderVerts))
return;
ssr_debugNumTriangles++;
ssrSortTriangle(triangle, order);
if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] &&
triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two
// new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1;
float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0];
float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2];
float newU, newV, p;
if (newX < triangle[order[1]][0]/* newX < x2 */) {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
//////// Just figure out the new texture coords....
float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]};
float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]};
float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]};
float whole = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ;
line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2];
float part = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
p = part / whole;
newU = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][0], uvs[secondBatch[0]][0], p));
newV = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][1], uvs[secondBatch[0]][1], p));
//////// Found
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = newX;
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = newZ;
renderVerts[6] = triangle[firstBatch[1]][0];
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = triangle[firstBatch[1]][2];
sumbituvs[0] = uvs[firstBatch[0]][0];
sumbituvs[1] = uvs[firstBatch[0]][1];
sumbituvs[2] = newU;
sumbituvs[3] = newV;
sumbituvs[4] = uvs[firstBatch[1]][0];
sumbituvs[5] = uvs[firstBatch[1]][1];
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
sumbituvs[0] = uvs[secondBatch[0]][0];
sumbituvs[1] = uvs[secondBatch[0]][1];
sumbituvs[2] = uvs[secondBatch[1]][0];
sumbituvs[3] = uvs[secondBatch[1]][1];
sumbituvs[4] = newU;
sumbituvs[5] = newV;
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
} else {
int firstBatch[3] = { order[0], order[1], order[1] };
int secondBatch[3] = { order[2], order[1], order[1] };
//////// Just figure out the new texture coords....
float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]};
float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]};
float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]};
float whole = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ;
line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2];
float part = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) );
p = part / whole;
newU = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][0], uvs[secondBatch[0]][0], p));
newV = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][1], uvs[secondBatch[0]][1], p));
//////// Found
renderVerts[0] = triangle[firstBatch[0]][0];
renderVerts[1] = triangle[firstBatch[0]][1];
renderVerts[2] = triangle[firstBatch[0]][2];
renderVerts[3] = triangle[firstBatch[1]][0];
renderVerts[4] = triangle[firstBatch[1]][1];
renderVerts[5] = triangle[firstBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[firstBatch[1]][1];
renderVerts[8] = newZ;
sumbituvs[0] = uvs[firstBatch[0]][0];
sumbituvs[1] = uvs[firstBatch[0]][1];
sumbituvs[2] = uvs[firstBatch[1]][0];
sumbituvs[3] = uvs[firstBatch[1]][1];
sumbituvs[4] = newU;
sumbituvs[5] = newV;
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
renderVerts[0] = triangle[secondBatch[0]][0];
renderVerts[1] = triangle[secondBatch[0]][1];
renderVerts[2] = triangle[secondBatch[0]][2];
renderVerts[3] = triangle[secondBatch[1]][0];
renderVerts[4] = triangle[secondBatch[1]][1];
renderVerts[5] = triangle[secondBatch[1]][2];
renderVerts[6] = newX;
renderVerts[7] = triangle[secondBatch[1]][1];
renderVerts[8] = newZ;
sumbituvs[0] = uvs[secondBatch[0]][0];
sumbituvs[1] = uvs[secondBatch[0]][1];
sumbituvs[2] = uvs[secondBatch[1]][0];
sumbituvs[3] = uvs[secondBatch[1]][1];
sumbituvs[4] = newU;
sumbituvs[5] = newV;
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
}
} else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat
if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2
int newOrder[3] = { order[2], order[1], order[0] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[2], order[0], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
sumbituvs[0] = uvs[order[0]][0];
sumbituvs[1] = uvs[order[0]][1];
sumbituvs[2] = uvs[order[1]][0];
sumbituvs[3] = uvs[order[1]][1];
sumbituvs[4] = uvs[order[2]][0];
sumbituvs[5] = uvs[order[2]][1];
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
} else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat
if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3
int newOrder[3] = { order[0], order[1], order[2] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
} else {
int newOrder[3] = { order[0], order[2], order[1] };
order[0] = newOrder[0];
order[1] = newOrder[1];
order[2] = newOrder[2];
}
renderVerts[0] = triangle[order[0]][0];
renderVerts[1] = triangle[order[0]][1];
renderVerts[2] = triangle[order[0]][2];
renderVerts[3] = triangle[order[1]][0];
renderVerts[4] = triangle[order[1]][1];
renderVerts[5] = triangle[order[1]][2];
renderVerts[6] = triangle[order[2]][0];
renderVerts[7] = triangle[order[2]][1];
renderVerts[8] = triangle[order[2]][2];
sumbituvs[0] = uvs[order[0]][0];
sumbituvs[1] = uvs[order[0]][1];
sumbituvs[2] = uvs[order[1]][0];
sumbituvs[3] = uvs[order[1]][1];
sumbituvs[4] = uvs[order[2]][0];
sumbituvs[5] = uvs[order[2]][1];
ssrRenderTexturedTriangle(renderVerts, sumbituvs);
}
}
void ssrTargaHelper(char* imagePath, unsigned char (*videoArea[])[4]) {
FILE *pFile;
TGAHEADER tgaHeader;
unsigned long lImageSize;
short sDepth;
pFile = fopen(imagePath, "rb");
if(pFile == NULL) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
return;
}
fread(&tgaHeader, 18, 1, pFile);
sDepth = tgaHeader.bits / 8;
if(tgaHeader.bits != 32) {
ssr_nLastError = SSR_ERR_TARGABITSOFF;
fclose(pFile);
return;
}
if (sDepth != 4) {
ssr_nLastError = SSR_ERR_TARGABITSOFF;
fclose(pFile);
return ;
}
lImageSize = tgaHeader.width * tgaHeader.height * sDepth;
int h = tgaHeader.height;
int w = tgaHeader.width;
*videoArea = new unsigned char[w * h + 2][4];
(*videoArea)[0][0] = (w ) & 0xff;
(*videoArea)[0][1] = (w >> 8) & 0xff;
(*videoArea)[0][2] = (w >> 16) & 0xff;
(*videoArea)[0][3] = (w >> 24) & 0xff;
(*videoArea)[1][0] = (h ) & 0xff;
(*videoArea)[1][1] = (h >> 8) & 0xff;
(*videoArea)[1][2] = (h >> 16) & 0xff;
(*videoArea)[1][3] = (h >> 24) & 0xff;
for (int j = h - 1; j >= 0; --j) {
for (int i = 0; i < w; ++i) {
unsigned char bgra[4];
if (fread(bgra, 1, 4, pFile) != 4) {
ssr_nLastError = SSR_ERR_NOREADIMAGE;
fclose(pFile);
return;
}
int index = (j * w + i) + 2;
(*videoArea)[index][0] = bgra[2];
(*videoArea)[index][1] = bgra[1];
(*videoArea)[index][2] = bgra[0];
(*videoArea)[index][3] = bgra[3];
}
}
fclose(pFile);
}
void ssrDrawTexturedLine(float x1, float x2, float y, float z1, float z2, float u_left, float v_left, float u_right, float v_right) {
if (x1 > x2) {
float temp = x1;
x1 = x2;
x2 = temp;
temp = z1;
z1 = z2;
z2 = temp;
temp = u_left;
u_left = u_right;
u_right = temp;
temp = v_left;
v_left = v_right;
v_right = temp;
}
x1 -= 1;
x2 += 1;
unsigned char (*bound)[4] = (unsigned char(*)[4])ssr_pCurrentRenderContext->displayComponent.boundImage;
unsigned int w = (bound[0][0]) | (bound[0][1] << 8) | (bound[0][2] << 16) | (bound[0][3] << 24);
unsigned int h = (bound[1][0]) | (bound[1][1] << 8) | (bound[1][2] << 16) | (bound[1][3] << 24);
int outOne = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1;
int outTwo = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1;
int outThree = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight;
for (int x = (int)x1, xmax = (int)x2; x < xmax; ++x) {
if (x > outOne) continue;
if (x < 0) continue;
if (y < 0) continue;
if (y > outTwo) continue;
int index = (int)y * (outOne + 1) + x;
if (index < 0) continue;
if (index > outThree) continue;
float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1));
float z = SSR_FLERP(z1, z2, p);
if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue;
int access = 0;
if (ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode == SSR_CLAMP) {
access = (int)(ssrClampToZeroOne(SSR_FLERP(v_left, v_right, p)) * h) * w + (int)(ssrClampToZeroOne(SSR_FLERP(u_left, u_right, p)) * w) + 2;
} else {
while (v_left < 0.0f) v_left += 1.0f;
while (v_left > 1.0f) v_left -= 1.0f;
while (v_right < 0.0f) v_right += 1.0f;
while (v_right > 1.0f) v_right -= 1.0f;
while (u_left < 0.0f) u_left += 1.0f;
while (u_left > 1.0f) u_left -= 1.0f;
while (u_right < 0.0f) u_right += 1.0f;
while (u_right > 1.0f) u_right -= 1.0f;
access = (int)(
ssrClampToZeroOne(SSR_FLERP(v_left, v_right, p)) * h
) * w + (int)(
ssrClampToZeroOne(SSR_FLERP(u_left, u_right, p)) * w
) + 2;
}
COLORREF pixel_color = SSR_ARGB(bound[access][3], bound[access][0], bound[access][1], bound[access][2]);
if (bound[access][3] != 255) {
COLORREF existing_pixel = ssr_pCurrentRenderContext->displayComponent.imageBuffer[index];
unsigned char dr = SSR_GETR(existing_pixel);
unsigned char dg = SSR_GETG(existing_pixel);
unsigned char db = SSR_GETB(existing_pixel);
db = (bound[access][3] * (bound[access][2] - db))/255 + db;
dg = (bound[access][3] * (bound[access][1] - dg))/255 + dg;
dr = (bound[access][3] * (bound[access][0] - dr))/255 + dr;
ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_ARGB(255, dr, dg, db);
} else {
ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = pixel_color;
}
ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z;
}
}
void ssrRenderTexturedTriangle(float* verts, float * uvs) {
#define x1 ((int)verts[0])
#define y1 ((int)verts[1])
#define z1 (verts[2])
#define x2 ((int)verts[3])
#define y2 ((int)verts[4])
#define z2 (verts[5])
#define x3 ((int)verts[6])
#define y3 ((int)verts[7])
#define z3 (verts[8])
#define u1 uvs[0]
#define v1 uvs[1]
#define u2 uvs[2]
#define v2 uvs[3]
#define u3 uvs[4]
#define v3 uvs[5]
float slope_left, slope_right;
float left, right;
float height = (float)(y3 - y1);
if (height == 0.0f)
return;
float reciprical = 1.0f / height;
slope_left = ((float)(x2 - x1)) * reciprical;
slope_right = ((float)(x3 - x1)) * reciprical;
left = right = (float)x1;
float uv_left[2] = { u1, v1};
float uv_right[2] = { u1, v1};
float uv_left_slope[2] = { (u2 - u1) * reciprical, (v2 - v1) * reciprical};
float uv_right_slope[2] = {(u3 - u1) * reciprical, (v3 - v1) * reciprical};
float z_left;
float z_right;
z_left = z_right = z1;
float z_slope_left = ((float)(z2 - z1)) * reciprical;
float z_slope_right = ((float)(z3 - z1)) * reciprical;
if (y1 < y3) {
for (int y = y1; y < y3; ++y) {
ssrDrawTexturedLine(left, right, (float)y, z_left, z_right, uv_left[0], uv_left[1], uv_right[0], uv_right[1]);
uv_left[0] += uv_left_slope[0];
uv_left[1] += uv_left_slope[1];
uv_right[0] += uv_right_slope[0];
uv_right[1] += uv_right_slope[1];
left += slope_left;
right += slope_right;
z_left += z_slope_left;
z_right += z_slope_right;
}
} else {
for (int y = (y1); y >= (y3); --y) {
ssrDrawTexturedLine(left, right, (float)y, z_left, z_right, uv_left[0], uv_left[1], uv_right[0], uv_right[1]);
uv_left[0] -= uv_left_slope[0];
uv_left[1] -= uv_left_slope[1];
uv_right[0] -= uv_right_slope[0];
uv_right[1] -= uv_right_slope[1];
left -= slope_left;
right -= slope_right;
z_left -= z_slope_left;
z_right -= z_slope_right;
}
}
#undef x1
#undef x2
#undef x3
#undef y1
#undef y2
#undef y3
#undef z1
#undef z2
#undef z3
#undef u1
#undef u2
#undef u3
#undef v1
#undef v2
#undef v3
}
float ssrClampToZeroOne(float f) {
if (f < 0.0f) return 0.0f;
if (f > 1.0f) return 1.0f;
return f;
}
float* ssrClampToZeroOne(float* f) {
if (f[0] < 0.0f) f[0] = 0.0f;
if (f[0] > 1.0f) f[0] = 1.0f;
if (f[1] < 0.0f) f[1] = 0.0f;
if (f[1] > 1.0f) f[1] = 1.0f;
if (f[2] < 0.0f) f[2] = 0.0f;
if (f[2] > 1.0f) f[2] = 1.0f;
return f;
}
int ssrGet32(FILE *f) {
unsigned long num;
unsigned char bytes[4];
fread(bytes, 1, 4, f);
num = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
return (int) num;
}
int ssrGet16(FILE *f) {
unsigned short num;
unsigned char bytes[2];
fread(bytes, 1, 2, f);
num = (bytes[1] << 8) | bytes[0];
return (int) num;
}
int ssrNextPowerOf2(int n) {
int pow;
for (pow = 1; pow < n; pow <<= 1);
return pow;
}
void ssrLookAt(float* _position, float* _forward, float* _up) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
float m[16], r[16];
float x[3], y[3], z[3];
float mag;
/* Z vector */
z[0] = _position[0] - _forward[0];
z[1] = _position[1] - _forward[1];
z[2] = _position[2] - _forward[2];
mag = sqrtf(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) {
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}
/* Y vector */
y[0] = _up[0];
y[1] = _up[1];
y[2] = _up[2];
/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];
/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/
mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
if (mag) {
x[0] /= mag;
x[1] /= mag;
x[2] /= mag;
}
mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
if (mag) {
y[0] /= mag;
y[1] /= mag;
y[2] /= mag;
}
m[0] = x[0];
m[1] = x[1];
m[2] = x[2];
m[3] = 0.0;
m[4] = y[0];
m[5] = y[1];
m[6] = y[2];
m[7] = 0.0;
m[8] = z[0];
m[9] = z[1];
m[10] = z[2];
m[11] = 0.0;
m[12] = 0.0;
m[13] = 0.0;
m[14] = 0.0;
m[15] = 1.0;
if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], m, r);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = r[i];
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][12] += -_position[0];
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][13] += -_position[1];
ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][14] += -_position[2];
} else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) {
SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], m, r);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = r[i];
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][12] += -_position[0];
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][13] += -_position[1];
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][14] += -_position[2];
}
}
void ssrFrustum(float left, float right, float bottom, float top, float near_, float far_) {
// Via http://msdn.microsoft.com/en-us/library/dd373537(v=vs.85).aspx (Matrix transposed)
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
float projectionMatrix[16];
for (int i = 0; i < 16; ++i)
projectionMatrix[i] = 0.0f;
projectionMatrix[0] = projectionMatrix[5] = 1.0f;
projectionMatrix[10] = projectionMatrix[15] = 1.0f;
projectionMatrix[0] = (2.0f * near_) / (right - left);
projectionMatrix[5] = (2.0f * near_) / (top - bottom);
projectionMatrix[8] = (right + left) / (right - left);
projectionMatrix[9] = (top + bottom) / (top - bottom);
projectionMatrix[10] = -1.0f * ((far_ + near_) / (far_ - near_));
projectionMatrix[11] = -1.0f;
projectionMatrix[14] = -1.0f * ((2.0f * (far_ + near_)) / (far_ - near_));
projectionMatrix[15] = 0.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[0] = (right - left) / 2.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[1] = (top - bottom) / 2.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[2] = near_;
ssr_pCurrentRenderContext->renderInfoComponent.offset[3] = far_;
ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[0] * 2);
ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[1] * 2);
ssr_pCurrentRenderContext->matrixComponent.projectionMode = SSR_PERSP;
float FOV = float(atanf(top / near_)) * SSR_RAD_TO_DEG * 2.0f;
ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] = ssr_pCurrentRenderContext->renderInfoComponent.offset[0] / tanf(FOV * 0.5f);
ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] = ssr_pCurrentRenderContext->renderInfoComponent.offset[1] / tanf(FOV * 0.5f);
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = projectionMatrix[i];
}
void ssrPerspective(float fov, float aspect, float near_, float far_) {
float top = near_ * float(tanf(fov * 3.14159265f / 360.0f));
float bottom = -1.0f * top;
float left = bottom * aspect;
float right = -1.0f * left;
ssrFrustum(left, right, bottom, top, near_, far_);
ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] = ssr_pCurrentRenderContext->renderInfoComponent.offset[0] / tanf(fov * 0.5f);
ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] = ssr_pCurrentRenderContext->renderInfoComponent.offset[1] / tanf(fov * 0.5f);
}
void ssrOrtho(float left, float right, float bottom, float top, float _near, float _far) {
float projectionMatrix[16];
projectionMatrix[0] = 2.0f / (right - left);
projectionMatrix[1] = 0.0f;
projectionMatrix[2] = 0.0f;
projectionMatrix[3] = 0.0f;
projectionMatrix[4] = 0.0f;
projectionMatrix[5] = 2.0f / (top - bottom);
projectionMatrix[6] = 0.0f;
projectionMatrix[7] = 0.0f;
projectionMatrix[8] = 0.0f;
projectionMatrix[9] = 0.0f;
projectionMatrix[10] = -2.0f / (_far - _near);
projectionMatrix[11] = 0.0f;
projectionMatrix[12] = (right + left) / (right - left);
projectionMatrix[13] = (top + bottom) / (top - bottom);
projectionMatrix[14] = (_far + _near) / (_far - _near);
projectionMatrix[15] = 1.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[0] = (right - left) / 2.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[1] = (top - bottom) / 2.0f;
ssr_pCurrentRenderContext->renderInfoComponent.offset[2] = _near;
ssr_pCurrentRenderContext->renderInfoComponent.offset[3] = _far;
ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[0] * 2);
ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[1] * 2);
ssr_pCurrentRenderContext->matrixComponent.projectionMode = SSR_ORTHO;
for (int i = 0; i < 16; ++i)
ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = projectionMatrix[i];
}
void ssrViewport(int x, int y, int width, int height) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (x < 0) x = 0;
if (y < 0) y = 0;
if (width == 0) width = 1;
if (height == 0) height = 1;
if (x + width > ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth) {
x -= 1;
width = 1;
}
if (y + height > ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight) {
y -= 1;
height = 1;
}
ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_LEFT] = x;
ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_TOP] = y;
ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_RIGHT] = x + width;
ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_BOTTOM] = y + height;
}
void ssrClearColor(float r, float g, float b) {
if (ssr_pCurrentRenderContext == NULL) {
ssr_nLastError = SSR_ERR_GLRC;
return;
}
if (r > 1.0f) r = 1.0f;
if (g > 1.0f) g = 1.0f;
if (b > 1.0f) b = 1.0f;
if (r < 0.0f) r = 0.0f;
if (g < 0.0f) g = 0.0f;
if (b < 0.0f) b = 0.0f;
ssr_pCurrentRenderContext->displayComponent.clearColor = SSR_FTORGB(r, g, b);
}
static unsigned char ssr_chFont[1533][4] = {
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
{255, 255, 255, 255}
};
SSRIMID ssrGetFont() {
return ssr_chFont;
}
void ssrRenderFont(PSSRTEXT toDraw) {
int current_x = toDraw->x;
int current_y = toDraw->y;
int top = 0;
int left = 0;
int width = 0;
int height = 0;
for (int i = 0, max = toDraw->displayString.size(); i < max; ++i) {
if (toDraw->displayString[i] == '\0')
break;
switch (toDraw->displayString[i]) {
case 'a':
case 'A':
top = 1; left = 1;
width = 5; height = 5;
break;
case 'b':
case 'B':
top = 1; left = 7;
width = 5; height = 5;
break;
case 'c':
case 'C':
top = 1; left = 13;
width = 5; height = 5;
break;
case 'd':
case 'D':
top = 1; left = 19;
width = 5; height = 5;
break;
case 'e':
case 'E':
top = 1; left = 25;
width = 5; height = 5;
break;
case 'f':
case 'F':
top = 1; left = 31;
width = 5; height = 5;
break;
case 'g':
case 'G':
top = 1; left = 37;
width = 5; height = 5;
break;
case 'h':
case 'H':
top = 1; left = 43;
width = 5; height = 5;
break;
case 'i':
case 'I':
top = 1; left = 49;
width = 5; height = 5;
break;
case 'j':
case 'J':
top = 1; left = 55;
width = 5; height = 5;
break;
case 'k':
case 'K':
top = 1; left = 61;
width = 5; height = 5;
break;
case 'l':
case 'L':
top = 1; left = 67;
width = 5; height = 5;
break;
case 'm':
case 'M':
top = 1; left = 73;
width = 5; height = 5;
break;
case 'n':
case 'N':
top = 1; left = 80;
width = 5; height = 5;
break;
case 'o':
case 'O':
top = 1; left = 86;
width = 5; height = 5;
break;
case 'p':
case 'P':
top = 1; left = 92;
width = 5; height = 5;
break;
case 'q':
case 'Q':
top = 1; left = 98;
width = 5; height = 6;
break;
case 'r':
case 'R':
top = 1; left = 104;
width = 5; height = 5;
break;
case 's':
case 'S':
top = 1; left = 110;
width = 5; height = 5;
break;
case 't':
case 'T':
top = 1; left = 116;
width = 5; height = 5;
break;
case 'u':
case 'U':
top = 1; left = 122;
width = 5; height = 5;
break;
case 'v':
case 'V':
top = 1; left = 128;
width = 5; height = 5;
break;
case 'w':
case 'W':
top = 1; left = 134;
width = 5; height = 5;
break;
case 'x':
case 'X':
top = 1; left = 140;
width = 5; height = 5;
break;
case 'y':
case 'Y':
top = 1; left = 146;
width = 5; height = 5;
break;
case 'z':
case 'Z':
top = 1; left = 153;
width = 5; height = 5;
break;
case '0':
top = 1; left = 161;
width = 5; height = 5;
break;
case '1':
top = 1; left = 167;
width = 2; height = 5;
break;
case '2':
top = 1; left = 170;
width = 5; height = 5;
break;
case '3':
top = 1; left = 176;
width = 5; height = 5;
break;
case '4':
top = 1; left = 182;
width = 5; height = 5;
break;
case '5':
top = 1; left = 188;
width = 5; height = 5;
break;
case '6':
top = 1; left = 194;
width = 5; height = 5;
break;
case '7':
top = 1; left = 200;
width = 5; height = 5;
break;
case '8':
top = 1; left = 206;
width = 5; height = 5;
break;
case '9':
top = 1; left = 212;
width = 5; height = 5;
break;
}
if (toDraw->displayString[i] == '\n') {
current_y += 7;
current_x = toDraw->x;
continue;
} else if (toDraw->displayString[i] == ' ') {
current_x += 4;
continue;
}
int font_width = 220;
int stage_width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth;
int stage_height = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight;
for (int k = 0; k < 7; ++k) {
for (int j = left; j < left + width; ++j) {
int index = ((6 - k) * font_width + j);
if (ssr_chFont[index][0] == 0) {
int stage_y = stage_height - (current_y + k);
int stage_x = current_x + (j - left);
int stage_index = stage_y * stage_width + stage_x;
ssr_pCurrentRenderContext->displayComponent.imageBuffer[stage_index] = toDraw->color;
}
}
}
current_x += width + 1;
}
}
void ssrDrawText() {
for (unsigned int i = 0, max = ssr_pCurrentRenderContext->textOutputComponent.size(); i < max; ++i)
ssrRenderFont(&(ssr_pCurrentRenderContext->textOutputComponent[i]));
ssr_pCurrentRenderContext->textOutputComponent.clear();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment