2007-01-15 12:09:25 -08:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
2010-07-26 20:42:11 -07:00
|
|
|
Copyright (C) 2005-2010 Warzone 2100 Project
|
2007-01-15 12:09:25 -08:00
|
|
|
|
|
|
|
Warzone 2100 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.
|
|
|
|
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
/*
|
|
|
|
* Screen.c
|
|
|
|
*
|
|
|
|
* Basic double buffered display using direct draw.
|
|
|
|
*
|
|
|
|
*/
|
2006-06-02 12:34:58 -07:00
|
|
|
|
2010-02-26 13:50:37 -08:00
|
|
|
#include <GLee.h>
|
2007-04-11 07:21:45 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2009-06-14 20:49:21 -07:00
|
|
|
#include "lib/exceptionhandler/dumpinfo.h"
|
2007-04-11 07:21:45 -07:00
|
|
|
#include <physfs.h>
|
2007-04-17 09:53:28 -07:00
|
|
|
#include <png.h>
|
2010-12-31 13:37:14 -08:00
|
|
|
#include "lib/ivis_opengl/png_util.h"
|
|
|
|
#include "lib/ivis_opengl/tex.h"
|
2007-04-17 09:53:28 -07:00
|
|
|
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/frameint.h"
|
2010-12-31 13:37:14 -08:00
|
|
|
#include "lib/ivis_opengl/textdraw.h"
|
|
|
|
#include "lib/ivis_opengl/piestate.h"
|
|
|
|
#include "lib/ivis_opengl/pieblitfunc.h"
|
|
|
|
#include "lib/ivis_opengl/pieclip.h"
|
2009-06-14 20:49:21 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "screen.h"
|
2008-10-03 20:31:18 -07:00
|
|
|
#include "src/console.h"
|
2010-03-19 21:03:28 -07:00
|
|
|
#include "src/levels.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-03-28 08:08:57 -07:00
|
|
|
/* global used to indicate preferred internal OpenGL format */
|
|
|
|
int wz_texture_compression;
|
|
|
|
|
2008-03-24 09:51:17 -07:00
|
|
|
static BOOL bBackDrop = false;
|
2007-11-14 14:29:19 -08:00
|
|
|
static char screendump_filename[PATH_MAX];
|
2008-03-24 09:51:17 -07:00
|
|
|
static BOOL screendump_required = false;
|
2007-11-14 14:29:19 -08:00
|
|
|
static GLuint backDropTexture = ~0;
|
2006-12-31 10:19:19 -08:00
|
|
|
|
2010-06-03 11:54:59 -07:00
|
|
|
static int preview_width = 0, preview_height = 0;
|
|
|
|
static Vector2i player_pos[MAX_PLAYERS];
|
|
|
|
static BOOL mappreview = false;
|
|
|
|
static char mapname[256];
|
2008-08-01 21:28:58 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
/* Initialise the double buffered display */
|
2010-05-15 18:36:21 -07:00
|
|
|
bool screenInitialise()
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2010-05-15 18:36:21 -07:00
|
|
|
char buf[256];
|
2010-03-06 15:06:35 -08:00
|
|
|
GLint glMaxTUs;
|
2006-11-03 17:11:26 -08:00
|
|
|
|
2010-05-15 18:36:21 -07:00
|
|
|
// Copy this info to be used by the crash handler for the dump file
|
|
|
|
ssprintf(buf, "OpenGL Vendor : %s", glGetString(GL_VENDOR));
|
|
|
|
addDumpInfo(buf);
|
|
|
|
ssprintf(buf, "OpenGL Renderer : %s", glGetString(GL_RENDERER));
|
|
|
|
addDumpInfo(buf);
|
|
|
|
ssprintf(buf, "OpenGL Version : %s", glGetString(GL_VERSION));
|
|
|
|
addDumpInfo(buf);
|
|
|
|
if (GLEE_VERSION_2_0)
|
2007-02-21 12:20:26 -08:00
|
|
|
{
|
2010-05-15 18:36:21 -07:00
|
|
|
{
|
|
|
|
ssprintf(buf, "OpenGL GLSL Version : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
|
|
|
addDumpInfo(buf);
|
|
|
|
}
|
2007-02-21 12:20:26 -08:00
|
|
|
}
|
2010-03-06 15:06:35 -08:00
|
|
|
/* Dump general information about OpenGL implementation to the console and the dump file */
|
|
|
|
ssprintf(buf, "OpenGL Vendor : %s", glGetString(GL_VENDOR));
|
|
|
|
addDumpInfo(buf);
|
2010-08-15 03:03:38 -07:00
|
|
|
debug(LOG_3D, "%s", buf);
|
2010-03-06 15:06:35 -08:00
|
|
|
ssprintf(buf, "OpenGL Renderer : %s", glGetString(GL_RENDERER));
|
|
|
|
addDumpInfo(buf);
|
2010-08-15 03:03:38 -07:00
|
|
|
debug(LOG_3D, "%s", buf);
|
2010-03-06 15:06:35 -08:00
|
|
|
ssprintf(buf, "OpenGL Version : %s", glGetString(GL_VERSION));
|
|
|
|
addDumpInfo(buf);
|
2010-08-15 03:03:38 -07:00
|
|
|
debug(LOG_3D, "%s", buf);
|
2009-06-14 20:49:21 -07:00
|
|
|
|
2010-03-06 15:06:35 -08:00
|
|
|
/* Dump extended information about OpenGL implementation to the console */
|
|
|
|
debug(LOG_3D, "OpenGL Extensions : %s", glGetString(GL_EXTENSIONS)); // FIXME This is too much for MAX_LEN_LOG_LINE
|
|
|
|
debug(LOG_3D, "Supported OpenGL extensions:");
|
|
|
|
debug(LOG_3D, " * OpenGL 1.2 %s supported!", GLEE_VERSION_1_2 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 1.3 %s supported!", GLEE_VERSION_1_3 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 1.4 %s supported!", GLEE_VERSION_1_4 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 1.5 %s supported!", GLEE_VERSION_1_5 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 2.0 %s supported!", GLEE_VERSION_2_0 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 2.1 %s supported!", GLEE_VERSION_2_1 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * OpenGL 3.0 %s supported!", GLEE_VERSION_3_0 ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * Texture compression %s supported.", GLEE_ARB_texture_compression ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * Two side stencil %s supported.", GLEE_EXT_stencil_two_side ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * ATI separate stencil is%s supported.", GLEE_ATI_separate_stencil ? "" : " NOT");
|
|
|
|
debug(LOG_3D, " * Stencil wrap %s supported.", GLEE_EXT_stencil_wrap ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * Anisotropic filtering %s supported.", GLEE_EXT_texture_filter_anisotropic ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * Rectangular texture %s supported.", GLEE_ARB_texture_rectangle ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * FrameBuffer Object (FBO) %s supported.", GLEE_EXT_framebuffer_object ? "is" : "is NOT");
|
2010-03-21 09:59:17 -07:00
|
|
|
debug(LOG_3D, " * Vertex Buffer Object (VBO) %s supported.", GLEE_ARB_vertex_buffer_object ? "is" : "is NOT");
|
2010-04-03 14:41:55 -07:00
|
|
|
debug(LOG_3D, " * NPOT %s supported.", GLEE_ARB_texture_non_power_of_two ? "is" : "is NOT");
|
|
|
|
debug(LOG_3D, " * texture cube_map %s supported.", GLEE_ARB_texture_cube_map ? "is" : "is NOT");
|
2010-03-06 15:06:35 -08:00
|
|
|
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &glMaxTUs);
|
2010-03-06 15:54:11 -08:00
|
|
|
debug(LOG_3D, " * Total number of Texture Units (TUs) supported is %d.", (int) glMaxTUs);
|
2010-03-06 15:06:35 -08:00
|
|
|
|
|
|
|
if (!GLEE_VERSION_1_4)
|
|
|
|
{
|
2010-03-21 09:59:17 -07:00
|
|
|
debug(LOG_FATAL, "OpenGL 1.4 + VBO extension is required for this game!");
|
2010-03-06 15:06:35 -08:00
|
|
|
exit(1);
|
|
|
|
}
|
2010-07-21 09:59:37 -07:00
|
|
|
screenWidth = MAX(screenWidth, 640);
|
|
|
|
screenHeight = MAX(screenHeight, 480);
|
2010-03-06 15:06:35 -08:00
|
|
|
|
2009-06-20 08:24:07 -07:00
|
|
|
#ifndef WZ_OS_MAC
|
2009-06-08 07:06:23 -07:00
|
|
|
// Make OpenGL's VBO functions available under the core names for
|
|
|
|
// implementations that have them only as extensions, namely Mesa.
|
2010-03-21 09:59:17 -07:00
|
|
|
if (!GLEE_VERSION_1_5)
|
2009-06-08 07:06:23 -07:00
|
|
|
{
|
2010-03-21 09:59:17 -07:00
|
|
|
if (GLEE_ARB_vertex_buffer_object)
|
|
|
|
{
|
|
|
|
info("Using VBO extension functions under the core names.");
|
|
|
|
|
|
|
|
GLeeFuncPtr_glBindBuffer = GLeeFuncPtr_glBindBufferARB;
|
|
|
|
GLeeFuncPtr_glDeleteBuffers = GLeeFuncPtr_glDeleteBuffersARB;
|
|
|
|
GLeeFuncPtr_glGenBuffers = GLeeFuncPtr_glGenBuffersARB;
|
|
|
|
GLeeFuncPtr_glIsBuffer = GLeeFuncPtr_glIsBufferARB;
|
|
|
|
GLeeFuncPtr_glBufferData = GLeeFuncPtr_glBufferDataARB;
|
|
|
|
GLeeFuncPtr_glBufferSubData = GLeeFuncPtr_glBufferSubDataARB;
|
|
|
|
GLeeFuncPtr_glGetBufferSubData = GLeeFuncPtr_glGetBufferSubDataARB;
|
|
|
|
GLeeFuncPtr_glMapBuffer = GLeeFuncPtr_glMapBufferARB;
|
|
|
|
GLeeFuncPtr_glUnmapBuffer = GLeeFuncPtr_glUnmapBufferARB;
|
|
|
|
GLeeFuncPtr_glGetBufferParameteriv = GLeeFuncPtr_glGetBufferParameterivARB;
|
|
|
|
GLeeFuncPtr_glGetBufferPointerv = GLeeFuncPtr_glGetBufferPointervARB;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
debug(LOG_FATAL, "OpenGL 1.4 + VBO extension is required for this game!");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
debug(LOG_WARNING, "OpenGL 1.5 is not supported by your system! Expect some glitches...");
|
2009-06-08 07:06:23 -07:00
|
|
|
}
|
2009-06-20 08:24:07 -07:00
|
|
|
#endif
|
2009-06-08 07:06:23 -07:00
|
|
|
|
2010-03-06 15:06:35 -08:00
|
|
|
/* Dump information about OpenGL 2.0+ implementation to the console and the dump file */
|
|
|
|
if (GLEE_VERSION_2_0)
|
|
|
|
{
|
|
|
|
GLint glMaxTIUs;
|
|
|
|
|
|
|
|
debug(LOG_3D, " * OpenGL GLSL Version : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
|
|
|
ssprintf(buf, "OpenGL GLSL Version : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
|
|
|
addDumpInfo(buf);
|
|
|
|
|
|
|
|
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &glMaxTIUs);
|
2010-03-06 15:54:11 -08:00
|
|
|
debug(LOG_3D, " * Total number of Texture Image Units (TIUs) supported is %d.", (int) glMaxTIUs);
|
2010-03-06 15:06:35 -08:00
|
|
|
|
2010-12-28 14:35:57 -08:00
|
|
|
pie_LoadShaders();
|
2010-03-06 15:06:35 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-12-07 17:17:50 -08:00
|
|
|
debug(LOG_POPUP, "OpenGL 2.0 is not supported by your system, current shaders require this.");
|
|
|
|
debug(LOG_POPUP, "Team colors will not function correctly on your system.");
|
2010-03-06 15:06:35 -08:00
|
|
|
}
|
|
|
|
|
2008-03-12 12:29:24 -07:00
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
2010-02-04 13:57:37 -08:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
2008-03-12 12:29:24 -07:00
|
|
|
|
2009-10-31 14:17:08 -07:00
|
|
|
glErrors();
|
2008-03-24 09:51:17 -07:00
|
|
|
return true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Release the DD objects */
|
|
|
|
void screenShutDown(void)
|
|
|
|
{
|
2010-02-28 09:23:12 -08:00
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-16 12:22:01 -07:00
|
|
|
void screen_SetBackDropFromFile(const char* filename)
|
2006-12-31 10:19:19 -08:00
|
|
|
{
|
2007-02-20 16:10:03 -08:00
|
|
|
// HACK : We should use a resource handler here!
|
2007-04-16 12:22:01 -07:00
|
|
|
const char *extension = strrchr(filename, '.');// determine the filetype
|
2007-05-01 13:34:54 -07:00
|
|
|
iV_Image image;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-02-20 16:10:03 -08:00
|
|
|
if(!extension)
|
2007-02-07 07:27:17 -08:00
|
|
|
{
|
2007-02-20 16:10:03 -08:00
|
|
|
debug(LOG_ERROR, "Image without extension: \"%s\"!", filename);
|
|
|
|
return; // filename without extension... don't bother
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the current texture page is reloaded after we are finished
|
|
|
|
// Otherwise WZ will think it is still loaded and not load it again
|
2010-12-16 15:36:10 -08:00
|
|
|
pie_SetTexturePage(TEXPAGE_EXTERN);
|
2007-02-10 06:34:12 -08:00
|
|
|
|
2007-04-17 11:24:31 -07:00
|
|
|
if( strcmp(extension,".png") == 0 )
|
2007-02-10 06:34:12 -08:00
|
|
|
{
|
2007-05-01 13:34:54 -07:00
|
|
|
if (iV_loadImage_PNG( filename, &image ) )
|
2007-02-20 16:10:03 -08:00
|
|
|
{
|
|
|
|
if (~backDropTexture == 0)
|
|
|
|
glGenTextures(1, &backDropTexture);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, backDropTexture);
|
2007-06-02 16:01:29 -07:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
2007-05-01 13:34:54 -07:00
|
|
|
image.width, image.height,
|
|
|
|
0, iV_getPixelFormat(&image), GL_UNSIGNED_BYTE, image.bmp);
|
2007-02-20 16:10:03 -08:00
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
|
2007-05-01 13:34:54 -07:00
|
|
|
iV_unloadImage(&image);
|
2007-02-20 16:10:03 -08:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2007-02-10 06:34:12 -08:00
|
|
|
else
|
2007-02-20 16:10:03 -08:00
|
|
|
debug(LOG_ERROR, "Unknown extension \"%s\" for image \"%s\"!", extension, filename);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
//===================================================================
|
|
|
|
|
|
|
|
void screen_StopBackDrop(void)
|
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
bBackDrop = false; //checking [movie]
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void screen_RestartBackDrop(void)
|
|
|
|
{
|
2008-03-24 09:51:17 -07:00
|
|
|
bBackDrop = true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL screen_GetBackDrop(void)
|
|
|
|
{
|
|
|
|
return bBackDrop;
|
|
|
|
}
|
2007-11-14 14:29:19 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
//******************************************************************
|
|
|
|
//slight hack to display maps (or whatever) in background.
|
2007-02-25 04:57:04 -08:00
|
|
|
//bitmap MUST be (BACKDROP_HACK_WIDTH * BACKDROP_HACK_HEIGHT) for now.
|
2010-06-03 11:54:59 -07:00
|
|
|
void screen_Upload(const char *newBackDropBmp, BOOL preview)
|
2006-06-02 12:34:58 -07:00
|
|
|
{
|
2008-04-18 11:04:55 -07:00
|
|
|
static bool processed = false;
|
2010-06-03 11:55:25 -07:00
|
|
|
int x1 = 0, x2 = screenWidth, y1 = 0, y2 = screenHeight, i, scale = 0, w = 0, h = 0;
|
2010-06-03 11:54:59 -07:00
|
|
|
float tx = 1, ty = 1;
|
2010-06-07 08:11:08 -07:00
|
|
|
const float aspect = screenWidth / (float)screenHeight, backdropAspect = 4 / (float)3;
|
|
|
|
|
2010-06-07 08:11:55 -07:00
|
|
|
if (aspect < backdropAspect)
|
2010-06-07 08:11:08 -07:00
|
|
|
{
|
|
|
|
int offset = (screenWidth - screenHeight * backdropAspect) / 2;
|
|
|
|
x1 += offset;
|
|
|
|
x2 -= offset;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int offset = (screenHeight - screenWidth / backdropAspect) / 2;
|
|
|
|
y1 += offset;
|
|
|
|
y2 -= offset;
|
|
|
|
}
|
2008-04-18 11:04:55 -07:00
|
|
|
|
2007-02-07 07:27:17 -08:00
|
|
|
if(newBackDropBmp != NULL)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2008-04-18 11:04:55 -07:00
|
|
|
if (processed) // lets free a texture when we use a new one.
|
|
|
|
{
|
|
|
|
glDeleteTextures( 1, &backDropTexture );
|
|
|
|
}
|
|
|
|
|
2007-02-07 07:27:17 -08:00
|
|
|
glGenTextures(1, &backDropTexture);
|
2008-03-21 07:34:30 -07:00
|
|
|
pie_SetTexturePage(TEXPAGE_NONE);
|
2007-02-07 07:27:17 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, backDropTexture);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
2007-02-25 04:57:04 -08:00
|
|
|
BACKDROP_HACK_WIDTH, BACKDROP_HACK_HEIGHT,
|
2006-03-27 03:03:10 -08:00
|
|
|
0, GL_RGB, GL_UNSIGNED_BYTE, newBackDropBmp);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-02-07 07:27:17 -08:00
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
2008-04-18 11:04:55 -07:00
|
|
|
processed = true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2006-06-02 12:34:58 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_FALSE);
|
2007-02-20 15:46:34 -08:00
|
|
|
|
2007-02-20 16:10:03 -08:00
|
|
|
// Make sure the current texture page is reloaded after we are finished
|
|
|
|
// Otherwise WZ will think it is still loaded and not load it again
|
2010-10-17 13:09:56 -07:00
|
|
|
pie_SetTexturePage(TEXPAGE_EXTERN);
|
2007-02-20 15:46:34 -08:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
glBindTexture(GL_TEXTURE_2D, backDropTexture);
|
2007-02-07 07:27:17 -08:00
|
|
|
glColor3f(1, 1, 1);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2010-06-03 11:54:59 -07:00
|
|
|
if (preview)
|
|
|
|
{
|
|
|
|
int s1, s2;
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
|
|
|
|
s1 = screenWidth / preview_width;
|
|
|
|
s2 = screenHeight / preview_height;
|
|
|
|
scale = MIN(s1, s2);
|
|
|
|
|
|
|
|
w = preview_width * scale;
|
|
|
|
h = preview_height * scale;
|
|
|
|
x1 = screenWidth / 2 - w / 2;
|
|
|
|
x2 = screenWidth / 2 + w / 2;
|
|
|
|
y1 = screenHeight / 2 - h / 2;
|
|
|
|
y2 = screenHeight / 2 + h / 2;
|
|
|
|
|
|
|
|
tx = preview_width / (float)BACKDROP_HACK_WIDTH;
|
|
|
|
ty = preview_height / (float)BACKDROP_HACK_HEIGHT;
|
|
|
|
}
|
2010-06-07 08:11:32 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
}
|
2010-06-03 11:54:59 -07:00
|
|
|
|
2010-10-25 23:36:22 -07:00
|
|
|
glBegin(GL_TRIANGLE_STRIP);
|
|
|
|
glTexCoord2f(0, 0);
|
|
|
|
glVertex2f(x1, y1);
|
|
|
|
glTexCoord2f(tx, 0);
|
|
|
|
glVertex2f(x2, y1);
|
|
|
|
glTexCoord2f(0, ty);
|
|
|
|
glVertex2f(x1, y2);
|
|
|
|
glTexCoord2f(tx, ty);
|
|
|
|
glVertex2f(x2, y2);
|
|
|
|
glEnd();
|
2010-06-03 11:54:59 -07:00
|
|
|
|
|
|
|
if (preview)
|
|
|
|
{
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
int x = player_pos[i].x;
|
|
|
|
int y = player_pos[i].y;
|
|
|
|
char text[5];
|
|
|
|
|
|
|
|
if (x == 0x77777777)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
x = screenWidth / 2 - w / 2 + x * scale;
|
|
|
|
y = screenHeight / 2 - h / 2 + y * scale;
|
|
|
|
ssprintf(text, "%d", i);
|
|
|
|
iV_SetFont(font_large);
|
|
|
|
iV_SetTextColour(WZCOL_BLACK);
|
|
|
|
iV_DrawText(text, x - 1, y - 1);
|
|
|
|
iV_DrawText(text, x + 1, y - 1);
|
|
|
|
iV_DrawText(text, x - 1, y + 1);
|
|
|
|
iV_DrawText(text, x + 1, y + 1);
|
|
|
|
iV_SetTextColour(WZCOL_WHITE);
|
|
|
|
iV_DrawText(text, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void screen_enableMapPreview(char *name, int width, int height, Vector2i *playerpositions)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
mappreview = true;
|
|
|
|
preview_width = width;
|
|
|
|
preview_height = height;
|
|
|
|
sstrcpy(mapname, name);
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
|
|
{
|
|
|
|
player_pos[i].x = playerpositions[i].x;
|
|
|
|
player_pos[i].y = playerpositions[i].y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void screen_disableMapPreview(void)
|
|
|
|
{
|
|
|
|
mappreview = false;
|
|
|
|
sstrcpy(mapname, "none");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL screen_getMapPreview(void)
|
|
|
|
{
|
|
|
|
return mappreview;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Swap between windowed and full screen mode */
|
|
|
|
void screenToggleMode(void)
|
|
|
|
{
|
2010-05-15 18:36:21 -07:00
|
|
|
// TODO
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-04-17 09:53:28 -07:00
|
|
|
// Screenshot code goes below this
|
|
|
|
static const unsigned int channelsPerPixel = 3;
|
|
|
|
|
2008-08-15 13:27:18 -07:00
|
|
|
/** Writes a screenshot of the current frame to file.
|
|
|
|
*
|
|
|
|
* Performs the actual work of writing the frame currently displayed on screen
|
|
|
|
* to the filename specified by screenDumpToDisk().
|
|
|
|
*
|
|
|
|
* @NOTE This function will only dump a screenshot to file if it was requested
|
|
|
|
* by screenDumpToDisk().
|
|
|
|
*
|
|
|
|
* \sa screenDumpToDisk()
|
|
|
|
*/
|
2007-04-29 16:00:38 -07:00
|
|
|
void screenDoDumpToDiskIfRequired(void)
|
2007-04-17 09:53:28 -07:00
|
|
|
{
|
2007-04-29 16:00:38 -07:00
|
|
|
const char* fileName = screendump_filename;
|
2010-03-13 20:56:00 -08:00
|
|
|
iV_Image image = { 0, 0, 8, NULL };
|
2007-04-17 09:53:28 -07:00
|
|
|
|
2007-04-29 16:00:38 -07:00
|
|
|
if (!screendump_required) return;
|
|
|
|
debug( LOG_3D, "Saving screenshot %s\n", fileName );
|
2007-05-01 13:34:54 -07:00
|
|
|
|
2010-05-15 18:36:21 -07:00
|
|
|
if (image.width != screenWidth || image.height != screenHeight)
|
2007-04-17 09:53:28 -07:00
|
|
|
{
|
2007-04-29 16:00:38 -07:00
|
|
|
if (image.bmp != NULL)
|
2007-04-23 07:28:04 -07:00
|
|
|
{
|
2007-04-29 16:00:38 -07:00
|
|
|
free(image.bmp);
|
2007-04-23 07:28:04 -07:00
|
|
|
}
|
2007-05-01 13:34:54 -07:00
|
|
|
|
2010-05-15 18:36:21 -07:00
|
|
|
image.width = screenWidth;
|
|
|
|
image.height = screenHeight;
|
2010-12-05 08:25:43 -08:00
|
|
|
image.bmp = (unsigned char *)malloc(channelsPerPixel * image.width * image.height);
|
2007-04-29 16:00:38 -07:00
|
|
|
if (image.bmp == NULL)
|
2007-04-17 09:53:28 -07:00
|
|
|
{
|
2007-04-29 16:00:38 -07:00
|
|
|
image.width = 0; image.height = 0;
|
2008-08-15 13:27:18 -07:00
|
|
|
debug(LOG_ERROR, "Couldn't allocate memory");
|
2007-04-29 16:00:38 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
2007-04-29 16:00:38 -07:00
|
|
|
glReadPixels(0, 0, image.width, image.height, GL_RGB, GL_UNSIGNED_BYTE, image.bmp);
|
2007-04-16 12:22:01 -07:00
|
|
|
|
2007-05-01 13:34:54 -07:00
|
|
|
iV_saveImage_PNG(fileName, &image);
|
2010-07-01 12:48:05 -07:00
|
|
|
iV_saveImage_JPEG(fileName, &image);
|
2007-04-16 12:22:01 -07:00
|
|
|
|
2008-10-03 20:31:18 -07:00
|
|
|
// display message to user about screenshot
|
|
|
|
snprintf(ConsoleString,sizeof(ConsoleString),"Screenshot %s saved!",fileName);
|
|
|
|
addConsoleMessage(ConsoleString, LEFT_JUSTIFY,SYSTEM_MESSAGE);
|
2010-03-13 20:56:00 -08:00
|
|
|
if (image.bmp)
|
|
|
|
{
|
|
|
|
free(image.bmp);
|
|
|
|
}
|
2008-03-24 09:51:17 -07:00
|
|
|
screendump_required = false;
|
2007-04-16 12:22:01 -07:00
|
|
|
}
|
|
|
|
|
2008-08-15 13:27:18 -07:00
|
|
|
/** Registers the currently displayed frame for making a screen shot.
|
|
|
|
*
|
|
|
|
* The filename will be suffixed with a number, such that no files are
|
|
|
|
* overwritten.
|
|
|
|
*
|
|
|
|
* \param path The directory path to save the screenshot in.
|
|
|
|
*/
|
2008-08-03 15:56:38 -07:00
|
|
|
void screenDumpToDisk(const char* path)
|
|
|
|
{
|
2010-06-03 12:13:50 -07:00
|
|
|
unsigned int screendump_num = 0;
|
|
|
|
time_t aclock;
|
|
|
|
struct tm *t;
|
|
|
|
|
|
|
|
time(&aclock); /* Get time in seconds */
|
|
|
|
t = localtime(&aclock); /* Convert time to struct */
|
2007-04-16 12:22:01 -07:00
|
|
|
|
2010-06-03 12:13:50 -07:00
|
|
|
ssprintf(screendump_filename, "%s/wz2100-%04d%02d%02d_%02d%02d%02d-%s.png", path, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, getLevelName());
|
2007-04-16 13:00:12 -07:00
|
|
|
|
2010-06-03 12:13:50 -07:00
|
|
|
while (PHYSFS_exists(screendump_filename))
|
|
|
|
{
|
|
|
|
ssprintf(screendump_filename, "%s/wz2100-%04d%02d%02d_%02d%02d%02d-%s-%d.png", path, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, getLevelName(), ++screendump_num);
|
|
|
|
}
|
|
|
|
screendump_required = true;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2008-08-03 14:06:39 -07:00
|
|
|
|