Merge the "retex" branch into the trunk.

This commit is contained in:
Yamagi Burmeister 2012-03-13 12:36:38 +00:00
commit 5324d01e89
11 changed files with 732 additions and 177 deletions

View File

@ -1,10 +1,11 @@
Quake II 4.03 to 4.04
Quake II 4.03 to 4.10
- Change the behavior of hotkey menus to fix some
strange bugs and memory leaks in the menu system.
- Add the "gl_farsee" cvar. When set to "1" Quake II
renders maps up to 4096x4096 units instead of being
limited to 2300x2300. The default is "0". (by Richard
Allen)
- Add support for the high resolution retexturing pack.
Quake II 4.02 to 4.03
- Fix wrong function call in the Quake II file system.

View File

@ -168,8 +168,8 @@ build/refresher/%.o: %.c
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) -o $@ $<
release/ref_gl.so : CFLAGS += -fPIC
release/ref_gl.so : LDFLAGS += -shared
release/ref_gl.so : LDFLAGS += -shared -ljpeg
# ----------
# The baseq2 game
@ -376,6 +376,7 @@ OPENGL_OBJS_ = \
src/refresh/files/pcx.o \
src/refresh/files/sp2.o \
src/refresh/files/tga.o \
src/refresh/files/jpeg.o \
src/refresh/files/wal.o \
src/sdl/input.o \
src/sdl/refresh.o \

12
README
View File

@ -279,6 +279,18 @@ the most common questions are answered.
by your video card and set the desired value "gl_anisotropic". The
value must be a power of 4, in most cases 2, 4, 8 or 16.
- Yamagi Quake II has support for the high resolution retexturing pack,
created by the community. Installation is easy:
1. Download q2_textures.zip and models.zip from
http://www-personal.umich.edu/~jimw/q2/
2. Extract both files into the baseq2/ directory of your Quake II
installation, so that the new directories baseq2/textures/ and
baseq2/models/ are created.
The retexturing pack is used by default if it's installed. It can
be switched of at any time by setting "gl_retexturing" to "1" and
execute "vid_restart" after it.
3.2 Input
---------
Quake II had a rather simple input system, even back then in 1997. It

171
src/refresh/files/jpeg.c Normal file
View File

@ -0,0 +1,171 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* The JPEG image format
*
* =======================================================================
*/
#include "../header/local.h"
#include <jpeglib.h>
#include <jerror.h>
void jpeg_memory_src(j_decompress_ptr cinfo, unsigned char *inbuffer, unsigned long insize);
void
jpg_null(j_decompress_ptr cinfo)
{
}
boolean
jpg_fill_input_buffer(j_decompress_ptr cinfo)
{
ri.Con_Printf(PRINT_ALL, "Premature end of JPEG data\n");
return 1;
}
void
jpg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
cinfo->src->next_input_byte += (size_t)num_bytes;
cinfo->src->bytes_in_buffer -= (size_t)num_bytes;
}
void
jpeg_mem_src(j_decompress_ptr cinfo, unsigned char *mem, unsigned long len)
{
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr));
cinfo->src->init_source = jpg_null;
cinfo->src->fill_input_buffer = jpg_fill_input_buffer;
cinfo->src->skip_input_data = jpg_skip_input_data;
cinfo->src->resync_to_restart = jpeg_resync_to_restart;
cinfo->src->term_source = jpg_null;
cinfo->src->bytes_in_buffer = len;
cinfo->src->next_input_byte = mem;
}
void
LoadJPG(char *origname, byte **pic, int *width, int *height)
{
struct jpeg_decompress_struct cinfo;
char filename[256];
struct jpeg_error_mgr jerr;
int len;
byte *rawdata, *rgbadata, *scanline, *p, *q;
unsigned int rawsize, i;
/* Add the extension */
len = strlen(origname);
if (strcmp(origname + len - 4, ".jpg"))
{
strncpy(filename, origname, 256);
strncat(filename, ".jpg", 255);
}
else
{
strncpy(filename, origname, 256);
}
*pic = NULL;
/* Load JPEG file into memory */
rawsize = ri.FS_LoadFile(filename, (void **)&rawdata);
if (!rawdata)
{
return;
}
if ((rawsize < 10) || (rawdata[6] != 'J') || (rawdata[7] != 'F') || (rawdata[8] != 'I') || (rawdata[9] != 'F'))
{
ri.Con_Printf(PRINT_ALL, "Invalid JPEG header: %s\n", filename);
ri.FS_FreeFile(rawdata);
return;
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, (unsigned char *)rawdata, (unsigned long)rawsize);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
if ((cinfo.output_components != 3) && (cinfo.output_components != 4))
{
ri.Con_Printf(PRINT_ALL, "Invalid JPEG colour components\n");
jpeg_destroy_decompress(&cinfo);
ri.FS_FreeFile(rawdata);
return;
}
/* Allocate Memory for decompressed image */
rgbadata = malloc(cinfo.output_width * cinfo.output_height * 4);
if (!rgbadata)
{
ri.Con_Printf(PRINT_ALL, "Insufficient memory for JPEG buffer\n");
jpeg_destroy_decompress(&cinfo);
ri.FS_FreeFile(rawdata);
return;
}
/* Pass sizes to output */
*width = cinfo.output_width;
*height = cinfo.output_height;
/* Allocate Scanline buffer */
scanline = malloc(cinfo.output_width * 3);
if (!scanline)
{
ri.Con_Printf(PRINT_ALL, "Insufficient memory for JPEG scanline buffer\n");
free(rgbadata);
jpeg_destroy_decompress(&cinfo);
ri.FS_FreeFile(rawdata);
return;
}
/* Read Scanlines, and expand from RGB to RGBA */
q = rgbadata;
while (cinfo.output_scanline < cinfo.output_height)
{
p = scanline;
jpeg_read_scanlines(&cinfo, &scanline, 1);
for (i = 0; i < cinfo.output_width; i++)
{
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
q[3] = 255;
p += 3;
q += 4;
}
}
free(scanline);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
*pic = rgbadata;
}

View File

@ -22,86 +22,96 @@
* The PCX file format
*
* =======================================================================
*/
*/
#include "../header/local.h"
void
LoadPCX ( char *filename, byte **pic, byte **palette, int *width, int *height )
LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
{
byte *raw;
pcx_t *pcx;
byte *raw;
pcx_t *pcx;
int x, y;
int len;
int filelen;
int dataByte, runLength;
byte *out, *pix;
byte *out, *pix;
char filename[256];
/* Add the extension */
filelen = strlen(origname);
if (strcmp(origname + filelen - 4, ".pcx"))
{
strncpy(filename, origname, 256);
strncat(filename, ".pcx", 255);
}
else
{
strncpy(filename, origname, 256);
}
*pic = NULL;
*palette = NULL;
/* load the file */
len = ri.FS_LoadFile( filename, (void **) &raw );
len = ri.FS_LoadFile(filename, (void **)&raw);
if ( !raw )
if (!raw)
{
ri.Con_Printf( PRINT_DEVELOPER, "Bad pcx file %s\n", filename );
ri.Con_Printf(PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
return;
}
/* parse the PCX file */
pcx = (pcx_t *) raw;
pcx = (pcx_t *)raw;
pcx->xmin = LittleShort( pcx->xmin );
pcx->ymin = LittleShort( pcx->ymin );
pcx->xmax = LittleShort( pcx->xmax );
pcx->ymax = LittleShort( pcx->ymax );
pcx->hres = LittleShort( pcx->hres );
pcx->vres = LittleShort( pcx->vres );
pcx->bytes_per_line = LittleShort( pcx->bytes_per_line );
pcx->palette_type = LittleShort( pcx->palette_type );
pcx->xmin = LittleShort(pcx->xmin);
pcx->ymin = LittleShort(pcx->ymin);
pcx->xmax = LittleShort(pcx->xmax);
pcx->ymax = LittleShort(pcx->ymax);
pcx->hres = LittleShort(pcx->hres);
pcx->vres = LittleShort(pcx->vres);
pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
pcx->palette_type = LittleShort(pcx->palette_type);
raw = &pcx->data;
if ( ( pcx->manufacturer != 0x0a ) ||
( pcx->version != 5 ) ||
( pcx->encoding != 1 ) ||
( pcx->bits_per_pixel != 8 ) ||
( pcx->xmax >= 640 ) ||
( pcx->ymax >= 480 ) )
if ((pcx->manufacturer != 0x0a) || (pcx->version != 5) || (pcx->encoding != 1) || (pcx->bits_per_pixel != 8) || (pcx->xmax >= 640) || (pcx->ymax >= 480))
{
ri.Con_Printf( PRINT_ALL, "Bad pcx file %s\n", filename );
ri.Con_Printf(PRINT_ALL, "Bad pcx file %s\n", filename);
return;
}
out = malloc( ( pcx->ymax + 1 ) * ( pcx->xmax + 1 ) );
out = malloc((pcx->ymax + 1) * (pcx->xmax + 1));
*pic = out;
pix = out;
if ( palette )
if (palette)
{
*palette = malloc( 768 );
memcpy( *palette, (byte *) pcx + len - 768, 768 );
*palette = malloc(768);
memcpy(*palette, (byte *)pcx + len - 768, 768);
}
if ( width )
if (width)
{
*width = pcx->xmax + 1;
}
if ( height )
if (height)
{
*height = pcx->ymax + 1;
}
for ( y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1 )
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1)
{
for ( x = 0; x <= pcx->xmax; )
for (x = 0; x <= pcx->xmax; )
{
dataByte = *raw++;
if ( ( dataByte & 0xC0 ) == 0xC0 )
if ((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
dataByte = *raw++;
@ -111,19 +121,43 @@ LoadPCX ( char *filename, byte **pic, byte **palette, int *width, int *height )
runLength = 1;
}
while ( runLength-- > 0 )
while (runLength-- > 0)
{
pix [ x++ ] = dataByte;
pix[x++] = dataByte;
}
}
}
if ( raw - (byte *) pcx > len )
if (raw - (byte *)pcx > len)
{
ri.Con_Printf( PRINT_DEVELOPER, "PCX file %s was malformed", filename );
free( *pic );
ri.Con_Printf(PRINT_DEVELOPER, "PCX file %s was malformed", filename);
free(*pic);
*pic = NULL;
}
ri.FS_FreeFile( pcx );
}
ri.FS_FreeFile(pcx);
}
void
GetPCXInfo(char *filename, int *width, int *height)
{
pcx_t *pcx;
byte *raw;
ri.FS_LoadFile(filename, (void **)&raw);
if (!raw)
{
return;
}
pcx = (pcx_t *)raw;
*width = pcx->xmax + 1;
*height = pcx->ymax + 1;
ri.FS_FreeFile(raw);
return;
}

View File

@ -22,9 +22,9 @@
* The Targa image format
*
* =======================================================================
*/
*/
#include "../header/local.h"
#include "../header/local.h"
typedef struct _TargaHeader
{
@ -36,102 +36,138 @@ typedef struct _TargaHeader
} TargaHeader;
void
LoadTGA ( char *name, byte **pic, int *width, int *height )
LoadTGA(char *origname, byte **pic, int *width, int *height)
{
int columns, rows, numPixels;
byte *pixbuf;
int row, column;
byte *buf_p;
byte *buffer;
int length;
unsigned rows, numPixels;
byte *pixbuf;
int row, column, columns;
byte *buf_p;
byte *buffer;
TargaHeader targa_header;
byte *targa_rgba;
byte tmp [ 2 ];
byte *targa_rgba;
int length;
int pixel_size;
char name[256];
int len;
/* Add the extension */
len = strlen(origname);
if (strcmp(origname + len - 4, ".tga"))
{
strncpy(name, origname, 256);
strncat(name, ".tga", 255);
}
else
{
strncpy(name, origname, 256);
}
*pic = NULL;
/* load the file */
length = ri.FS_LoadFile( name, (void **) &buffer );
length = ri.FS_LoadFile(name, (void **)&buffer);
if ( !buffer )
if (!buffer)
{
ri.Con_Printf( PRINT_DEVELOPER, "Bad tga file %s\n", name );
return;
}
if (length < 18)
{
ri.Sys_Error(ERR_DROP, "LoadTGA: %s has an invalid file size", name);
}
buf_p = buffer;
targa_header.id_length = *buf_p++;
targa_header.colormap_type = *buf_p++;
targa_header.image_type = *buf_p++;
targa_header.id_length = buf_p[0];
targa_header.colormap_type = buf_p[1];
targa_header.image_type = buf_p[2];
tmp [ 0 ] = buf_p [ 0 ];
tmp [ 1 ] = buf_p [ 1 ];
targa_header.colormap_index = LittleShort( *( (short *) tmp ) );
buf_p += 2;
tmp [ 0 ] = buf_p [ 0 ];
tmp [ 1 ] = buf_p [ 1 ];
targa_header.colormap_length = LittleShort( *( (short *) tmp ) );
buf_p += 2;
targa_header.colormap_size = *buf_p++;
targa_header.x_origin = LittleShort( *( (short *) buf_p ) );
buf_p += 2;
targa_header.y_origin = LittleShort( *( (short *) buf_p ) );
buf_p += 2;
targa_header.width = LittleShort( *( (short *) buf_p ) );
buf_p += 2;
targa_header.height = LittleShort( *( (short *) buf_p ) );
buf_p += 2;
targa_header.pixel_size = *buf_p++;
targa_header.attributes = *buf_p++;
memcpy(&targa_header.colormap_index, &buf_p[3], 2);
memcpy(&targa_header.colormap_length, &buf_p[5], 2);
targa_header.colormap_size = buf_p[7];
memcpy(&targa_header.x_origin, &buf_p[8], 2);
memcpy(&targa_header.y_origin, &buf_p[10], 2);
memcpy(&targa_header.width, &buf_p[12], 2);
memcpy(&targa_header.height, &buf_p[14], 2);
targa_header.pixel_size = buf_p[16];
targa_header.attributes = buf_p[17];
if ( ( targa_header.image_type != 2 ) &&
( targa_header.image_type != 10 ) )
targa_header.colormap_index = LittleShort(targa_header.colormap_index);
targa_header.colormap_length = LittleShort(targa_header.colormap_length);
targa_header.x_origin = LittleShort(targa_header.x_origin);
targa_header.y_origin = LittleShort(targa_header.y_origin);
targa_header.width = LittleShort(targa_header.width);
targa_header.height = LittleShort(targa_header.height);
buf_p += 18;
if ((targa_header.image_type != 2) &&
(targa_header.image_type != 10) &&
(targa_header.image_type != 3))
{
ri.Sys_Error( ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n" );
ri.Sys_Error( ERR_DROP, "LoadTGA (%s): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported", name);
}
if ( ( targa_header.colormap_type != 0 ) ||
( ( targa_header.pixel_size != 32 ) && ( targa_header.pixel_size != 24 ) ) )
if (targa_header.colormap_type != 0)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n" );
ri.Sys_Error(ERR_DROP, "LoadTGA (%s): colormaps not supported", name);
}
if (((targa_header.pixel_size != 32) && (targa_header.pixel_size != 24)) && (targa_header.image_type != 3))
{
ri.Sys_Error( ERR_DROP, "LoadTGA (%s): Only 32 or 24 bit images supported (no colormaps)", name);
}
columns = targa_header.width;
rows = targa_header.height;
numPixels = columns * rows;
numPixels = columns * rows * 4;
if ( width )
if (width)
{
*width = columns;
}
if ( height )
if (height)
{
*height = rows;
}
targa_rgba = malloc( numPixels * 4 );
if (!columns || !rows || (numPixels > 0x7FFFFFFF) || (numPixels / columns / 4 != rows))
{
ri.Sys_Error(ERR_DROP, "LoadTGA (%s): Invalid image size", name);
}
targa_rgba = malloc(numPixels);
*pic = targa_rgba;
if ( targa_header.id_length != 0 )
if (targa_header.id_length != 0)
{
buf_p += targa_header.id_length; /* skip TARGA image comment */
}
if ( targa_header.image_type == 2 ) /* Uncompressed, RGB images */
pixel_size = targa_header.pixel_size;
if ((targa_header.image_type == 2) || (targa_header.image_type == 3))
{
for ( row = rows - 1; row >= 0; row-- )
/* Uncompressed RGB or gray scale image */
switch (pixel_size)
{
pixbuf = targa_rgba + row * columns * 4;
case 24:
for ( column = 0; column < columns; column++ )
{
unsigned char red, green, blue, alphabyte;
switch ( targa_header.pixel_size )
if (buf_p - buffer + (3 * columns * rows) > length)
{
case 24:
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
for (row = rows - 1; row >= 0; row--)
{
pixbuf = targa_rgba + row * columns * 4;
for (column = 0; column < columns; column++)
{
unsigned char red, green, blue;
blue = *buf_p++;
green = *buf_p++;
@ -140,8 +176,26 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = 255;
break;
case 32:
}
}
break;
case 32:
if (buf_p - buffer + (4 * columns * rows) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
for (row = rows - 1; row >= 0; row--)
{
pixbuf = targa_rgba + row * columns * 4;
for (column = 0; column < columns; column++)
{
unsigned char red, green, blue, alphabyte;
blue = *buf_p++;
green = *buf_p++;
red = *buf_p++;
@ -150,49 +204,93 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = alphabyte;
break;
}
}
}
break;
case 8:
if (buf_p - buffer + (1 * columns * rows) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
for (row = rows - 1; row >= 0; row--)
{
pixbuf = targa_rgba + row * columns * 4;
for (column = 0; column < columns; column++)
{
unsigned char red, green, blue;
blue = *buf_p++;
green = blue;
red = blue;
*pixbuf++ = red;
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = 255;
}
}
break;
}
}
else if ( targa_header.image_type == 10 ) /* Runlength encoded RGB images */
else if (targa_header.image_type == 10)
{
unsigned char red, green, blue, alphabyte, packetHeader, packetSize, j;
/* Runlength encoded RGB images */
byte red, green, blue, alphabyte, packetHeader;
unsigned packetSize, j;
for ( row = rows - 1; row >= 0; row-- )
red = 0;
green = 0;
blue = 0;
alphabyte = 0xff;
for (row = rows - 1; row >= 0; row--)
{
pixbuf = targa_rgba + row * columns * 4;
for ( column = 0; column < columns; )
for (column = 0; column < columns; )
{
packetHeader = *buf_p++;
packetSize = 1 + ( packetHeader & 0x7f );
packetSize = 1 + (packetHeader & 0x7f);
if ( packetHeader & 0x80 ) /* run-length packet */
if (packetHeader & 0x80)
{
switch ( targa_header.pixel_size )
/* run-length packet */
switch (pixel_size)
{
case 24:
if (buf_p - buffer + (3) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
blue = *buf_p++;
green = *buf_p++;
red = *buf_p++;
alphabyte = 255;
break;
case 32:
if (buf_p - buffer + (4) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
blue = *buf_p++;
green = *buf_p++;
red = *buf_p++;
alphabyte = *buf_p++;
break;
default:
blue = 0;
green = 0;
red = 0;
alphabyte = 0;
break;
}
for ( j = 0; j < packetSize; j++ )
for (j = 0; j < packetSize; j++)
{
*pixbuf++ = red;
*pixbuf++ = green;
@ -200,12 +298,12 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
*pixbuf++ = alphabyte;
column++;
/* run spans across rows */
if ( column == columns )
if (column == columns)
{
/* run spans across rows */
column = 0;
if ( row > 0 )
if (row > 0)
{
row--;
}
@ -218,13 +316,20 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
}
}
}
else /* non run-length packet */
else
{
for ( j = 0; j < packetSize; j++ )
/* non run-length packet */
switch (pixel_size)
{
switch ( targa_header.pixel_size )
{
case 24:
case 24:
if (buf_p - buffer + (3 * packetSize) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
for (j = 0; j < packetSize; j++)
{
blue = *buf_p++;
green = *buf_p++;
red = *buf_p++;
@ -232,8 +337,38 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = 255;
break;
case 32:
column++;
if (column == columns)
{
/* pixel packet run spans across rows */
column = 0;
if (row > 0)
{
row--;
}
else
{
goto breakOut;
}
pixbuf = targa_rgba + row * columns * 4;
}
}
break;
case 32:
if (buf_p - buffer + (4 * packetSize) > length)
{
ri.Sys_Error( ERR_DROP, "LoadTGA: (%s): Pointer passed end of file - corrupt TGA file", name);
}
for (j = 0; j < packetSize; j++)
{
blue = *buf_p++;
green = *buf_p++;
red = *buf_p++;
@ -242,26 +377,31 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = alphabyte;
break;
}
column++;
column++;
if ( column == columns ) /* pixel packet run spans across rows */
{
column = 0;
if (column == columns)
{
/* pixel packet run spans across rows */
column = 0;
if ( row > 0 )
{
row--;
}
else
{
goto breakOut;
if (row > 0)
{
row--;
}
else
{
goto breakOut;
}
pixbuf = targa_rgba + row * columns * 4;
}
}
pixbuf = targa_rgba + row * columns * 4;
}
break;
default:
break;
}
}
}
@ -270,6 +410,27 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
}
}
ri.FS_FreeFile( buffer );
}
if (targa_header.attributes & 0x20)
{
byte *temp;
temp = malloc(numPixels);
if (!temp)
{
ri.Sys_Error(ERR_FATAL, "LoadTGA: not enough memory");
}
ri.Con_Printf(PRINT_DEVELOPER, "LoadTGA: Bottom-to-top TGA file (slow): %s\n", name);
memcpy(temp, targa_rgba, numPixels);
for (row = 0; row < rows; row++)
{
memcpy(targa_rgba + (row * columns * 4), temp + (rows - row - 1) * columns * 4, columns * 4);
}
free(temp);
}
ri.FS_FreeFile(buffer);
}

View File

@ -1,28 +1,89 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* The Wal image format
*
* =======================================================================
*/
#include "../header/local.h"
image_t *
LoadWal ( char *name )
LoadWal(char *origname)
{
miptex_t *mt;
miptex_t *mt;
int width, height, ofs;
image_t *image;
image_t *image;
int len;
char name[256];
ri.FS_LoadFile( name, (void **) &mt );
/* Add the extension */
len = strlen(origname);
if ( !mt )
if (strcmp(origname + len - 4, ".wal"))
{
ri.Con_Printf( PRINT_ALL, "LoadWall: can't load %s\n", name );
return ( r_notexture );
strncpy(name, origname, 256);
strncat(name, ".wal", 255);
}
else
{
strncpy(name, origname, 256);
}
width = LittleLong( mt->width );
height = LittleLong( mt->height );
ofs = LittleLong( mt->offsets [ 0 ] );
ri.FS_LoadFile(name, (void **)&mt);
image = R_LoadPic( name, (byte *) mt + ofs, width, height, it_wall, 8 );
if (!mt)
{
ri.Con_Printf(PRINT_ALL, "LoadWall: can't load %s\n", name);
return r_notexture;
}
ri.FS_FreeFile( (void *) mt );
width = LittleLong(mt->width);
height = LittleLong(mt->height);
ofs = LittleLong(mt->offsets[0]);
return ( image );
}
image = R_LoadPic(name, (byte *)mt + ofs, width, 0, height, 0, it_wall, 8);
ri.FS_FreeFile((void *)mt);
return image;
}
void
GetWalInfo(char *name, int *width, int *height)
{
miptex_t *mt;
ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
return;
}
*width = LittleLong(mt->width);
*height = LittleLong(mt->height);
ri.FS_FreeFile((void *)mt);
return;
}

View File

@ -200,6 +200,8 @@ extern cvar_t *gl_mode;
extern cvar_t *gl_customwidth;
extern cvar_t *gl_customheight;
extern cvar_t *gl_retexturing;
extern cvar_t *gl_log;
extern cvar_t *gl_lightmap;
extern cvar_t *gl_shadows;
@ -313,7 +315,12 @@ void R_ResampleTexture ( unsigned *in, int inwidth, int inheight, unsigned *out,
struct image_s *R_RegisterSkin ( char *name );
void LoadPCX ( char *filename, byte **pic, byte **palette, int *width, int *height );
image_t *R_LoadPic ( char *name, byte *pic, int width, int height, imagetype_t type, int bits );
image_t *LoadWal ( char *name );
void LoadJPG ( char *origname, byte **pic, int *width, int *height );
void LoadTGA ( char *origname, byte **pic, int *width, int *height );
void GetWalInfo ( char *name, int *width, int *height );
void GetPCXInfo ( char *filename, int *width, int *height );
image_t *R_LoadPic ( char *name, byte *pic, int width, int realwidth, int height, int realheight, imagetype_t type, int bits );
image_t *R_FindImage ( char *name, imagetype_t type );
void R_TextureMode ( char *string );
void R_ImageList_f ( void );

View File

@ -51,8 +51,6 @@ int gl_tex_alpha_format = 4;
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR;
image_t *LoadWal ( char *name );
void LoadTGA ( char *name, byte **pic, int *width, int *height );
int Draw_GetPalette ( void );
typedef struct
@ -897,7 +895,7 @@ R_Upload8 ( byte *data, int width, int height, qboolean mipmap, qboolean is_sky
* This is also used as an entry point for the generated r_notexture
*/
image_t *
R_LoadPic ( char *name, byte *pic, int width, int height, imagetype_t type, int bits )
R_LoadPic ( char *name, byte *pic, int width, int realwidth, int height, int realheight, imagetype_t type, int bits )
{
image_t *image;
int i;
@ -996,6 +994,20 @@ R_LoadPic ( char *name, byte *pic, int width, int height, imagetype_t type, int
image->upload_width = upload_width; /* after power of 2 and scales */
image->upload_height = upload_height;
image->paletted = uploaded_paletted;
if ( realwidth && realheight )
{
if ( ( realwidth <= image->width ) && ( realheight <= image->height ) )
{
image->width = realwidth;
image->height = realheight;
}
else
{
ri.Con_Printf( PRINT_DEVELOPER, "Warning, image '%s' has hi-res replacement smaller than the original! (%d x %d) < (%d x %d)\n", name, image->width, image->height, realwidth, realheight );
}
}
image->sl = 0;
image->sh = 1;
image->tl = 0;
@ -1015,15 +1027,21 @@ R_FindImage ( char *name, imagetype_t type )
int i, len;
byte *pic, *palette;
int width, height;
int realwidth, realheight;
char *ptr;
char namewe[256];
if ( !name )
{
return ( NULL );
}
len = strlen( name );
/* Remove the extension */
memset(namewe, 0, 256);
memcpy(namewe, name, len - 4);
if ( len < 5 )
{
return ( NULL );
@ -1051,29 +1069,114 @@ R_FindImage ( char *name, imagetype_t type )
if ( !strcmp( name + len - 4, ".pcx" ) )
{
LoadPCX( name, &pic, &palette, &width, &height );
if ( !pic )
if (gl_retexturing->value)
{
return ( NULL );
}
GetPCXInfo( name, &realwidth, &realheight );
image = R_LoadPic( name, pic, width, height, type, 8 );
/* Try to load a TGA */
LoadTGA( namewe, &pic, &width, &height );
if ( !pic )
{
/* JPEG if no TGA available */
LoadJPG( namewe, &pic, &width, &height);
}
else
{
/* Upload TGA */
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
if( !pic )
{
/* PCX if no JPEG available (exists always) */
LoadPCX( name, &pic, &palette, &width, &height );
if ( !pic )
{
/* No texture found */
return ( NULL );
}
/* Upload the PCX */
image = R_LoadPic( name, pic, width, 0, height, 0, type, 8 );
}
else
{
/* Upload JPEG */
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
}
else
{
LoadPCX( name, &pic, &palette, &width, &height );
if ( !pic )
{
return ( NULL );
}
image = R_LoadPic( name, pic, width, 0, height, 0, type, 8 );
}
}
else if ( !strcmp( name + len - 4, ".wal" ) )
{
image = LoadWal( name );
if (gl_retexturing->value)
{
/* Get size of the original texture */
GetWalInfo(name, &realwidth, &realheight);
/* Try to load a TGA */
LoadTGA( namewe, &pic, &width, &height );
if( !pic )
{
/* JPEG if no TGA available */
LoadJPG( namewe, &pic, &width, &height );
}
else
{
/* Upload TGA */
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
if( !pic )
{
/* WAL of no JPEG available (exists always) */
image = LoadWal( namewe );
}
else
{
/* Upload JPEG */
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
if ( !image )
{
/* No texture found */
return ( NULL );
}
}
else
{
image = LoadWal( name );
if ( !image )
{
/* No texture found */
return ( NULL );
}
}
}
else if ( !strcmp( name + len - 4, ".tga" ) )
{
LoadTGA( name, &pic, &width, &height );
if ( !pic )
{
return ( NULL );
}
image = R_LoadPic( name, pic, width, height, type, 32 );
image = R_LoadPic( name, pic, width, realwidth, height, realwidth, type, 32 );
}
else if ( !strcmp( name + len - 4, ".jpg" ) )
{
LoadJPG( name, &pic, &width, &height );
image = R_LoadPic( name, pic, width, realwidth, height, realheight, type, 32 );
}
else
{

View File

@ -134,6 +134,8 @@ cvar_t *gl_mode;
cvar_t *gl_customwidth;
cvar_t *gl_customheight;
cvar_t *gl_retexturing;
cvar_t *gl_dynamic;
cvar_t *gl_modulate;
cvar_t *gl_nobind;
@ -1010,6 +1012,8 @@ R_Register ( void )
gl_customwidth = ri.Cvar_Get( "gl_customwidth", "1024", CVAR_ARCHIVE );
gl_customheight = ri.Cvar_Get( "gl_customheight", "768", CVAR_ARCHIVE );
gl_retexturing = ri.Cvar_Get( "gl_retexturing", "1", CVAR_ARCHIVE );
ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
ri.Cmd_AddCommand( "screenshot", R_ScreenShot );
ri.Cmd_AddCommand( "modellist", Mod_Modellist_f );

View File

@ -64,7 +64,7 @@ R_InitParticleTexture ( void )
}
}
r_particletexture = R_LoadPic( "***particle***", (byte *) data, 8, 8, it_sprite, 32 );
r_particletexture = R_LoadPic( "***particle***", (byte *) data, 8, 0, 8, 0, it_sprite, 32 );
/* also use this for bad textures, but without alpha */
for ( x = 0; x < 8; x++ )
@ -78,7 +78,7 @@ R_InitParticleTexture ( void )
}
}
r_notexture = R_LoadPic( "***r_notexture***", (byte *) data, 8, 8, it_wall, 32 );
r_notexture = R_LoadPic( "***r_notexture***", (byte *) data, 8, 0, 8, 0, it_wall, 32 );
}
void