aboutsummaryrefslogtreecommitdiff
path: root/engines/sludge/sprites.cpp
diff options
context:
space:
mode:
authoryinsimei2017-05-26 05:24:38 +0200
committerEugene Sandulenko2017-07-13 18:27:45 +0200
commit219044abf9841461043d6e2acf0d5a48a7c7648b (patch)
treee9d16f9de2317e3596da5a71447e0c823ba3861d /engines/sludge/sprites.cpp
parent94439e2ce311734bfe7bb5700a6584b7550ea8f9 (diff)
downloadscummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.tar.gz
scummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.tar.bz2
scummvm-rg350-219044abf9841461043d6e2acf0d5a48a7c7648b.zip
SLUDGE: Add sludge files and make it compile
Diffstat (limited to 'engines/sludge/sprites.cpp')
-rw-r--r--engines/sludge/sprites.cpp1111
1 files changed, 1111 insertions, 0 deletions
diff --git a/engines/sludge/sprites.cpp b/engines/sludge/sprites.cpp
new file mode 100644
index 0000000000..43ddcbe8a1
--- /dev/null
+++ b/engines/sludge/sprites.cpp
@@ -0,0 +1,1111 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#if 0
+#if defined __unix__ && !(defined __APPLE__)
+#include <png.h>
+#else
+#include <libpng/png.h>
+#endif
+#endif
+
+#include <string.h>
+
+#include "allfiles.h"
+
+#include "fileset.h"
+#include "people.h"
+#include "sprites.h"
+#include "moreio.h"
+#include "newfatal.h"
+#include "colours.h"
+#include "backdrop.h"
+#include "sludger.h"
+#include "zbuffer.h"
+#include "debug.h"
+#include "graphics.h"
+
+#include "shaders.h"
+
+extern zBufferData zBuffer;
+
+#if 0
+extern GLuint backdropTextureName;
+#endif
+
+extern inputType input;
+extern int cameraX, cameraY;
+extern float cameraZoom;
+
+unsigned char currentBurnR = 0, currentBurnG = 0, currentBurnB = 0;
+
+
+void forgetSpriteBank(spriteBank &forgetme) {
+#if 0
+ deleteTextures(forgetme.myPalette.numTextures, forgetme.myPalette.tex_names);
+ if (forgetme.isFont) {
+ deleteTextures(forgetme.myPalette.numTextures, forgetme.myPalette.burnTex_names);
+ delete [] forgetme.myPalette.burnTex_names;
+ forgetme.myPalette.burnTex_names = NULL;
+ }
+
+ delete [] forgetme.myPalette.tex_names;
+ forgetme.myPalette.tex_names = NULL;
+#endif
+ delete [] forgetme.myPalette.tex_w;
+ forgetme.myPalette.tex_w = NULL;
+ delete [] forgetme.myPalette.tex_h;
+ forgetme.myPalette.tex_h = NULL;
+
+ if (forgetme.myPalette.pal) {
+ delete [] forgetme.myPalette.pal;
+ forgetme.myPalette.pal = NULL;
+ delete [] forgetme.myPalette.r;
+ forgetme.myPalette.r = NULL;
+ delete [] forgetme.myPalette.g;
+ forgetme.myPalette.g = NULL;
+ delete [] forgetme.myPalette.b;
+ forgetme.myPalette.b = NULL;
+ }
+
+ delete forgetme.sprites;
+ forgetme.sprites = NULL;
+
+
+ // TODO: also remove sprite bank from allLoadedBanks
+ // And add a function call for this function to the scripting language
+}
+
+bool reserveSpritePal(spritePalette &sP, int n) {
+ if (sP.pal) {
+ delete [] sP.pal;
+ delete [] sP.r;
+ delete [] sP.g;
+ delete [] sP.b;
+ }
+
+ sP.pal = new unsigned short int [n];
+ if (! checkNew(sP.pal)) return false;
+
+ sP.r = new unsigned char [n];
+ if (! checkNew(sP.r)) return false;
+ sP.g = new unsigned char [n];
+ if (! checkNew(sP.g)) return false;
+ sP.b = new unsigned char [n];
+ if (! checkNew(sP.b)) return false;
+ sP.total = n;
+ return (bool)(sP.pal != NULL) && (sP.r != NULL) && (sP.g != NULL) && (sP.b != NULL);
+}
+
+bool loadSpriteBank(int fileNum, spriteBank &loadhere, bool isFont) {
+#if ALLOW_FILE
+ int i, tex_num, total, picwidth, picheight, spriteBankVersion = 0, howmany = 0, startIndex = 0;
+ int *totalwidth, * maxheight;
+ int numTextures = 0;
+ byte *data;
+
+ setResourceForFatal(fileNum);
+ if (! openFileFromNum(fileNum)) return fatal("Can't open sprite bank / font");
+
+ loadhere.isFont = isFont;
+
+ total = get2bytes(bigDataFile);
+ if (! total) {
+ spriteBankVersion = fgetc(bigDataFile);
+ if (spriteBankVersion == 1) {
+ total = 0;
+ } else {
+ total = get2bytes(bigDataFile);
+ }
+ }
+
+ if (total <= 0) return fatal("No sprites in bank or invalid sprite bank file");
+ if (spriteBankVersion > 3) return fatal("Unsupported sprite bank file format");
+
+ loadhere.total = total;
+ loadhere.sprites = new sprite [total];
+ if (! checkNew(loadhere.sprites)) return false;
+ byte **spriteData = new byte * [total];
+ if (! checkNew(spriteData)) return false;
+
+ totalwidth = new int[total];
+ if (! checkNew(totalwidth)) return false;
+
+ maxheight = new int[total];
+ if (! checkNew(maxheight)) return false;
+
+ loadhere.myPalette.tex_names = new GLuint [total];
+ if (! checkNew(loadhere.myPalette.tex_names)) return false;
+
+ if (isFont) {
+ loadhere.myPalette.burnTex_names = new GLuint [total];
+ if (! checkNew(loadhere.myPalette.burnTex_names)) return false;
+ }
+ loadhere.myPalette.tex_w = new int [total];
+ if (! checkNew(loadhere.myPalette.tex_w)) return false;
+ loadhere.myPalette.tex_h = new int [total];
+ if (! checkNew(loadhere.myPalette.tex_h)) return false;
+
+ if (spriteBankVersion && spriteBankVersion < 3) {
+ howmany = fgetc(bigDataFile);
+ startIndex = 1;
+ }
+
+ totalwidth[0] = maxheight[0] = 1;
+
+ for (i = 0; i < total; i ++) {
+ switch (spriteBankVersion) {
+ case 3: {
+ loadhere.sprites[i].xhot = getSigned(bigDataFile);
+ loadhere.sprites[i].yhot = getSigned(bigDataFile);
+
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ return fatal("Can't open sprite bank / font.");
+ }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
+ return fatal("Can't open sprite bank / font.");
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (!end_info) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ return fatal("Can't open sprite bank / font.");
+ }
+ png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read
+ png_set_sig_bytes(png_ptr, 8); // No sig
+
+ png_read_info(png_ptr, info_ptr);
+
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type, compression_type, filter_method;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method);
+
+ int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+
+ unsigned char *row_pointers[height];
+ spriteData[i] = new unsigned char [rowbytes * height];
+ if (! checkNew(spriteData[i])) return false;
+
+ for (unsigned int row = 0; row < height; row++)
+ row_pointers[row] = spriteData[i] + row * rowbytes;
+
+ png_read_image(png_ptr, (png_byte **) row_pointers);
+ png_read_end(png_ptr, NULL);
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+
+ picwidth = loadhere.sprites[i].width = width;
+ picheight = loadhere.sprites[i].height = height;
+ break;
+ }
+ case 2:
+ picwidth = get2bytes(bigDataFile);
+ picheight = get2bytes(bigDataFile);
+ loadhere.sprites[i].xhot = getSigned(bigDataFile);
+ loadhere.sprites[i].yhot = getSigned(bigDataFile);
+ break;
+
+ default:
+ picwidth = (byte) fgetc(bigDataFile);
+ picheight = (byte) fgetc(bigDataFile);
+ loadhere.sprites[i].xhot = fgetc(bigDataFile);
+ loadhere.sprites[i].yhot = fgetc(bigDataFile);
+ break;
+ }
+
+ if (((picwidth > 511) && (totalwidth[numTextures] + picwidth < 2047)) || ((picwidth < 511) && (totalwidth[numTextures] + picwidth < 511))) {
+ loadhere.sprites[i].tex_x = totalwidth[numTextures];
+ totalwidth[numTextures] += (loadhere.sprites[i].width = picwidth) + 1;
+ if ((loadhere.sprites[i].height = picheight) + 2 > maxheight[numTextures]) maxheight[numTextures] = picheight + 2;
+ } else {
+ numTextures++;
+ if (numTextures > 255) return fatal("Can't open sprite bank / font - it's too big.");
+ loadhere.sprites[i].tex_x = 0;
+ totalwidth[numTextures] = (loadhere.sprites[i].width = picwidth);
+ maxheight[numTextures] = loadhere.sprites[i].height = picheight;
+ }
+ loadhere.sprites[i].texNum = numTextures;
+
+ if (spriteBankVersion < 3) {
+ data = (byte *) new byte [picwidth * (picheight + 1)];
+ if (! checkNew(data)) return false;
+ int ooo = picwidth * picheight;
+ for (int tt = 0; tt < picwidth; tt ++) {
+ data[ooo ++] = 0;
+ }
+ spriteData[i] = data;
+ switch (spriteBankVersion) {
+ case 2: { // RUN LENGTH COMPRESSED DATA
+ unsigned size = picwidth * picheight;
+ unsigned pip = 0;
+
+ while (pip < size) {
+ byte col = fgetc(bigDataFile);
+ int looper;
+
+ if (col > howmany) {
+ col -= howmany + 1;
+ looper = fgetc(bigDataFile) + 1;
+ } else looper = 1;
+
+ while (looper --) {
+ data[pip ++] = col;
+ }
+ }
+ }
+ break;
+
+ default: // RAW DATA
+ size_t bytes_read = fread(data, picwidth, picheight, bigDataFile);
+ if (bytes_read != picwidth * picheight && ferror(bigDataFile)) {
+ debugOut("Reading error in loadSpriteBank.\n");
+ }
+ break;
+ }
+ }
+ }
+ numTextures++;
+
+
+ if (! spriteBankVersion) {
+ howmany = fgetc(bigDataFile);
+ startIndex = fgetc(bigDataFile);
+ }
+
+ if (spriteBankVersion < 3) {
+ if (! reserveSpritePal(loadhere.myPalette, howmany + startIndex)) return false;
+
+ for (i = 0; i < howmany; i ++) {
+ loadhere.myPalette.r[i + startIndex] = (byte) fgetc(bigDataFile);
+ loadhere.myPalette.g[i + startIndex] = (byte) fgetc(bigDataFile);
+ loadhere.myPalette.b[i + startIndex] = (byte) fgetc(bigDataFile);
+ loadhere.myPalette.pal[i + startIndex] = makeColour(loadhere.myPalette.r[i + startIndex], loadhere.myPalette.g[i + startIndex], loadhere.myPalette.b[i + startIndex]);
+ }
+ }
+
+ loadhere.myPalette.originalRed = loadhere.myPalette.originalGreen = loadhere.myPalette.originalBlue = 255;
+
+ loadhere.myPalette.numTextures = numTextures;
+ GLubyte *tmp[numTextures];
+ GLubyte *tmp2[numTextures];
+ for (tex_num = 0; tex_num < numTextures; tex_num++) {
+ if (! NPOT_textures) {
+ totalwidth[tex_num] = getNextPOT(totalwidth[tex_num]);
+ maxheight[tex_num] = getNextPOT(maxheight[tex_num]);
+ }
+ tmp[tex_num] = new GLubyte [(maxheight[tex_num] + 1)*totalwidth[tex_num] * 4];
+ if (! checkNew(tmp[tex_num])) return false;
+ memset(tmp[tex_num], 0, maxheight[tex_num]*totalwidth[tex_num] * 4);
+ if (isFont) {
+ tmp2[tex_num] = new GLubyte [(maxheight[tex_num] + 1)*totalwidth[tex_num] * 4];
+ if (! checkNew(tmp2[tex_num])) return false;
+ memset(tmp2[tex_num], 0, maxheight[tex_num]*totalwidth[tex_num] * 4);
+ }
+ loadhere.myPalette.tex_w[tex_num] = totalwidth[tex_num];
+ loadhere.myPalette.tex_h[tex_num] = maxheight[tex_num];
+ }
+
+ int fromhere;
+ unsigned char s;
+
+ for (i = 0; i < total; i ++) {
+ fromhere = 0;
+
+ int transColour = -1;
+ if (spriteBankVersion < 3) {
+ int size = loadhere.sprites[i].height * loadhere.sprites[i].width;
+ while (fromhere < size) {
+ s = spriteData[i][fromhere++];
+ if (s) {
+ transColour = s;
+ break;
+ }
+ }
+ fromhere = 0;
+ }
+
+ for (int y = 1; y < 1 + loadhere.sprites[i].height; y ++) {
+ for (int x = loadhere.sprites[i].tex_x; x < loadhere.sprites[i].tex_x + loadhere.sprites[i].width; x ++) {
+ GLubyte *target = tmp[loadhere.sprites[i].texNum] + 4 * totalwidth[loadhere.sprites[i].texNum] * y + x * 4;
+ if (spriteBankVersion < 3) {
+ s = spriteData[i][fromhere++];
+ if (s) {
+ target[0] = (GLubyte) loadhere.myPalette.r[s];
+ target[1] = (GLubyte) loadhere.myPalette.g[s];
+ target[2] = (GLubyte) loadhere.myPalette.b[s];
+ target[3] = (GLubyte) 255;
+ transColour = s;
+ } else if (transColour >= 0) {
+ target[0] = (GLubyte) loadhere.myPalette.r[transColour];
+ target[1] = (GLubyte) loadhere.myPalette.g[transColour];
+ target[2] = (GLubyte) loadhere.myPalette.b[transColour];
+ target[3] = (GLubyte) 0;
+ }
+ if (isFont) {
+ target = tmp2[loadhere.sprites[i].texNum] + 4 * totalwidth[loadhere.sprites[i].texNum] * y + x * 4;
+ target[0] = (GLubyte) 255;
+ target[1] = (GLubyte) 255;
+ target[2] = (GLubyte) 255;
+ if (s)
+ target[3] = (GLubyte) loadhere.myPalette.r[s];
+ /*else
+ target[3] = (GLubyte) 0;*/
+ }
+ } else {
+ target[0] = (GLubyte) spriteData[i][fromhere++];
+ target[1] = (GLubyte) spriteData[i][fromhere++];
+ target[2] = (GLubyte) spriteData[i][fromhere++];
+ target[3] = (GLubyte) spriteData[i][fromhere++];
+ }
+ }
+ }
+ delete[] spriteData[i];
+ }
+ delete[] spriteData;
+ spriteData = NULL;
+
+#if 0
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glGenTextures(numTextures, loadhere.myPalette.tex_names);
+ if (isFont)
+ glGenTextures(numTextures, loadhere.myPalette.burnTex_names);
+
+#endif
+
+ for (tex_num = 0; tex_num < numTextures; tex_num++) {
+
+ glBindTexture(GL_TEXTURE_2D, loadhere.myPalette.tex_names[tex_num]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (gameSettings.antiAlias < 0) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, totalwidth[tex_num], maxheight[tex_num], 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp[tex_num], loadhere.myPalette.tex_names[tex_num]);
+
+ delete[] tmp[tex_num];
+ tmp[tex_num] = NULL;
+
+ if (isFont) {
+
+ glBindTexture(GL_TEXTURE_2D, loadhere.myPalette.burnTex_names[tex_num]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (gameSettings.antiAlias < 0) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, totalwidth[tex_num], maxheight[tex_num], 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp2[tex_num], loadhere.myPalette.burnTex_names[tex_num]);
+ delete[] tmp2[tex_num];
+ tmp2[tex_num] = NULL;
+ }
+ }
+
+ finishAccess();
+#endif
+ setResourceForFatal(-1);
+
+ return true;
+}
+
+void pasteSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal) {
+#if 0
+ float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum];
+ float ty1 = 0.0;
+ float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum];
+ float ty2 = (float)(single.height) / fontPal.tex_h[single.texNum];
+
+ float btx1;
+ float btx2;
+ float bty1;
+ float bty2;
+
+ int diffX = single.width;
+ int diffY = single.height;
+
+ x1 -= single.xhot;
+ y1 -= single.yhot;
+
+ if (! NPOT_textures) {
+ btx1 = backdropTexW * x1 / sceneWidth;
+ btx2 = backdropTexW * (x1 + single.width) / sceneWidth;
+ bty1 = backdropTexH * y1 / sceneHeight;
+ bty2 = backdropTexH * (y1 + single.height) / sceneHeight;
+ } else {
+ btx1 = (float) x1 / sceneWidth;
+ btx2 = (float)(x1 + single.width) / sceneWidth;
+ bty1 = (float) y1 / sceneHeight;
+ bty2 = (float)(y1 + single.height) / sceneHeight;
+ }
+
+ const GLfloat btexCoords[] = {
+ btx1, bty1,
+ btx2, bty1,
+ btx1, bty2,
+ btx2, bty2
+ };
+
+ if (x1 < 0) diffX += x1;
+ if (y1 < 0) diffY += y1;
+ if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1;
+ if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1;
+ if (diffX < 0) return;
+ if (diffY < 0) return;
+
+ setPixelCoords(true);
+
+ int xoffset = 0;
+ while (xoffset < diffX) {
+ int w = (diffX - xoffset < viewportWidth) ? diffX - xoffset : viewportWidth;
+
+ int yoffset = 0;
+ while (yoffset < diffY) {
+ int h = (diffY - yoffset < viewportHeight) ? diffY - yoffset : viewportHeight;
+
+
+ // Render the sprite to the backdrop
+ // (using mulitexturing, so the backdrop is seen where alpha < 1.0)
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, backdropTextureName);
+ glActiveTexture(GL_TEXTURE0);
+
+ glUseProgram(shader.paste);
+ GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture");
+ if (uniform >= 0) glUniform1i(uniform, 0); // No lighting
+
+ setPMVMatrix(shader.paste);
+
+ setPrimaryColor(fontPal.originalRed / 255.f, fontPal.originalGreen / 255.f, fontPal.originalBlue / 255.f, 1.0f);
+ glBindTexture(GL_TEXTURE_2D, fontPal.tex_names[single.texNum]);
+ //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ const GLfloat vertices[] = {
+ (GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
+ (GLfloat)single.width - xoffset, (GLfloat) - yoffset, 0.,
+ (GLfloat) - xoffset, (GLfloat)single.height - yoffset, 0.,
+ (GLfloat)single.width - xoffset, (GLfloat)single.height - yoffset, 0.
+ };
+
+ const GLfloat texCoords[] = {
+ tx1, ty1,
+ tx2, ty1,
+ tx1, ty2,
+ tx2, ty2
+ };
+
+ drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords);
+
+ // Copy Our ViewPort To The Texture
+ glUseProgram(0);
+
+ copyTexSubImage2D(GL_TEXTURE_2D, 0, (int)((x1 < 0) ? xoffset : x1 + xoffset), (int)((y1 < 0) ? yoffset : y1 + yoffset), (int)((x1 < 0) ? viewportOffsetX - x1 : viewportOffsetX), (int)((y1 < 0) ? viewportOffsetY - y1 : viewportOffsetY), w, h, backdropTextureName);
+
+ yoffset += viewportHeight;
+ }
+ xoffset += viewportWidth;
+ }
+#endif
+ setPixelCoords(false);
+}
+
+void burnSpriteToBackDrop(int x1, int y1, sprite &single, const spritePalette &fontPal) {
+#if 0
+ float tx1 = (float)(single.tex_x - 0.5) / fontPal.tex_w[single.texNum];
+ float ty1 = 0.0;
+ float tx2 = (float)(single.tex_x + single.width + 0.5) / fontPal.tex_w[single.texNum];
+ float ty2 = (float)(single.height + 2) / fontPal.tex_h[single.texNum];
+
+ const GLfloat spriteTexCoords[] = {
+ tx1, ty1,
+ tx2, ty1,
+ tx1, ty2,
+ tx2, ty2
+ };
+
+ x1 -= single.xhot;
+ y1 -= single.yhot - 1;
+
+ float bx1 = (float)x1 * backdropTexW / sceneWidth;
+ float by1 = (float)y1 * backdropTexH / sceneHeight;
+ float bx2 = (float)(x1 + single.width - 1) * backdropTexW / sceneWidth;
+ float by2 = (float)(y1 + single.height - 1) * backdropTexH / sceneHeight;
+
+ const GLfloat backdropTexCoords[] = {
+ bx1, by1,
+ bx2, by1,
+ bx1, by2,
+ bx2, by2
+ };
+
+ const GLfloat backdropTexCoords2[] = {
+ 0.0f, 0.0f,
+ backdropTexW, 0.0f,
+ 0.0f, backdropTexH,
+ backdropTexW, backdropTexH
+ };
+
+ int diffX = single.width + 1;
+ int diffY = single.height + 2;
+
+ if (x1 < 0) diffX += x1;
+ if (y1 < 0) diffY += y1;
+ if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1;
+ if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1;
+ if (diffX < 0) return;
+ if (diffY < 0) return;
+
+ setPixelCoords(true);
+ setPrimaryColor(currentBurnR / 255.f, currentBurnG / 255.f, currentBurnB / 255.f, 1.0f);
+
+ GLfloat xoffset = 0.0f;
+ while (xoffset < diffX) {
+ int w = (diffX - xoffset < viewportWidth) ? diffX - xoffset : viewportWidth;
+
+ GLfloat yoffset = 0.0f;
+ while (yoffset < diffY) {
+ int h = (diffY - yoffset < viewportHeight) ? diffY - yoffset : viewportHeight;
+
+ const GLfloat backdropVertices[] = {
+ -x1 - xoffset, -y1 + yoffset, 0.0f,
+ sceneWidth - 1.0f - x1 - xoffset, -y1 + yoffset, 0.0f,
+ -x1 - xoffset, sceneHeight - 1.0f - y1 + yoffset, 0.0f,
+ sceneWidth - 1.0f - x1 - xoffset, sceneHeight - 1.0f - y1 + yoffset, 0.0f
+ };
+
+ const GLfloat spriteVertices[] = {
+ -xoffset, -yoffset, 0.0f,
+ single.width - 1 - xoffset, -yoffset, 0.0f,
+ -xoffset, single.height - 1 - yoffset, 0.0f,
+ single.width - 1 - xoffset, single.height - 1 - yoffset, 0.0f
+ };
+
+ glBindTexture(GL_TEXTURE_2D, backdropTextureName);
+ glUseProgram(shader.texture);
+ setPMVMatrix(shader.texture);
+
+ drawQuad(shader.texture, backdropVertices, 1, backdropTexCoords2);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, backdropTextureName);
+ glActiveTexture(GL_TEXTURE0);
+
+ glUseProgram(shader.paste);
+ GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture");
+ if (uniform >= 0) glUniform1i(uniform, 0); // No lighting
+
+ setPMVMatrix(shader.paste);
+
+ glBindTexture(GL_TEXTURE_2D, fontPal.burnTex_names[single.texNum]);
+
+//FIXME: Test this some more. Also pasting the backdrop again is not strictly necessary but allows using the paste shader.
+ drawQuad(shader.paste, spriteVertices, 3, spriteTexCoords, NULL, backdropTexCoords);
+ glUseProgram(0);
+
+ // Copy Our ViewPort To The Texture
+ copyTexSubImage2D(GL_TEXTURE_2D, 0, (x1 < 0) ? xoffset : x1 + xoffset, (y1 < 0) ? yoffset : y1 + yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName);
+
+ yoffset += viewportHeight;
+ }
+ xoffset += viewportWidth;
+ }
+ setPixelCoords(false);
+#endif
+}
+
+#if 0
+extern GLuint backdropTextureName;
+#endif
+
+void fontSprite(bool flip, int x, int y, sprite &single, const spritePalette &fontPal) {
+
+ float tx1 = (float)(single.tex_x - 0.5) / fontPal.tex_w[single.texNum];
+ float ty1 = 0.0;
+ float tx2 = (float)(single.tex_x + single.width + (flip ? 1.0 : 0.5)) / fontPal.tex_w[single.texNum];
+ float ty2 = (float)(single.height + 2) / fontPal.tex_h[single.texNum];
+
+ float x1 = (float)x - (float)single.xhot / cameraZoom;
+ float y1 = (float)y - (float)single.yhot / cameraZoom;
+ float x2 = x1 + (float)single.width / cameraZoom;
+ float y2 = y1 + (float)single.height / cameraZoom;
+
+#if 0
+ GLfloat vertices[] = {
+ x1, y1, 0.0f,
+ x2, y1, 0.0f,
+ x1, y2, 0.0f,
+ x2, y2, 0.0f
+ };
+ if (flip) {
+ vertices[0] = x2;
+ vertices[3] = x1;
+ vertices[6] = x2;
+ vertices[9] = x1;
+ }
+
+ const GLfloat texCoords[] = {
+ tx1, ty1,
+ tx2, ty1,
+ tx1, ty2,
+ tx2, ty2
+ };
+
+ //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE instead of decal mixes the colours!
+ setPrimaryColor(fontPal.originalRed / 255.f, fontPal.originalGreen / 255.f, fontPal.originalBlue / 255.f, 1.0f);
+
+ glBindTexture(GL_TEXTURE_2D, fontPal.tex_names[single.texNum]);
+
+ glUseProgram(shader.smartScaler);
+ GLuint uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture");
+ if (uniform >= 0) glUniform1i(uniform, 0);
+
+ setPMVMatrix(shader.smartScaler);
+
+ if (gameSettings.antiAlias == 1) {
+ glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 0);
+ }
+
+ glEnable(GL_BLEND);
+
+ drawQuad(shader.smartScaler, vertices, 1, texCoords);
+
+ glDisable(GL_BLEND);
+ glUseProgram(0);
+#endif
+}
+
+void fontSprite(int x, int y, sprite &single, const spritePalette &fontPal) {
+ fontSprite(false, x, y, single, fontPal);
+}
+
+void flipFontSprite(int x, int y, sprite &single, const spritePalette &fontPal) {
+ fontSprite(true, x, y, single, fontPal);
+}
+
+
+
+
+unsigned char curLight[3];
+
+void setDrawMode(onScreenPerson *thisPerson) {
+#if 0
+ if (thisPerson->colourmix) {
+ //glEnable(GL_COLOR_SUM); FIXME: replace line?
+ setSecondaryColor(curLight[0]*thisPerson->r * thisPerson->colourmix / 65025 / 255.f, curLight[1]*thisPerson->g * thisPerson->colourmix / 65025 / 255.f, curLight[2]*thisPerson->b * thisPerson->colourmix / 65025 / 255.f, 1.0f);
+ }
+
+ //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ setPrimaryColor(curLight[0] * (255 - thisPerson->colourmix) / 65025.f, curLight[1] * (255 - thisPerson->colourmix) / 65025.f, curLight[2] * (255 - thisPerson->colourmix) / 65025.f, 1.0f - thisPerson->transparency / 255.f);
+#endif
+}
+
+#if 0
+extern GLuint backdropTextureName;
+#endif
+
+bool checkColourChange(bool reset);
+
+bool scaleSprite(sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, bool mirror) {
+#if 0
+ float x = thisPerson->x;
+ float y = thisPerson->y;
+
+ float scale = thisPerson-> scale;
+ bool light = !(thisPerson->extra & EXTRA_NOLITE);
+
+ if (scale <= 0.05) return false;
+
+ float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum];
+ float ty1 = (float) 1.0 / fontPal.tex_h[single.texNum];
+ float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum];
+ float ty2 = (float)(single.height + 1) / fontPal.tex_h[single.texNum];
+
+ int diffX = (int)(((float)single.width) * scale);
+ int diffY = (int)(((float)single.height) * scale);
+
+ GLfloat x1, y1, x2, y2;
+
+ if (thisPerson -> extra & EXTRA_FIXTOSCREEN) {
+ x = x / cameraZoom;
+ y = y / cameraZoom;
+ if (single.xhot < 0)
+ x1 = x - (int)((mirror ? (float)(single.width - single.xhot) : (float)(single.xhot + 1)) * scale / cameraZoom);
+ else
+ x1 = x - (int)((mirror ? (float)(single.width - (single.xhot + 1)) : (float)single.xhot) * scale / cameraZoom);
+ y1 = y - (int)((single.yhot - thisPerson->floaty) * scale / cameraZoom);
+ x2 = x1 + (int)(diffX / cameraZoom);
+ y2 = y1 + (int)(diffY / cameraZoom);
+ } else {
+ x -= cameraX;
+ y -= cameraY;
+ if (single.xhot < 0)
+ x1 = x - (int)((mirror ? (float)(single.width - single.xhot) : (float)(single.xhot + 1)) * scale);
+ else
+ x1 = x - (int)((mirror ? (float)(single.width - (single.xhot + 1)) : (float)single.xhot) * scale);
+ y1 = y - (int)((single.yhot - thisPerson->floaty) * scale);
+ x2 = x1 + diffX;
+ y2 = y1 + diffY;
+ }
+
+ GLfloat z;
+
+ if ((!(thisPerson->extra & EXTRA_NOZB)) && zBuffer.numPanels) {
+ int i;
+ for (i = 1; i < zBuffer.numPanels; i++) {
+ if (zBuffer.panel[i] >= y + cameraY) {
+ i--;
+ break;
+ }
+ }
+ z = 0.999 - (double) i * (1.0 / 128.0);
+ } else {
+ z = -0.5;
+ }
+
+ float ltx1, ltx2, lty1, lty2;
+ if (! NPOT_textures) {
+ ltx1 = lightMap.texW * (x1 + cameraX) / sceneWidth;
+ ltx2 = lightMap.texW * (x2 + cameraX) / sceneWidth;
+ lty1 = lightMap.texH * (y1 + cameraY) / sceneHeight;
+ lty2 = lightMap.texH * (y2 + cameraY) / sceneHeight;
+ } else {
+ ltx1 = (float)(x1 + cameraX) / sceneWidth;
+ ltx2 = (float)(x2 + cameraX) / sceneWidth;
+ lty1 = (float)(y1 + cameraY) / sceneHeight;
+ lty2 = (float)(y2 + cameraY) / sceneHeight;
+ }
+
+ const GLfloat ltexCoords[] = {
+ ltx1, lty1,
+ ltx2, lty1,
+ ltx1, lty2,
+ ltx2, lty2
+ };
+
+ if (light && lightMap.data) {
+ if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
+ int lx = (int)(x + cameraX);
+ int ly = (int)(y + cameraY);
+
+ if (lx < 0) lx = 0;
+ else if (lx >= sceneWidth) lx = sceneWidth - 1;
+ if (ly < 0) ly = 0;
+ else if (ly >= sceneHeight) ly = sceneHeight - 1;
+
+ GLubyte *target;
+ if (! NPOT_textures) {
+ target = lightMap.data + (ly * getNextPOT(sceneWidth) + lx) * 4;
+ } else {
+ target = lightMap.data + (ly * sceneWidth + lx) * 4;
+ }
+ curLight[0] = target[0];
+ curLight[1] = target[1];
+ curLight[2] = target[2];
+ } else if (lightMapMode == LIGHTMAPMODE_PIXEL) {
+ curLight[0] = curLight[1] = curLight[2] = 255;
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, lightMap.name);
+ glActiveTexture(GL_TEXTURE0);
+
+ }
+ } else {
+ curLight[0] = curLight[1] = curLight[2] = 255;
+ }
+#ifndef HAVE_GLES2
+ if (!(thisPerson->extra & EXTRA_RECTANGULAR))
+ checkColourChange(true);
+#endif
+ setDrawMode(thisPerson);
+
+ glBindTexture(GL_TEXTURE_2D, fontPal.tex_names[single.texNum]);
+
+ glEnable(GL_BLEND);
+
+ glUseProgram(shader.smartScaler);
+ GLuint uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture");
+ if (uniform >= 0) glUniform1i(uniform, light && lightMapMode == LIGHTMAPMODE_PIXEL && lightMap.data);
+
+ setPMVMatrix(shader.smartScaler);
+
+ if (gameSettings.antiAlias == 1) {
+ glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 0);
+ }
+
+ const GLfloat vertices[] = {
+ x1, y1, z,
+ x2, y1, z,
+ x1, y2, z,
+ x2, y2, z
+ };
+
+ if (! mirror) {
+ GLfloat tx3 = tx1;
+ tx1 = tx2;
+ tx2 = tx3;
+ }
+ const GLfloat texCoords[] = {
+ tx2, ty1,
+ tx1, ty1,
+ tx2, ty2,
+ tx1, ty2
+ };
+
+ drawQuad(shader.smartScaler, vertices, 2, texCoords, ltexCoords);
+
+ glDisable(GL_BLEND);
+ glUseProgram(0);
+
+ if (light && lightMapMode == LIGHTMAPMODE_PIXEL) {
+ glActiveTexture(GL_TEXTURE1);
+ glActiveTexture(GL_TEXTURE0);
+ }
+
+ setSecondaryColor(0., 0., 0., 1.);
+ //glDisable(GL_COLOR_SUM); FIXME: replace line?
+
+ // Are we pointing at the sprite?
+ if (input.mouseX >= x1 && input.mouseX <= x2 && input.mouseY >= y1 && input.mouseY <= y2) {
+ if (thisPerson->extra & EXTRA_RECTANGULAR) return true;
+#ifdef HAVE_GLES2
+ return true;
+#else
+ return checkColourChange(false);
+#endif
+ }
+#endif
+ return false;
+}
+
+// Paste a scaled sprite onto the backdrop
+void fixScaleSprite(int x, int y, sprite &single, const spritePalette &fontPal, onScreenPerson *thisPerson, int camX, int camY, bool mirror) {
+#if 0
+ float scale = thisPerson-> scale;
+ bool useZB = !(thisPerson->extra & EXTRA_NOZB);
+ bool light = !(thisPerson->extra & EXTRA_NOLITE);
+
+ if (scale <= 0.05) return;
+
+ float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum];
+ float ty1 = (float) 1.0 / fontPal.tex_h[single.texNum]; //0.0;
+ float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum];
+ float ty2 = (float)(single.height + 1) / fontPal.tex_h[single.texNum];
+
+ int diffX = (int)(((float)single.width) * scale);
+ int diffY = (int)(((float)single.height) * scale);
+ int x1;
+ if (single.xhot < 0)
+ x1 = x - (int)((mirror ? (float)(single.width - single.xhot) : (float)(single.xhot + 1)) * scale);
+ else
+ x1 = x - (int)((mirror ? (float)(single.width - (single.xhot + 1)) : (float)single.xhot) * scale);
+ int y1 = y - (int)((single.yhot - thisPerson->floaty) * scale);
+
+ float spriteWidth = diffX;
+ float spriteHeight = diffY;
+ if (x1 < 0) diffX += x1;
+ if (y1 < 0) diffY += y1;
+ if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1;
+ if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1;
+ if (diffX < 0) return;
+ if (diffY < 0) return;
+
+ GLfloat z;
+
+
+ if (useZB && zBuffer.numPanels) {
+ int i;
+ for (i = 1; i < zBuffer.numPanels; i++) {
+ if (zBuffer.panel[i] >= y + cameraY) {
+ i--;
+ break;
+ }
+ }
+ z = 0.999 - (double) i * (1.0 / 128.0);
+ } else {
+ z = -0.5;
+ }
+
+ float ltx1, btx1;
+ float ltx2, btx2;
+ float lty1, bty1;
+ float lty2, bty2;
+ if (! NPOT_textures) {
+ ltx1 = lightMap.texW * x1 / sceneWidth;
+ ltx2 = lightMap.texW * (x1 + spriteWidth) / sceneWidth;
+ lty1 = lightMap.texH * y1 / sceneHeight;
+ lty2 = lightMap.texH * (y1 + spriteHeight) / sceneHeight;
+ btx1 = backdropTexW * x1 / sceneWidth;
+ btx2 = backdropTexW * (x1 + spriteWidth) / sceneWidth;
+ bty1 = backdropTexH * y1 / sceneHeight;
+ bty2 = backdropTexH * (y1 + spriteHeight) / sceneHeight;
+ } else {
+ btx1 = ltx1 = (float) x1 / sceneWidth;
+ btx2 = ltx2 = (float)(x1 + spriteWidth) / sceneWidth;
+ bty1 = lty1 = (float) y1 / sceneHeight;
+ bty2 = lty2 = (float)(y1 + spriteHeight) / sceneHeight;
+ }
+
+ const GLfloat ltexCoords[] = {
+ ltx1, lty1,
+ ltx2, lty1,
+ ltx1, lty2,
+ ltx2, lty2
+ };
+
+ const GLfloat btexCoords[] = {
+ btx1, bty1,
+ btx2, bty1,
+ btx1, bty2,
+ btx2, bty2
+ };
+
+ if (light && lightMap.data) {
+ if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
+ int lx = x + cameraX;
+ int ly = y + cameraY;
+ if (lx < 0 || ly < 0 || lx >= sceneWidth || ly >= sceneHeight) {
+ curLight[0] = curLight[1] = curLight[2] = 255;
+ } else {
+ GLubyte *target = lightMap.data + (ly * sceneWidth + lx) * 4;
+ curLight[0] = target[0];
+ curLight[1] = target[1];
+ curLight[2] = target[2];
+ }
+ } else if (lightMapMode == LIGHTMAPMODE_PIXEL) {
+ curLight[0] = curLight[1] = curLight[2] = 255;
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, lightMap.name);
+
+ }
+ } else {
+ curLight[0] = curLight[1] = curLight[2] = 255;
+ }
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, backdropTextureName);
+ glActiveTexture(GL_TEXTURE0);
+
+ setPixelCoords(true);
+ GLfloat xoffset = 0.0f;
+ while (xoffset < diffX) {
+ int w = (diffX - xoffset < viewportWidth) ? (int)(diffX - xoffset) : viewportWidth;
+
+ GLfloat yoffset = 0.0f;
+ while (yoffset < diffY) {
+
+ int h = (diffY - yoffset < viewportHeight) ? (int)(diffY - yoffset) : viewportHeight;
+
+ // Render the scene - first the old backdrop (so that it'll show through when the z-buffer is active
+ //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glBindTexture(GL_TEXTURE_2D, backdropTextureName);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ const GLfloat vertices[] = {
+ -x1 - xoffset, -y1 - yoffset, 0.0f,
+ sceneWidth - x1 - xoffset, -y1 - yoffset, 0.0f,
+ -x1 - xoffset, sceneHeight - y1 - yoffset, 0.0f,
+ sceneWidth - x1 - xoffset, sceneHeight - y1 - yoffset, 0.0f
+ };
+
+ const GLfloat texCoords[] = {
+ 0.0f, 0.0f,
+ backdropTexW, 0.0f,
+ 0.0f, backdropTexH,
+ backdropTexW, backdropTexH
+ };
+
+ glUseProgram(shader.texture);
+ setPMVMatrix(shader.texture);
+
+ drawQuad(shader.texture, vertices, 1, texCoords);
+
+ // The z-buffer
+ if (useZB) {
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ drawZBuffer((int)(x1 + xoffset + camX), (int)(y1 + yoffset + camY), false);
+
+ glDepthMask(GL_FALSE);
+ glEnable(GL_DEPTH_TEST);
+ }
+
+ // Then the sprite
+ glUseProgram(shader.paste);
+ GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture");
+ if (uniform >= 0) glUniform1i(uniform, light && lightMapMode == LIGHTMAPMODE_PIXEL && lightMap.data);
+ setPMVMatrix(shader.paste);
+
+ setDrawMode(thisPerson);
+
+ glBindTexture(GL_TEXTURE_2D, fontPal.tex_names[single.texNum]);
+
+ const GLfloat vertices2[] = {
+ -xoffset, -yoffset, z,
+ spriteWidth - xoffset, -yoffset, z,
+ -xoffset, spriteHeight - yoffset, z,
+ spriteWidth - xoffset, spriteHeight - yoffset, z
+ };
+
+ if (! mirror) {
+ GLfloat tx3 = tx1;
+ tx1 = tx2;
+ tx2 = tx3;
+ }
+ const GLfloat texCoords2[] = {
+ tx2, ty1,
+ tx1, ty1,
+ tx2, ty2,
+ tx1, ty2
+ };
+
+ drawQuad(shader.paste, vertices2, 3, texCoords2, ltexCoords, btexCoords);
+
+ setSecondaryColor(0., 0., 0., 1.);
+ //glDisable(GL_COLOR_SUM); FIXME: replace line?
+ // Copy Our ViewPort To The Texture
+ glUseProgram(0);
+ copyTexSubImage2D(GL_TEXTURE_2D, 0, (int)((x1 < 0) ? xoffset : x1 + xoffset), (int)((y1 < 0) ? yoffset : y1 + yoffset), (int)((x1 < 0) ? viewportOffsetX - x1 : viewportOffsetX), (int)((y1 < 0) ? viewportOffsetY - y1 : viewportOffsetY), w, h, backdropTextureName);
+
+ yoffset += viewportHeight;
+ }
+ xoffset += viewportWidth;
+ }
+
+ setPixelCoords(false);
+ glUseProgram(0);
+#endif
+}
+