mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-14 05:30:53 +00:00
1754 lines
47 KiB
C++
1754 lines
47 KiB
C++
|
/* 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
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#if !defined(HAVE_GLES2)
|
||
|
#include "GLee.h"
|
||
|
#else
|
||
|
#include <GLES2/gl2.h>
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#include "allfiles.h"
|
||
|
#include "debug.h"
|
||
|
#include "newfatal.h"
|
||
|
#include "colours.h"
|
||
|
#include "fileset.h"
|
||
|
#include "cursors.h"
|
||
|
#include "backdrop.h"
|
||
|
#include "language.h"
|
||
|
#include "moreio.h"
|
||
|
#include "variable.h"
|
||
|
#include "zbuffer.h"
|
||
|
#include "graphics.h"
|
||
|
#include "line.h"
|
||
|
#include "people.h"
|
||
|
#include "talk.h"
|
||
|
#include "sludger.h"
|
||
|
#include "statusba.h"
|
||
|
|
||
|
#include "CommonCode/version.h"
|
||
|
|
||
|
extern inputType input;
|
||
|
|
||
|
|
||
|
bool freeze();
|
||
|
void unfreeze(bool); // Because FREEZE.H needs a load of other includes
|
||
|
|
||
|
#if 0
|
||
|
GLubyte *backdropTexture = NULL;
|
||
|
GLuint backdropTextureName = 0;
|
||
|
bool backdropExists = false;
|
||
|
GLfloat backdropTexW = 1.0;
|
||
|
GLfloat backdropTexH = 1.0;
|
||
|
|
||
|
texture lightMap;
|
||
|
|
||
|
GLuint snapshotTextureName = 0;
|
||
|
#endif
|
||
|
|
||
|
float snapTexW = 1.0;
|
||
|
float snapTexH = 1.0;
|
||
|
|
||
|
int lightMapMode = LIGHTMAPMODE_PIXEL;
|
||
|
parallaxLayer *parallaxStuff = NULL;
|
||
|
int cameraPX = 0, cameraPY = 0;
|
||
|
|
||
|
unsigned int sceneWidth, sceneHeight;
|
||
|
int lightMapNumber;
|
||
|
unsigned int currentBlankColour = makeColour(0, 0, 0);
|
||
|
|
||
|
extern int cameraX, cameraY;
|
||
|
extern float cameraZoom;
|
||
|
|
||
|
void nosnapshot() {
|
||
|
#if 0
|
||
|
deleteTextures(1, &snapshotTextureName);
|
||
|
snapshotTextureName = 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#if ALLOW_FILE
|
||
|
void saveSnapshot(FILE *fp) {
|
||
|
if (snapshotTextureName) {
|
||
|
fputc(1, fp); // 1 for snapshot follows
|
||
|
saveCoreHSI(fp, snapshotTextureName, winWidth, winHeight);
|
||
|
} else {
|
||
|
fputc(0, fp);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bool snapshot() {
|
||
|
|
||
|
nosnapshot();
|
||
|
if (! freeze()) return false;
|
||
|
#if 0
|
||
|
setPixelCoords(true);
|
||
|
glGenTextures(1, &snapshotTextureName);
|
||
|
|
||
|
int w = winWidth;
|
||
|
int h = winHeight;
|
||
|
if (! NPOT_textures) {
|
||
|
w = getNextPOT(winWidth);
|
||
|
h = getNextPOT(winHeight);
|
||
|
snapTexW = ((double)winWidth) / w;
|
||
|
snapTexH = ((double)winHeight) / h;
|
||
|
}
|
||
|
|
||
|
glBindTexture(GL_TEXTURE_2D, snapshotTextureName);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
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, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, snapshotTextureName);
|
||
|
|
||
|
// Render scene
|
||
|
glDepthMask(GL_TRUE);
|
||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen
|
||
|
glDepthMask(GL_FALSE);
|
||
|
|
||
|
drawBackDrop(); // Draw the room
|
||
|
drawZBuffer(cameraX, cameraY, false);
|
||
|
|
||
|
glEnable(GL_DEPTH_TEST);
|
||
|
|
||
|
drawPeople(); // Then add any moving characters...
|
||
|
|
||
|
glDisable(GL_DEPTH_TEST);
|
||
|
|
||
|
viewSpeech(); // ...and anything being said
|
||
|
drawStatusBar();
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewportOffsetX, viewportOffsetY, winWidth, winHeight, snapshotTextureName);
|
||
|
|
||
|
setPixelCoords(false);
|
||
|
#endif
|
||
|
unfreeze(false);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#if ALLOW_FILE
|
||
|
bool restoreSnapshot(FILE *fp) {
|
||
|
unsigned int picWidth = get2bytes(fp);
|
||
|
unsigned int picHeight = get2bytes(fp);
|
||
|
|
||
|
if ((picWidth != winWidth) || (picHeight != winHeight))
|
||
|
return false;
|
||
|
|
||
|
unsigned int t1, t2, n;
|
||
|
unsigned short c;
|
||
|
|
||
|
GLubyte *target;
|
||
|
if (! NPOT_textures) {
|
||
|
picWidth = getNextPOT(picWidth);
|
||
|
picHeight = getNextPOT(picHeight);
|
||
|
snapTexW = ((double)winWidth) / picWidth;
|
||
|
snapTexH = ((double)winHeight) / picHeight;
|
||
|
}
|
||
|
GLubyte *snapshotTexture = new GLubyte [picHeight * picWidth * 4];
|
||
|
if (! snapshotTexture) return fatal("Out of memory while restoring snapshot.");
|
||
|
|
||
|
for (t2 = 0; t2 < winHeight; t2 ++) {
|
||
|
t1 = 0;
|
||
|
while (t1 < winWidth) {
|
||
|
c = (unsigned short) get2bytes(fp);
|
||
|
if (c & 32) {
|
||
|
n = fgetc(fp) + 1;
|
||
|
c -= 32;
|
||
|
} else {
|
||
|
n = 1;
|
||
|
}
|
||
|
while (n --) {
|
||
|
target = snapshotTexture + 4 * picWidth * t2 + t1 * 4;
|
||
|
target[0] = (GLubyte) redValue(c);
|
||
|
target[1] = (GLubyte) greenValue(c);
|
||
|
target[2] = (GLubyte) blueValue(c);
|
||
|
target[3] = (GLubyte) 255;
|
||
|
t1++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (! snapshotTextureName) glGenTextures(1, &snapshotTextureName);
|
||
|
glBindTexture(GL_TEXTURE_2D, snapshotTextureName);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
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, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, snapshotTexture, snapshotTextureName);
|
||
|
|
||
|
delete snapshotTexture;
|
||
|
snapshotTexture = NULL;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void killBackDrop() {
|
||
|
#if 0
|
||
|
deleteTextures(1, &backdropTextureName);
|
||
|
backdropTextureName = 0;
|
||
|
backdropExists = false;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void killLightMap() {
|
||
|
#if 0
|
||
|
deleteTextures(1, &lightMap.name);
|
||
|
lightMap.name = 0;
|
||
|
if (lightMap.data) {
|
||
|
delete lightMap.data;
|
||
|
lightMap.data = NULL;
|
||
|
}
|
||
|
lightMapNumber = 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void killParallax() {
|
||
|
#if 0
|
||
|
while (parallaxStuff) {
|
||
|
|
||
|
parallaxLayer *k = parallaxStuff;
|
||
|
parallaxStuff = k -> next;
|
||
|
|
||
|
// Now kill the image
|
||
|
deleteTextures(1, &k -> textureName);
|
||
|
delete k -> texture;
|
||
|
delete k;
|
||
|
k = NULL;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool reserveBackdrop() {
|
||
|
cameraX = 0;
|
||
|
cameraY = 0;
|
||
|
input.mouseX = (int)((float)input.mouseX * cameraZoom);
|
||
|
input.mouseY = (int)((float)input.mouseY * cameraZoom);
|
||
|
cameraZoom = 1.0;
|
||
|
input.mouseX = (int)((float)input.mouseX / cameraZoom);
|
||
|
input.mouseY = (int)((float)input.mouseY / cameraZoom);
|
||
|
setPixelCoords(false);
|
||
|
int picWidth = sceneWidth;
|
||
|
int picHeight = sceneHeight;
|
||
|
#if 0
|
||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||
|
|
||
|
if (backdropTexture) delete backdropTexture;
|
||
|
if (! NPOT_textures) {
|
||
|
picWidth = getNextPOT(sceneWidth);
|
||
|
picHeight = getNextPOT(sceneHeight);
|
||
|
backdropTexW = ((double)sceneWidth) / picWidth;
|
||
|
backdropTexH = ((double)sceneHeight) / picHeight;
|
||
|
}
|
||
|
backdropTexture = new GLubyte [picWidth * picHeight * 4];
|
||
|
if (! checkNew(backdropTexture)) return false;
|
||
|
|
||
|
if (! backdropTextureName) glGenTextures(1, &backdropTextureName);
|
||
|
glBindTexture(GL_TEXTURE_2D, backdropTextureName);
|
||
|
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, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, backdropTextureName);
|
||
|
#endif
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool resizeBackdrop(int x, int y) {
|
||
|
killLightMap();
|
||
|
killBackDrop();
|
||
|
killParallax();
|
||
|
killZBuffer();
|
||
|
sceneWidth = x;
|
||
|
sceneHeight = y;
|
||
|
return reserveBackdrop();
|
||
|
}
|
||
|
|
||
|
void loadBackDrop(int fileNum, int x, int y) {
|
||
|
setResourceForFatal(fileNum);
|
||
|
#if ALLOW_FILE
|
||
|
if (! openFileFromNum(fileNum)) {
|
||
|
fatal("Can't load overlay image");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (! loadHSI(bigDataFile, x, y, false)) {
|
||
|
char mess[200];
|
||
|
sprintf(mess, "Can't paste overlay image outside scene dimensions\n\nX = %i\nY = %i\nWidth = %i\nHeight = %i", x, y, sceneWidth, sceneHeight);
|
||
|
fatal(mess);
|
||
|
}
|
||
|
|
||
|
finishAccess();
|
||
|
#endif
|
||
|
setResourceForFatal(-1);
|
||
|
}
|
||
|
|
||
|
void mixBackDrop(int fileNum, int x, int y) {
|
||
|
#if ALLOW_FILE
|
||
|
setResourceForFatal(fileNum);
|
||
|
if (! openFileFromNum(fileNum)) {
|
||
|
fatal("Can't load overlay image");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (! mixHSI(bigDataFile, x, y)) {
|
||
|
fatal("Can't paste overlay image outside screen dimensions");
|
||
|
}
|
||
|
|
||
|
finishAccess();
|
||
|
#endif
|
||
|
setResourceForFatal(-1);
|
||
|
}
|
||
|
|
||
|
void blankScreen(int x1, int y1, int x2, int y2) {
|
||
|
|
||
|
if (y1 < 0) y1 = 0;
|
||
|
if (x1 < 0) x1 = 0;
|
||
|
if (x2 > (int) sceneWidth) x2 = (int)sceneWidth;
|
||
|
if (y2 > (int) sceneHeight) y2 = (int)sceneHeight;
|
||
|
|
||
|
int picWidth = x2 - x1;
|
||
|
int picHeight = y2 - y1;
|
||
|
#if 0
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < picWidth) {
|
||
|
int w = (picWidth - xoffset < viewportWidth) ? picWidth - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < picHeight) {
|
||
|
int h = (picHeight - yoffset < viewportHeight) ? picHeight - yoffset : viewportHeight;
|
||
|
|
||
|
// Render the scene
|
||
|
|
||
|
|
||
|
|
||
|
const GLfloat vertices[] = {
|
||
|
-10.325f, -1.325f, 0.0f,
|
||
|
w + 1.325f, -1.325f, 0.0f,
|
||
|
-10.325f, h + 1.325f, 0.0f,
|
||
|
w + 1.325f, h + 1.325f, 0.0f
|
||
|
};
|
||
|
|
||
|
glUseProgram(shader.color);
|
||
|
|
||
|
setPMVMatrix(shader.color);
|
||
|
setPrimaryColor(redValue(currentBlankColour) / 255.0f, greenValue(currentBlankColour) / 255.0f, blueValue(currentBlankColour) / 255.0f, 1.0f);
|
||
|
drawQuad(shader.color, vertices, 0);
|
||
|
|
||
|
glUseProgram(0);
|
||
|
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, x1 + xoffset, y1 + yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName);
|
||
|
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
|
||
|
setPixelCoords(false);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void hardScroll(int distance) {
|
||
|
if (abs(distance) >= sceneHeight) {
|
||
|
blankScreen(0, 0, sceneWidth, sceneHeight);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (! distance) return;
|
||
|
#if 0
|
||
|
const GLfloat backdropTexCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
backdropTexW, 0.0f,
|
||
|
0.0f, backdropTexH,
|
||
|
backdropTexW, backdropTexH
|
||
|
};
|
||
|
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
unsigned int xoffset = 0;
|
||
|
while (xoffset < sceneWidth) {
|
||
|
int w = (sceneWidth - xoffset < viewportWidth) ? sceneWidth - xoffset : viewportWidth;
|
||
|
|
||
|
unsigned int yoffset = 0;
|
||
|
while (yoffset < sceneHeight) {
|
||
|
int h = (sceneHeight - yoffset < viewportHeight) ? sceneHeight - yoffset : viewportHeight;
|
||
|
|
||
|
|
||
|
glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen
|
||
|
|
||
|
// Render the backdrop
|
||
|
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[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - distance - yoffset, 0.,
|
||
|
(GLfloat)sceneWidth - xoffset, (GLfloat) - distance - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat)sceneHeight - distance - yoffset, 0.,
|
||
|
(GLfloat)sceneWidth - xoffset, (GLfloat)sceneHeight - distance - yoffset, 0.
|
||
|
};
|
||
|
|
||
|
|
||
|
glUseProgram(shader.texture);
|
||
|
|
||
|
setPMVMatrix(shader.texture);
|
||
|
|
||
|
drawQuad(shader.texture, vertices, 1, backdropTexCoords);
|
||
|
|
||
|
glUseProgram(0);
|
||
|
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName);
|
||
|
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
setPixelCoords(false);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void drawVerticalLine(unsigned int x, unsigned int y1, unsigned int y2) {
|
||
|
drawLine(x, y1, x, y2);
|
||
|
}
|
||
|
|
||
|
void drawHorizontalLine(unsigned int x1, unsigned int y, unsigned int x2) {
|
||
|
drawLine(x1, y, x2, y);
|
||
|
}
|
||
|
|
||
|
void darkScreen() {
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < sceneWidth) {
|
||
|
int w = (sceneWidth - xoffset < viewportWidth) ? sceneWidth - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < sceneHeight) {
|
||
|
int h = (sceneHeight - yoffset < viewportHeight) ? sceneHeight - yoffset : viewportHeight;
|
||
|
|
||
|
// Render the scene - first the old backdrop
|
||
|
#if 0
|
||
|
//glTexEnvf (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[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat)sceneWidth - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat)sceneHeight - yoffset, 0.,
|
||
|
(GLfloat)sceneWidth - xoffset, (GLfloat)sceneHeight - yoffset, 0.
|
||
|
};
|
||
|
|
||
|
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);
|
||
|
|
||
|
// Then the darkness
|
||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||
|
|
||
|
glEnable(GL_BLEND);
|
||
|
|
||
|
glUseProgram(shader.color);
|
||
|
|
||
|
setPMVMatrix(shader.color);
|
||
|
setPrimaryColor(0.0f, 0.0f, 0.0f, 0.5f);
|
||
|
drawQuad(shader.color, vertices, 0);
|
||
|
|
||
|
glUseProgram(0);
|
||
|
|
||
|
glDisable(GL_BLEND);
|
||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||
|
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName);
|
||
|
|
||
|
yoffset += h;
|
||
|
|
||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||
|
#endif
|
||
|
}
|
||
|
xoffset += w;
|
||
|
}
|
||
|
|
||
|
|
||
|
setPixelCoords(false);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
inline int sortOutPCamera(int cX, int fX, int sceneMax, int boxMax) {
|
||
|
return (fX == 65535) ?
|
||
|
(sceneMax ? ((cX * boxMax) / sceneMax) : 0)
|
||
|
:
|
||
|
((cX * fX) / 100);
|
||
|
}
|
||
|
|
||
|
|
||
|
void drawBackDrop() {
|
||
|
#if 0
|
||
|
setPrimaryColor(1.0, 1.0, 1.0, 1.0);
|
||
|
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||
|
glEnable(GL_BLEND);
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
if (parallaxStuff) {
|
||
|
parallaxLayer *ps = parallaxStuff;
|
||
|
|
||
|
while (ps->next) ps = ps->next;
|
||
|
|
||
|
while (ps) {
|
||
|
ps -> cameraX = sortOutPCamera(cameraX, ps -> fractionX, (int)(sceneWidth - (float)winWidth / cameraZoom), (int)(ps -> width - (float)winWidth / cameraZoom));
|
||
|
ps -> cameraY = sortOutPCamera(cameraY, ps -> fractionY, (int)(sceneHeight - (float)winHeight / cameraZoom), (int)(ps -> height - (float)winHeight / cameraZoom));
|
||
|
glBindTexture(GL_TEXTURE_2D, ps->textureName);
|
||
|
|
||
|
float w = (ps->wrapS) ? sceneWidth : ps->width;
|
||
|
float h = (ps->wrapT) ? sceneHeight : ps->height;
|
||
|
float texw;
|
||
|
float texh;
|
||
|
if (! NPOT_textures) {
|
||
|
texw = (ps->wrapS) ? (float) sceneWidth / ps->width : (float) ps->width / getNextPOT(ps->width);
|
||
|
texh = (ps->wrapT) ? (float) sceneHeight / ps->height : (float) ps->height / getNextPOT(ps->height);
|
||
|
} else {
|
||
|
texw = (ps->wrapS) ? (float) sceneWidth / ps->width : 1.0;
|
||
|
texh = (ps->wrapT) ? (float) sceneHeight / ps->height : 1.0;
|
||
|
}
|
||
|
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - ps -> cameraX, (GLfloat) - ps -> cameraY, 0.1f,
|
||
|
w - ps -> cameraX, (GLfloat) - ps -> cameraY, 0.1f,
|
||
|
(GLfloat) - ps -> cameraX, h - ps -> cameraY, 0.1f,
|
||
|
w - ps -> cameraX, h - ps -> cameraY, 0.1f
|
||
|
};
|
||
|
|
||
|
const GLfloat texCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
texw, 0.0f,
|
||
|
0.0f, texh,
|
||
|
texw, texh
|
||
|
};
|
||
|
drawQuad(shader.smartScaler, vertices, 1, texCoords);
|
||
|
|
||
|
ps = ps -> prev;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
glBindTexture(GL_TEXTURE_2D, backdropTextureName);
|
||
|
|
||
|
const GLfloat backdropTexCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
backdropTexW, 0.0f,
|
||
|
0.0f, backdropTexH,
|
||
|
backdropTexW, backdropTexH
|
||
|
};
|
||
|
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - cameraX, (GLfloat) - cameraY, 0.,
|
||
|
(GLfloat)sceneWidth - (GLfloat)cameraX, (GLfloat) - cameraY, 0.,
|
||
|
(GLfloat) - cameraX, (GLfloat)sceneHeight - (GLfloat)cameraY, 0.,
|
||
|
(GLfloat)sceneWidth - (GLfloat)cameraX, (GLfloat)sceneHeight - (GLfloat)cameraY, 0.
|
||
|
};
|
||
|
|
||
|
drawQuad(shader.smartScaler, vertices, 1, backdropTexCoords);
|
||
|
|
||
|
glDisable(GL_BLEND);
|
||
|
|
||
|
glUseProgram(0);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool loadLightMap(int v) {
|
||
|
int newPicWidth, newPicHeight;
|
||
|
#if ALLOW_FILE
|
||
|
setResourceForFatal(v);
|
||
|
if (! openFileFromNum(v)) return fatal("Can't open light map.");
|
||
|
long file_pointer = ftell(bigDataFile);
|
||
|
|
||
|
png_structp png_ptr;
|
||
|
png_infop info_ptr, end_info;
|
||
|
|
||
|
|
||
|
int fileIsPNG = true;
|
||
|
|
||
|
// Is this a PNG file?
|
||
|
|
||
|
char tmp[10];
|
||
|
size_t bytes_read = fread(tmp, 1, 8, bigDataFile);
|
||
|
if (bytes_read != 8 && ferror(bigDataFile)) {
|
||
|
debugOut("Reading error in loadLightMap.\n");
|
||
|
}
|
||
|
|
||
|
if (png_sig_cmp((png_byte *) tmp, 0, 8)) {
|
||
|
// No, it's old-school HSI
|
||
|
fileIsPNG = false;
|
||
|
fseek(bigDataFile, file_pointer, SEEK_SET);
|
||
|
|
||
|
newPicWidth = lightMap.w = get2bytes(bigDataFile);
|
||
|
newPicHeight = lightMap.h = get2bytes(bigDataFile);
|
||
|
} else {
|
||
|
// Read the PNG header
|
||
|
|
||
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||
|
if (!png_ptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (!info_ptr) {
|
||
|
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
end_info = png_create_info_struct(png_ptr);
|
||
|
if (!end_info) {
|
||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||
|
return false;
|
||
|
}
|
||
|
png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read
|
||
|
png_set_sig_bytes(png_ptr, 8); // 8 bytes already read
|
||
|
|
||
|
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);
|
||
|
|
||
|
newPicWidth = lightMap.w = width;
|
||
|
newPicHeight = lightMap.h = height;
|
||
|
|
||
|
if (bit_depth < 8) png_set_packing(png_ptr);
|
||
|
png_set_expand(png_ptr);
|
||
|
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
|
||
|
if (bit_depth == 16) png_set_strip_16(png_ptr);
|
||
|
|
||
|
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||
|
|
||
|
png_read_update_info(png_ptr, info_ptr);
|
||
|
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);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (lightMapMode == LIGHTMAPMODE_HOTSPOT) {
|
||
|
if (lightMap.w != sceneWidth || lightMap.h != sceneHeight) {
|
||
|
return fatal("Light map width and height don't match scene width and height. That is required for lightmaps in HOTSPOT mode.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (! NPOT_textures) {
|
||
|
newPicWidth = getNextPOT(lightMap.w);
|
||
|
newPicHeight = getNextPOT(lightMap.h);
|
||
|
lightMap.texW = (double) lightMap.w / newPicWidth;
|
||
|
lightMap.texH = (double) lightMap.h / newPicHeight;
|
||
|
} else {
|
||
|
lightMap.texW = 1.0;
|
||
|
lightMap.texH = 1.0;
|
||
|
}
|
||
|
|
||
|
killLightMap();
|
||
|
lightMapNumber = v;
|
||
|
#if 0
|
||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||
|
#endif
|
||
|
if (lightMap.data) delete [] lightMap.data;
|
||
|
|
||
|
lightMap.data = new GLubyte [newPicWidth * newPicHeight * 4];
|
||
|
if (! lightMap.data) {
|
||
|
return fatal("Out of memory loading light map.");
|
||
|
}
|
||
|
|
||
|
int t1, t2, n;
|
||
|
unsigned short c;
|
||
|
GLubyte *target;
|
||
|
|
||
|
if (fileIsPNG) {
|
||
|
unsigned char *row_pointers[lightMap.h];
|
||
|
for (int i = 0; i < lightMap.h; i++)
|
||
|
row_pointers[i] = lightMap.data + 4 * i * newPicWidth;
|
||
|
|
||
|
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);
|
||
|
} else {
|
||
|
|
||
|
for (t2 = 0; t2 < lightMap.h; t2 ++) {
|
||
|
t1 = 0;
|
||
|
while (t1 < lightMap.w) {
|
||
|
c = (unsigned short) get2bytes(bigDataFile);
|
||
|
if (c & 32) {
|
||
|
n = fgetc(bigDataFile) + 1;
|
||
|
c -= 32;
|
||
|
} else {
|
||
|
n = 1;
|
||
|
}
|
||
|
while (n --) {
|
||
|
target = lightMap.data + 4 * newPicWidth * t2 + t1 * 4;
|
||
|
target[0] = (GLubyte) redValue(c);
|
||
|
target[1] = (GLubyte) greenValue(c);
|
||
|
target[2] = (GLubyte) blueValue(c);
|
||
|
target[3] = (GLubyte) 255;
|
||
|
t1++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#if 0
|
||
|
if (! lightMap.name) glGenTextures(1, &lightMap.name);
|
||
|
glBindTexture(GL_TEXTURE_2D, lightMap.name);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||
|
#endif
|
||
|
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, newPicWidth, newPicHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightMap.data, lightMap.name);
|
||
|
|
||
|
finishAccess();
|
||
|
|
||
|
#endif
|
||
|
setResourceForFatal(-1);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void reloadParallaxTextures() {
|
||
|
#if 0
|
||
|
parallaxLayer *nP = parallaxStuff;
|
||
|
if (! nP) return;
|
||
|
|
||
|
while (nP) {
|
||
|
//fprintf (stderr, "Reloading parallax. (%d, %d) ", nP->width, nP->height);
|
||
|
nP->textureName = 0;
|
||
|
|
||
|
glGenTextures(1, &nP->textureName);
|
||
|
glBindTexture(GL_TEXTURE_2D, nP->textureName);
|
||
|
if (nP -> wrapS)
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||
|
else
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
if (nP -> wrapT)
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||
|
else
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
if (! NPOT_textures) {
|
||
|
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getNextPOT(nP->width), getNextPOT(nP->height), 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName);
|
||
|
} else {
|
||
|
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nP->width, nP->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName);
|
||
|
}
|
||
|
|
||
|
nP = nP->next;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool loadParallax(unsigned short v, unsigned short fracX, unsigned short fracY) {
|
||
|
|
||
|
#if ALLOW_FILE
|
||
|
setResourceForFatal(v);
|
||
|
if (! openFileFromNum(v)) return fatal("Can't open parallax image");
|
||
|
|
||
|
parallaxLayer *nP = new parallaxLayer;
|
||
|
if (! checkNew(nP)) return false;
|
||
|
|
||
|
nP -> next = parallaxStuff;
|
||
|
parallaxStuff = nP;
|
||
|
if (nP -> next) {
|
||
|
nP -> next -> prev = nP;
|
||
|
}
|
||
|
nP -> prev = NULL;
|
||
|
|
||
|
int picWidth;
|
||
|
int picHeight;
|
||
|
|
||
|
long file_pointer = ftell(bigDataFile);
|
||
|
|
||
|
png_structp png_ptr;
|
||
|
png_infop info_ptr, end_info;
|
||
|
|
||
|
|
||
|
int fileIsPNG = true;
|
||
|
|
||
|
// Is this a PNG file?
|
||
|
|
||
|
char tmp[10];
|
||
|
size_t bytes_read = fread(tmp, 1, 8, bigDataFile);
|
||
|
if (bytes_read != 8 && ferror(bigDataFile)) {
|
||
|
debugOut("Reading error in loadParallax.\n");
|
||
|
}
|
||
|
if (png_sig_cmp((png_byte *) tmp, 0, 8)) {
|
||
|
// No, it's old-school HSI
|
||
|
fileIsPNG = false;
|
||
|
fseek(bigDataFile, file_pointer, SEEK_SET);
|
||
|
|
||
|
picWidth = nP -> width = get2bytes(bigDataFile);
|
||
|
picHeight = nP -> height = get2bytes(bigDataFile);
|
||
|
} else {
|
||
|
// Read the PNG header
|
||
|
|
||
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||
|
if (!png_ptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (!info_ptr) {
|
||
|
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
end_info = png_create_info_struct(png_ptr);
|
||
|
if (!end_info) {
|
||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||
|
return false;
|
||
|
}
|
||
|
png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read
|
||
|
png_set_sig_bytes(png_ptr, 8); // 8 bytes already read
|
||
|
|
||
|
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);
|
||
|
|
||
|
picWidth = nP -> width = width;
|
||
|
picHeight = nP -> height = height;
|
||
|
|
||
|
if (bit_depth < 8) png_set_packing(png_ptr);
|
||
|
png_set_expand(png_ptr);
|
||
|
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
|
||
|
if (bit_depth == 16) png_set_strip_16(png_ptr);
|
||
|
|
||
|
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||
|
|
||
|
png_read_update_info(png_ptr, info_ptr);
|
||
|
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);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (! NPOT_textures) {
|
||
|
picWidth = getNextPOT(picWidth);
|
||
|
picHeight = getNextPOT(picHeight);
|
||
|
}
|
||
|
|
||
|
nP -> fileNum = v;
|
||
|
nP -> fractionX = fracX;
|
||
|
nP -> fractionY = fracY;
|
||
|
|
||
|
if (fracX == 65535) {
|
||
|
nP -> wrapS = false;
|
||
|
if (nP -> width < winWidth) {
|
||
|
fatal("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen.");
|
||
|
return false;
|
||
|
}
|
||
|
} else {
|
||
|
nP -> wrapS = true;
|
||
|
}
|
||
|
|
||
|
if (fracY == 65535) {
|
||
|
nP -> wrapT = false;
|
||
|
if (nP -> height < winHeight) {
|
||
|
fatal("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen.");
|
||
|
return false;
|
||
|
}
|
||
|
} else {
|
||
|
nP -> wrapT = true;
|
||
|
}
|
||
|
|
||
|
nP -> texture = new GLubyte [picHeight * picWidth * 4];
|
||
|
if (! checkNew(nP -> texture)) return false;
|
||
|
|
||
|
if (fileIsPNG) {
|
||
|
unsigned char *row_pointers[nP -> height];
|
||
|
for (int i = 0; i < nP -> height; i++)
|
||
|
row_pointers[i] = nP -> texture + 4 * i * picWidth;
|
||
|
|
||
|
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);
|
||
|
} else {
|
||
|
|
||
|
int t1, t2, n;
|
||
|
unsigned short c;
|
||
|
GLubyte *target;
|
||
|
|
||
|
for (t2 = 0; t2 < nP -> height; t2 ++) {
|
||
|
t1 = 0;
|
||
|
while (t1 < nP -> width) {
|
||
|
c = (unsigned short) get2bytes(bigDataFile);
|
||
|
if (c & 32) {
|
||
|
n = fgetc(bigDataFile) + 1;
|
||
|
c -= 32;
|
||
|
} else {
|
||
|
n = 1;
|
||
|
}
|
||
|
while (n--) {
|
||
|
target = nP -> texture + 4 * picWidth * t2 + t1 * 4;
|
||
|
if (c == 63519 || c == 2015) {
|
||
|
target[0] = (GLubyte) 0;
|
||
|
target[1] = (GLubyte) 0;
|
||
|
target[2] = (GLubyte) 0;
|
||
|
target[3] = (GLubyte) 0;
|
||
|
} else {
|
||
|
target[0] = (GLubyte) redValue(c);
|
||
|
target[1] = (GLubyte) greenValue(c);
|
||
|
target[2] = (GLubyte) blueValue(c);
|
||
|
target[3] = (GLubyte) 255;
|
||
|
}
|
||
|
t1 ++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
glGenTextures(1, &nP->textureName);
|
||
|
glBindTexture(GL_TEXTURE_2D, nP->textureName);
|
||
|
if (nP -> wrapS)
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||
|
else
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
if (nP -> wrapT)
|
||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||
|
else
|
||
|
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, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName);
|
||
|
|
||
|
finishAccess();
|
||
|
#endif
|
||
|
setResourceForFatal(-1);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
extern int viewportOffsetX, viewportOffsetY;
|
||
|
|
||
|
#if ALLOW_FILE
|
||
|
bool loadHSI(FILE *fp, int x, int y, bool reserve) {
|
||
|
|
||
|
int t1, t2, n;
|
||
|
unsigned short c;
|
||
|
GLubyte *target;
|
||
|
int32_t transCol = reserve ? -1 : 63519;
|
||
|
int picWidth;
|
||
|
int picHeight;
|
||
|
int realPicWidth, realPicHeight;
|
||
|
long file_pointer = ftell(fp);
|
||
|
|
||
|
png_structp png_ptr;
|
||
|
png_infop info_ptr, end_info;
|
||
|
|
||
|
|
||
|
int fileIsPNG = true;
|
||
|
|
||
|
// Is this a PNG file?
|
||
|
|
||
|
char tmp[10];
|
||
|
size_t bytes_read = fread(tmp, 1, 8, fp);
|
||
|
if (bytes_read != 8 && ferror(fp)) {
|
||
|
debugOut("Reading error in loadHSI.\n");
|
||
|
}
|
||
|
if (png_sig_cmp((png_byte *) tmp, 0, 8)) {
|
||
|
// No, it's old-school HSI
|
||
|
fileIsPNG = false;
|
||
|
fseek(fp, file_pointer, SEEK_SET);
|
||
|
|
||
|
picWidth = realPicWidth = get2bytes(fp);
|
||
|
picHeight = realPicHeight = get2bytes(fp);
|
||
|
} else {
|
||
|
// Read the PNG header
|
||
|
|
||
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||
|
if (!png_ptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (!info_ptr) {
|
||
|
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
end_info = png_create_info_struct(png_ptr);
|
||
|
if (!end_info) {
|
||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||
|
return false;
|
||
|
}
|
||
|
png_init_io(png_ptr, fp); // Tell libpng which file to read
|
||
|
png_set_sig_bytes(png_ptr, 8); // 8 bytes already read
|
||
|
|
||
|
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);
|
||
|
|
||
|
picWidth = realPicWidth = width;
|
||
|
picHeight = realPicHeight = height;
|
||
|
|
||
|
if (bit_depth < 8) png_set_packing(png_ptr);
|
||
|
png_set_expand(png_ptr);
|
||
|
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
|
||
|
if (bit_depth == 16) png_set_strip_16(png_ptr);
|
||
|
|
||
|
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||
|
|
||
|
png_read_update_info(png_ptr, info_ptr);
|
||
|
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);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
GLfloat texCoordW = 1.0;
|
||
|
GLfloat texCoordH = 1.0;
|
||
|
if (! NPOT_textures) {
|
||
|
picWidth = getNextPOT(picWidth);
|
||
|
picHeight = getNextPOT(picHeight);
|
||
|
texCoordW = ((double)realPicWidth) / picWidth;
|
||
|
texCoordH = ((double)realPicHeight) / picHeight;
|
||
|
}
|
||
|
|
||
|
if (reserve) {
|
||
|
if (! resizeBackdrop(realPicWidth, realPicHeight)) return false;
|
||
|
}
|
||
|
|
||
|
if (x == IN_THE_CENTRE) x = (sceneWidth - realPicWidth) >> 1;
|
||
|
if (y == IN_THE_CENTRE) y = (sceneHeight - realPicHeight) >> 1;
|
||
|
if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) return false;
|
||
|
|
||
|
if (fileIsPNG) {
|
||
|
unsigned char *row_pointers[realPicHeight];
|
||
|
for (int i = 0; i < realPicHeight; i++)
|
||
|
row_pointers[i] = backdropTexture + 4 * i * picWidth;
|
||
|
|
||
|
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);
|
||
|
} else {
|
||
|
for (t2 = 0; t2 < realPicHeight; t2 ++) {
|
||
|
t1 = 0;
|
||
|
while (t1 < realPicWidth) {
|
||
|
c = (unsigned short) get2bytes(fp);
|
||
|
if (c & 32) {
|
||
|
n = fgetc(fp) + 1;
|
||
|
c -= 32;
|
||
|
} else {
|
||
|
n = 1;
|
||
|
}
|
||
|
while (n --) {
|
||
|
target = backdropTexture + 4 * picWidth * t2 + t1 * 4;
|
||
|
if (c == transCol || c == 2015) {
|
||
|
target[0] = (GLubyte) 0;
|
||
|
target[1] = (GLubyte) 0;
|
||
|
target[2] = (GLubyte) 0;
|
||
|
target[3] = (GLubyte) 0;
|
||
|
} else {
|
||
|
target[0] = (GLubyte) redValue(c);
|
||
|
target[1] = (GLubyte) greenValue(c);
|
||
|
target[2] = (GLubyte) blueValue(c);
|
||
|
target[3] = (GLubyte) 255;
|
||
|
}
|
||
|
t1++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GLuint tmpTex;
|
||
|
#if 0
|
||
|
glGenTextures(1, &tmpTex);
|
||
|
glBindTexture(GL_TEXTURE_2D, tmpTex);
|
||
|
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);
|
||
|
}
|
||
|
#endif
|
||
|
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, tmpTex);
|
||
|
|
||
|
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||
|
|
||
|
|
||
|
float btx1;
|
||
|
float btx2;
|
||
|
float bty1;
|
||
|
float bty2;
|
||
|
if (! NPOT_textures) {
|
||
|
btx1 = backdropTexW * x / sceneWidth;
|
||
|
btx2 = backdropTexW * (x + realPicWidth) / sceneWidth;
|
||
|
bty1 = backdropTexH * y / sceneHeight;
|
||
|
bty2 = backdropTexH * (y + realPicHeight) / sceneHeight;
|
||
|
} else {
|
||
|
btx1 = (float) x / sceneWidth;
|
||
|
btx2 = (float)(x + realPicWidth) / sceneWidth;
|
||
|
bty1 = (float) y / sceneHeight;
|
||
|
bty2 = (float)(y + realPicHeight) / sceneHeight;
|
||
|
}
|
||
|
|
||
|
const GLfloat btexCoords[] = {
|
||
|
btx1, bty1,
|
||
|
btx2, bty1,
|
||
|
btx1, bty2,
|
||
|
btx2, bty2
|
||
|
};
|
||
|
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < realPicWidth) {
|
||
|
int w = (realPicWidth - xoffset < viewportWidth) ? realPicWidth - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < realPicHeight) {
|
||
|
int h = (realPicHeight - yoffset < viewportHeight) ? realPicHeight - yoffset : viewportHeight;
|
||
|
#if 0
|
||
|
glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen
|
||
|
#endif
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat)realPicWidth - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset + realPicHeight, 0.,
|
||
|
(GLfloat)realPicWidth - xoffset, (GLfloat) - yoffset + realPicHeight, 0.
|
||
|
};
|
||
|
|
||
|
const GLfloat texCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
texCoordW, 0.0f,
|
||
|
0.0f, texCoordH,
|
||
|
texCoordW, texCoordH
|
||
|
};
|
||
|
|
||
|
if (backdropExists) {
|
||
|
#if 0
|
||
|
// Render the sprite to the backdrop
|
||
|
// (using mulitexturing, so the old 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
|
||
|
#endif
|
||
|
setPMVMatrix(shader.paste);
|
||
|
|
||
|
setPrimaryColor(1.0, 1.0, 1.0, 1.0);
|
||
|
#if 0
|
||
|
glBindTexture(GL_TEXTURE_2D, tmpTex);
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||
|
#endif
|
||
|
drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords);
|
||
|
#if 0
|
||
|
glUseProgram(0);
|
||
|
#endif
|
||
|
} else {
|
||
|
// It's all new - nothing special to be done.
|
||
|
|
||
|
#if 0
|
||
|
glUseProgram(shader.texture);
|
||
|
#endif
|
||
|
setPMVMatrix(shader.texture);
|
||
|
#if 0
|
||
|
glBindTexture(GL_TEXTURE_2D, tmpTex);
|
||
|
#endif
|
||
|
setPrimaryColor(1.0, 0.0, 0.0, 0.0);
|
||
|
|
||
|
drawQuad(shader.texture, vertices, 1, texCoords);
|
||
|
|
||
|
#if 0
|
||
|
glUseProgram(0);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, x + xoffset, y + yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName);
|
||
|
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
deleteTextures(1, &tmpTex);
|
||
|
|
||
|
setPixelCoords(false);
|
||
|
|
||
|
backdropExists = true;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool mixHSI(FILE *fp, int x, int y) {
|
||
|
int realPicWidth, realPicHeight;
|
||
|
int picWidth;
|
||
|
int picHeight;
|
||
|
|
||
|
long file_pointer = ftell(fp);
|
||
|
|
||
|
png_structp png_ptr;
|
||
|
png_infop info_ptr, end_info;
|
||
|
|
||
|
|
||
|
int fileIsPNG = true;
|
||
|
|
||
|
// Is this a PNG file?
|
||
|
char tmp[10];
|
||
|
size_t bytes_read = fread(tmp, 1, 8, fp);
|
||
|
if (bytes_read != 8 && ferror(fp)) {
|
||
|
debugOut("Reading error in mixHSI.\n");
|
||
|
}
|
||
|
if (png_sig_cmp((png_byte *) tmp, 0, 8)) {
|
||
|
// No, it's old-school HSI
|
||
|
fileIsPNG = false;
|
||
|
fseek(fp, file_pointer, SEEK_SET);
|
||
|
|
||
|
picWidth = realPicWidth = get2bytes(fp);
|
||
|
picHeight = realPicHeight = get2bytes(fp);
|
||
|
} else {
|
||
|
// Read the PNG header
|
||
|
|
||
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||
|
if (!png_ptr) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (!info_ptr) {
|
||
|
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
end_info = png_create_info_struct(png_ptr);
|
||
|
if (!end_info) {
|
||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||
|
return false;
|
||
|
}
|
||
|
png_init_io(png_ptr, fp); // Tell libpng which file to read
|
||
|
png_set_sig_bytes(png_ptr, 8); // 8 bytes already read
|
||
|
|
||
|
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);
|
||
|
|
||
|
picWidth = realPicWidth = width;
|
||
|
picHeight = realPicHeight = height;
|
||
|
|
||
|
if (bit_depth < 8) png_set_packing(png_ptr);
|
||
|
png_set_expand(png_ptr);
|
||
|
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
|
||
|
if (bit_depth == 16) png_set_strip_16(png_ptr);
|
||
|
|
||
|
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||
|
|
||
|
png_read_update_info(png_ptr, info_ptr);
|
||
|
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);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (x == IN_THE_CENTRE) x = (sceneWidth - realPicWidth) >> 1;
|
||
|
if (y == IN_THE_CENTRE) y = (sceneHeight - realPicHeight) >> 1;
|
||
|
if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) return false;
|
||
|
|
||
|
float btx1, tx1;
|
||
|
float btx2, tx2;
|
||
|
float bty1, ty1;
|
||
|
float bty2, ty2;
|
||
|
|
||
|
if (! NPOT_textures) {
|
||
|
tx1 = 0.0;
|
||
|
ty1 = 0.0;
|
||
|
tx2 = ((double)picWidth) / getNextPOT(picWidth);
|
||
|
ty2 = ((double)picHeight) / getNextPOT(picHeight);
|
||
|
picWidth = getNextPOT(picWidth);
|
||
|
picHeight = getNextPOT(picHeight);
|
||
|
btx1 = backdropTexW * x / sceneWidth;
|
||
|
btx2 = backdropTexW * (x + realPicWidth) / sceneWidth;
|
||
|
bty1 = backdropTexH * y / sceneHeight;
|
||
|
bty2 = backdropTexH * (y + realPicHeight) / sceneHeight;
|
||
|
} else {
|
||
|
tx1 = 0.0;
|
||
|
ty1 = 0.0;
|
||
|
tx2 = 1.0;
|
||
|
ty2 = 1.0;
|
||
|
btx1 = (float) x / sceneWidth;
|
||
|
btx2 = (float)(x + picWidth) / sceneWidth;
|
||
|
bty1 = (float) y / sceneHeight;
|
||
|
bty2 = (float)(y + picHeight) / sceneHeight;
|
||
|
}
|
||
|
|
||
|
const GLfloat texCoords[] = {
|
||
|
tx1, ty1,
|
||
|
tx2, ty1,
|
||
|
tx1, ty2,
|
||
|
tx2, ty2
|
||
|
};
|
||
|
|
||
|
const GLfloat btexCoords[] = {
|
||
|
btx1, bty1,
|
||
|
btx2, bty1,
|
||
|
btx1, bty2,
|
||
|
btx2, bty2
|
||
|
};
|
||
|
|
||
|
int t1, t2, n;
|
||
|
unsigned short c;
|
||
|
GLubyte *target;
|
||
|
int32_t transCol = 63519;
|
||
|
|
||
|
|
||
|
if (fileIsPNG) {
|
||
|
unsigned char *row_pointers[realPicHeight];
|
||
|
for (int i = 0; i < realPicHeight; i++)
|
||
|
row_pointers[i] = backdropTexture + 4 * i * picWidth;
|
||
|
|
||
|
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);
|
||
|
} else {
|
||
|
for (t2 = 0; t2 < realPicHeight; t2 ++) {
|
||
|
t1 = 0;
|
||
|
while (t1 < realPicWidth) {
|
||
|
c = (unsigned short) get2bytes(fp);
|
||
|
if (c & 32) {
|
||
|
n = fgetc(fp) + 1;
|
||
|
c -= 32;
|
||
|
} else {
|
||
|
n = 1;
|
||
|
}
|
||
|
while (n --) {
|
||
|
target = backdropTexture + 4 * picWidth * t2 + t1 * 4;
|
||
|
if (c == transCol || c == 2015) {
|
||
|
target[0] = (GLubyte) 0;
|
||
|
target[1] = (GLubyte) 0;
|
||
|
target[2] = (GLubyte) 0;
|
||
|
target[3] = (GLubyte) 0;
|
||
|
} else {
|
||
|
target[0] = (GLubyte) redValue(c);
|
||
|
target[1] = (GLubyte) greenValue(c);
|
||
|
target[2] = (GLubyte) blueValue(c);
|
||
|
target[3] = (GLubyte) 255;
|
||
|
}
|
||
|
t1++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GLuint tmpTex;
|
||
|
#if 0
|
||
|
glGenTextures(1, &tmpTex);
|
||
|
glBindTexture(GL_TEXTURE_2D, tmpTex);
|
||
|
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);
|
||
|
}
|
||
|
#endif
|
||
|
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, tmpTex);
|
||
|
|
||
|
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||
|
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < realPicWidth) {
|
||
|
int w = (realPicWidth - xoffset < viewportWidth) ? realPicWidth - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < realPicHeight) {
|
||
|
int h = (realPicHeight - yoffset < viewportHeight) ? realPicHeight - yoffset : viewportHeight;
|
||
|
#if 0
|
||
|
glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen
|
||
|
|
||
|
// 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
|
||
|
#endif
|
||
|
setPMVMatrix(shader.paste);
|
||
|
|
||
|
setPrimaryColor(1.0, 1.0, 1.0, 0.5);
|
||
|
#if 0
|
||
|
glBindTexture(GL_TEXTURE_2D, tmpTex);
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||
|
#endif
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat)realPicWidth - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset + realPicHeight, 0.,
|
||
|
(GLfloat)realPicWidth - xoffset, (GLfloat) - yoffset + realPicHeight, 0.
|
||
|
};
|
||
|
|
||
|
drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords);
|
||
|
#if 0
|
||
|
// Copy Our ViewPort To The Texture
|
||
|
glUseProgram(0);
|
||
|
#endif
|
||
|
copyTexSubImage2D(GL_TEXTURE_2D, 0, (int)((x < 0) ? xoffset : x + xoffset), (int)((y < 0) ? yoffset : y + yoffset), (int)((x < 0) ? viewportOffsetX - x : viewportOffsetX), (int)((y < 0) ? viewportOffsetY - y : viewportOffsetY), w, h, backdropTextureName);
|
||
|
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
deleteTextures(1, &tmpTex);
|
||
|
setPixelCoords(false);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void saveCorePNG(FILE *writer, GLuint texture, int w, int h) {
|
||
|
GLint tw, th;
|
||
|
#if 0
|
||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||
|
#endif
|
||
|
getTextureDimensions(texture, &tw, &th);
|
||
|
|
||
|
GLubyte *image = new GLubyte [tw * th * 4];
|
||
|
if (! checkNew(image)) return;
|
||
|
#if 0
|
||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||
|
// glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||
|
#endif
|
||
|
#ifdef HAVE_GLES2
|
||
|
#if 0
|
||
|
GLuint old_fbo, new_fbo;
|
||
|
GLint old_vp[4];
|
||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&old_fbo);
|
||
|
glGetIntegerv(GL_VIEWPORT, old_vp);
|
||
|
glGenFramebuffers(1, &new_fbo);
|
||
|
glBindFramebuffer(GL_FRAMEBUFFER, new_fbo);
|
||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||
|
glViewport(0, 0, tw, th);
|
||
|
glReadPixels(0, 0, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||
|
glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
|
||
|
glViewport(old_vp[0], old_vp[1], old_vp[2], old_vp[3]);
|
||
|
glDeleteFramebuffers(1, &new_fbo);
|
||
|
#endif
|
||
|
#else
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||
|
|
||
|
const GLfloat texCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
1.0f, 0.0f,
|
||
|
0.0f, 1.0f,
|
||
|
1.0f, 1.0f
|
||
|
};
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < tw) {
|
||
|
int w = (tw - xoffset < viewportWidth) ? tw - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < th) {
|
||
|
int h = (th - yoffset < viewportHeight) ? th - yoffset : viewportHeight;
|
||
|
#if 0
|
||
|
glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen
|
||
|
#endif
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat)tw - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset + th, 0.,
|
||
|
(GLfloat)tw - xoffset, (GLfloat) - yoffset + th, 0.
|
||
|
};
|
||
|
|
||
|
#if 0
|
||
|
glUseProgram(shader.texture);
|
||
|
#endif
|
||
|
setPMVMatrix(shader.texture);
|
||
|
|
||
|
drawQuad(shader.texture, vertices, 1, texCoords);
|
||
|
#if 0
|
||
|
glUseProgram(0);
|
||
|
|
||
|
for (int i = 0; i < h; i++) {
|
||
|
glReadPixels(viewportOffsetX, viewportOffsetY + i, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, image + xoffset * 4 + (yoffset + i) * 4 * tw);
|
||
|
}
|
||
|
#endif
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
setPixelCoords(false);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||
|
if (!png_ptr) {
|
||
|
fatal("Error saving image!");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (!info_ptr) {
|
||
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||
|
fatal("Error saving image!");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
png_init_io(png_ptr, writer);
|
||
|
|
||
|
png_set_IHDR(png_ptr, info_ptr, w, h,
|
||
|
8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||
|
|
||
|
unsigned char *row_pointers[h];
|
||
|
|
||
|
for (int i = 0; i < h; i++) {
|
||
|
row_pointers[i] = image + 4 * i * tw;
|
||
|
}
|
||
|
|
||
|
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||
|
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||
|
|
||
|
delete [] image;
|
||
|
image = NULL;
|
||
|
}
|
||
|
|
||
|
void saveCoreHSI(FILE *writer, GLuint texture, int w, int h) {
|
||
|
|
||
|
GLint tw, th;
|
||
|
#if 0
|
||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||
|
#endif
|
||
|
getTextureDimensions(texture, &tw, &th);
|
||
|
|
||
|
GLushort *image = new GLushort [tw * th];
|
||
|
if (! checkNew(image)) return;
|
||
|
#if 0
|
||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||
|
// glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, image);
|
||
|
#endif
|
||
|
setPixelCoords(true);
|
||
|
|
||
|
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||
|
|
||
|
const GLfloat texCoords[] = {
|
||
|
0.0f, 0.0f,
|
||
|
1.0f, 0.0f,
|
||
|
0.0f, 1.0f,
|
||
|
1.0f, 1.0f
|
||
|
};
|
||
|
|
||
|
int xoffset = 0;
|
||
|
while (xoffset < tw) {
|
||
|
int w = (tw - xoffset < viewportWidth) ? tw - xoffset : viewportWidth;
|
||
|
|
||
|
int yoffset = 0;
|
||
|
while (yoffset < th) {
|
||
|
int h = (th - yoffset < viewportHeight) ? th - yoffset : viewportHeight;
|
||
|
#if 0
|
||
|
glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen
|
||
|
#endif
|
||
|
const GLfloat vertices[] = {
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat)w - xoffset, (GLfloat) - yoffset, 0.,
|
||
|
(GLfloat) - xoffset, (GLfloat) - yoffset + h, 0.,
|
||
|
(GLfloat)w - xoffset, (GLfloat) - yoffset + h, 0.
|
||
|
};
|
||
|
|
||
|
#if 0
|
||
|
glUseProgram(shader.texture);
|
||
|
#endif
|
||
|
setPMVMatrix(shader.texture);
|
||
|
drawQuad(shader.texture, vertices, 1, texCoords);
|
||
|
#if 0
|
||
|
glUseProgram(0);
|
||
|
|
||
|
for (int i = 0; i < h; i++) {
|
||
|
glReadPixels(viewportOffsetX, viewportOffsetY + i, w, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, image + xoffset + (yoffset + i)*tw);
|
||
|
}
|
||
|
#endif
|
||
|
yoffset += viewportHeight;
|
||
|
}
|
||
|
|
||
|
xoffset += viewportWidth;
|
||
|
}
|
||
|
//glReadPixels(viewportOffsetX, viewportOffsetY, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||
|
|
||
|
setPixelCoords(false);
|
||
|
|
||
|
|
||
|
|
||
|
int x, y, lookAhead;
|
||
|
unsigned short int *fromHere, * lookPointer;
|
||
|
|
||
|
put2bytes(w, writer);
|
||
|
put2bytes(h, writer);
|
||
|
|
||
|
for (y = 0; y < h; y ++) {
|
||
|
fromHere = image + (y * tw);
|
||
|
x = 0;
|
||
|
while (x < w) {
|
||
|
lookPointer = fromHere + 1;
|
||
|
for (lookAhead = x + 1; lookAhead < w; lookAhead ++) {
|
||
|
if (lookAhead - x == 256) break;
|
||
|
if (* fromHere != * lookPointer) break;
|
||
|
lookPointer ++;
|
||
|
}
|
||
|
if (lookAhead == x + 1) {
|
||
|
put2bytes((* fromHere) & 65503, writer);
|
||
|
} else {
|
||
|
put2bytes(* fromHere | 32, writer);
|
||
|
fputc(lookAhead - x - 1, writer);
|
||
|
}
|
||
|
fromHere = lookPointer;
|
||
|
x = lookAhead;
|
||
|
}
|
||
|
}
|
||
|
delete [] image;
|
||
|
image = NULL;
|
||
|
}
|
||
|
|
||
|
void saveHSI(FILE *writer) {
|
||
|
saveCorePNG(writer, backdropTextureName, sceneWidth, sceneHeight);
|
||
|
}
|
||
|
|
||
|
|
||
|
void saveParallaxRecursive(parallaxLayer *me, FILE *fp) {
|
||
|
if (me) {
|
||
|
saveParallaxRecursive(me -> next, fp);
|
||
|
fputc(1, fp);
|
||
|
put2bytes(me->fileNum, fp);
|
||
|
put2bytes(me ->fractionX, fp);
|
||
|
put2bytes(me->fractionY, fp);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
bool getRGBIntoStack(unsigned int x, unsigned int y, stackHandler *sH) {
|
||
|
#if 0
|
||
|
if (x >= sceneWidth || y >= sceneHeight) {
|
||
|
return fatal("Co-ordinates are outside current scene!");
|
||
|
}
|
||
|
|
||
|
variable newValue;
|
||
|
|
||
|
newValue.varType = SVT_NULL;
|
||
|
|
||
|
saveTexture(backdropTextureName, backdropTexture);
|
||
|
|
||
|
GLubyte *target;
|
||
|
if (! NPOT_textures) {
|
||
|
target = backdropTexture + 4 * getNextPOT(sceneWidth) * y + x * 4;
|
||
|
} else {
|
||
|
target = backdropTexture + 4 * sceneWidth * y + x * 4;
|
||
|
}
|
||
|
|
||
|
setVariable(newValue, SVT_INT, target[2]);
|
||
|
if (! addVarToStackQuick(newValue, sH -> first)) return false;
|
||
|
sH -> last = sH -> first;
|
||
|
|
||
|
setVariable(newValue, SVT_INT, target[1]);
|
||
|
if (! addVarToStackQuick(newValue, sH -> first)) return false;
|
||
|
|
||
|
setVariable(newValue, SVT_INT, target[0]);
|
||
|
if (! addVarToStackQuick(newValue, sH -> first)) return false;
|
||
|
#endif
|
||
|
return true;
|
||
|
}
|