mirror of
https://git.code.sf.net/p/quake/newtree
synced 2024-11-25 21:41:57 +00:00
chop up gl_warp into gl_sky, pcx and tga. also break out pcx stuff from client.h
This commit is contained in:
parent
5d07b61d7a
commit
06e50ba0c9
11 changed files with 798 additions and 660 deletions
|
@ -518,24 +518,6 @@ void CL_ParseEntityLump(char *entdata);
|
|||
// skin.c
|
||||
//
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
|
||||
void Skin_Find (player_info_t *sc);
|
||||
byte *Skin_Cache (skin_t *skin);
|
||||
void Skin_Skins_f (void);
|
||||
|
|
49
include/pcx.h
Normal file
49
include/pcx.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
pcx.h
|
||||
|
||||
pcx image hangling
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __pcx_h
|
||||
#define __pcx_h
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
#endif // __pcx_h
|
37
include/tga.h
Normal file
37
include/tga.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
tga.h
|
||||
|
||||
targa image hangling
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __tga_h
|
||||
#define __tga_h
|
||||
|
||||
#include "qtypes.h"
|
||||
|
||||
byte *
|
||||
LoadTGA (QFile *fin);
|
||||
|
||||
#endif // __tga_h
|
|
@ -148,7 +148,7 @@ endif
|
|||
client_SOURCES= cl_cam.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c cl_input.c \
|
||||
cl_main.c cl_misc.c cl_parse.c cl_pred.c cl_slist.c cl_tent.c \
|
||||
console.c keys.c menu.c model_alias.c model_sprite.c nonintel.c \
|
||||
r_view.c sbar.c skin.c teamplay.c wad.c vid.c $(client_ASM)
|
||||
pcx.c r_view.c sbar.c skin.c teamplay.c tga.c wad.c vid.c $(client_ASM)
|
||||
|
||||
#
|
||||
# Software-rendering clients
|
||||
|
@ -223,7 +223,7 @@ qf_client_x11_DEPENDENCIES=libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
|
|||
ogl_SOURCES= fractalnoise.c gl_draw.c gl_dyn_fires.c gl_dyn_part.c \
|
||||
gl_dyn_textures.c gl_mesh.c gl_ngraph.c gl_refrag.c \
|
||||
gl_rlight.c gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c \
|
||||
gl_trans.c gl_view.c gl_warp.c gl_model_alias.c \
|
||||
gl_sky.c gl_trans.c gl_view.c gl_warp.c gl_model_alias.c \
|
||||
gl_model_brush.c gl_model_fullbright.c gl_model_sprite.c
|
||||
|
||||
#
|
||||
|
|
|
@ -30,36 +30,19 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "bothdefs.h" // needed by: common.h, net.h, client.h
|
||||
#include "qendian.h"
|
||||
#include "bspfile.h" // needed by: glquake.h
|
||||
#include "vid.h"
|
||||
#include "sys.h"
|
||||
#include "mathlib.h" // needed by: protocol.h, render.h, client.h,
|
||||
// modelgen.h, glmodel.h
|
||||
#include "wad.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "draw.h"
|
||||
#include "cvar.h"
|
||||
#include "net.h" // needed by: client.h
|
||||
#include "protocol.h" // needed by: client.h
|
||||
#include "glquake.h"
|
||||
#include "keys.h"
|
||||
#include "menu.h"
|
||||
#include "cmd.h"
|
||||
#include "pcx.h"
|
||||
#include "qendian.h"
|
||||
#include "sbar.h"
|
||||
#include "sound.h"
|
||||
#include "screen.h"
|
||||
#include "render.h" // needed by: client.h, gl_model.h, glquake.h
|
||||
#include "client.h" // need cls in this file
|
||||
#include "model.h" // needed by: glquake.h
|
||||
#include "console.h"
|
||||
#include "glquake.h"
|
||||
#include "sys.h"
|
||||
|
||||
/*
|
||||
|
||||
|
|
352
source/gl_sky.c
Normal file
352
source/gl_sky.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
gl_sky.c
|
||||
|
||||
sky polygons
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "glquake.h"
|
||||
#include "tga.h"
|
||||
|
||||
extern double realtime;
|
||||
extern model_t *loadmodel;
|
||||
|
||||
extern int skytexturenum;
|
||||
extern qboolean lighthalf;
|
||||
|
||||
int solidskytexture;
|
||||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
|
||||
// Set to true if a valid skybox is loaded --KB
|
||||
qboolean skyloaded = false;
|
||||
|
||||
msurface_t *warpface;
|
||||
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
Quake 2 environment sky
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
#define SKY_TEX 2000
|
||||
|
||||
/*
|
||||
==================
|
||||
R_LoadSkys
|
||||
==================
|
||||
*/
|
||||
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
void R_LoadSkys (char * skyname)
|
||||
{
|
||||
int i;
|
||||
QFile *f;
|
||||
char name[64];
|
||||
|
||||
if (stricmp (skyname, "none") == 0)
|
||||
{
|
||||
skyloaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
skyloaded = true;
|
||||
for (i=0 ; i<6 ; i++) {
|
||||
byte *targa_rgba;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
|
||||
snprintf (name, sizeof(name),"env/%s%s.tga", skyname, suf[i]);
|
||||
COM_FOpenFile (name, &f);
|
||||
if (!f) {
|
||||
Con_DPrintf ("Couldn't load %s\n", name);
|
||||
skyloaded = false;
|
||||
continue;
|
||||
}
|
||||
targa_rgba = LoadTGA (f);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
|
||||
|
||||
free (targa_rgba);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
if (!skyloaded)
|
||||
Con_Printf ("Unable to load skybox %s, using normal sky\n",
|
||||
skyname);
|
||||
}
|
||||
|
||||
void
|
||||
R_SkyBoxPolyVec(vec5_t v)
|
||||
{
|
||||
// avoid interpolation seams
|
||||
// s = s * (254.0/256.0) + (1.0/256.0);
|
||||
// t = t * (254.0/256.0) + (1.0/256.0);
|
||||
glTexCoord2fv (v);
|
||||
glVertex3f (r_refdef.vieworg[0] + v[2],
|
||||
r_refdef.vieworg[1] + v[3],
|
||||
r_refdef.vieworg[2] + v[4]);
|
||||
}
|
||||
|
||||
#define ftc(x) (x * (254.0/256.0) + (1.0/256.0))
|
||||
|
||||
vec5_t skyvec[6][4] = {
|
||||
{
|
||||
// right
|
||||
{ftc(1), ftc(0), 1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
// back
|
||||
{ftc(1), ftc(0), -1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// left
|
||||
{ftc(1), ftc(0), -1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// front
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
// up
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, 1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, 1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// down
|
||||
{ftc(1), ftc(0), 1024, 1024, -1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, -1024}
|
||||
}
|
||||
};
|
||||
|
||||
#undef ftc
|
||||
|
||||
void
|
||||
R_DrawSkyBox (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, SKY_TEX + i);
|
||||
glBegin(GL_QUADS);
|
||||
for (j = 0; j < 4; j++)
|
||||
R_SkyBoxPolyVec(skyvec[i][j]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange(gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
|
||||
vec3_t domescale;
|
||||
void
|
||||
R_DrawSkyLayer (float s)
|
||||
{
|
||||
int a, b;
|
||||
float x, y, a1x, a1y, a2x, a2y;
|
||||
vec3_t v;
|
||||
|
||||
for (a = 0; a < 16; a++)
|
||||
{
|
||||
a1x = bubble_costable[a*2];
|
||||
a1y = -bubble_sintable[a*2];
|
||||
a2x = bubble_costable[(a+1)*2];
|
||||
a2y = -bubble_sintable[(a+1)*2];
|
||||
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]+domescale[2]);
|
||||
for (b = 1; b < 8; b++)
|
||||
{
|
||||
x = bubble_costable[b*2+16];
|
||||
y = -bubble_sintable[b*2+16];
|
||||
|
||||
v[0] = a1x*x * domescale[0];
|
||||
v[1] = a1y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
|
||||
v[0] = a2x*x * domescale[0];
|
||||
v[1] = a2y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
}
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]-domescale[2]);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_DrawSkyDome (void)
|
||||
{
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
|
||||
// base sky
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
glEnable (GL_BLEND);
|
||||
|
||||
// clouds
|
||||
if (gl_skymultipass->int_val) {
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
}
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSky ( void )
|
||||
{
|
||||
if (skyloaded)
|
||||
R_DrawSkyBox();
|
||||
else
|
||||
R_DrawSkyDome();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
/*
|
||||
=============
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
*/
|
||||
void R_InitSky (texture_t *mt)
|
||||
{
|
||||
int i, j, p;
|
||||
byte *src;
|
||||
unsigned int trans[128*128];
|
||||
unsigned int transpix;
|
||||
int r, g, b;
|
||||
unsigned int *rgba;
|
||||
|
||||
src = (byte *)mt + mt->offsets[0];
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
|
||||
r = g = b = 0;
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j + 128];
|
||||
rgba = &d_8to24table[p];
|
||||
trans[(i*128) + j] = *rgba;
|
||||
r += ((byte *)rgba)[0];
|
||||
g += ((byte *)rgba)[1];
|
||||
b += ((byte *)rgba)[2];
|
||||
}
|
||||
|
||||
((byte *)&transpix)[0] = r/(128*128);
|
||||
((byte *)&transpix)[1] = g/(128*128);
|
||||
((byte *)&transpix)[2] = b/(128*128);
|
||||
((byte *)&transpix)[3] = 0;
|
||||
|
||||
|
||||
if (!solidskytexture)
|
||||
solidskytexture = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture );
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j];
|
||||
if (p == 0)
|
||||
trans[(i*128) + j] = transpix;
|
||||
else
|
||||
trans[(i*128) + j] = d_8to24table[p];
|
||||
}
|
||||
|
||||
if (!alphaskytexture)
|
||||
alphaskytexture = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
597
source/gl_warp.c
597
source/gl_warp.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
gl_warp.c
|
||||
|
||||
sky and water polygons
|
||||
water polygons
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -30,33 +30,15 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "console.h"
|
||||
#include "model.h"
|
||||
#include "cvar.h"
|
||||
#include "glquake.h"
|
||||
#include "sys.h"
|
||||
|
||||
extern double realtime;
|
||||
extern model_t *loadmodel;
|
||||
|
||||
extern int skytexturenum;
|
||||
extern qboolean lighthalf;
|
||||
|
||||
int solidskytexture;
|
||||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
|
||||
// Set to true if a valid skybox is loaded --KB
|
||||
qboolean skyloaded = false;
|
||||
|
||||
msurface_t *warpface;
|
||||
|
||||
extern cvar_t *gl_subdivide_size;
|
||||
|
@ -253,578 +235,3 @@ void EmitWaterPolys (msurface_t *fa)
|
|||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
Quake 2 environment sky
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
#define SKY_TEX 2000
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PCX Loading
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
byte *pcx_rgb;
|
||||
|
||||
/*
|
||||
============
|
||||
LoadPCX
|
||||
============
|
||||
*/
|
||||
void LoadPCX (QFile *f)
|
||||
{
|
||||
pcx_t *pcx, pcxbuf;
|
||||
byte palette[768];
|
||||
byte *pix;
|
||||
int x, y;
|
||||
int dataByte, runLength;
|
||||
int count;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
Qread (f, &pcxbuf, sizeof(pcxbuf));
|
||||
|
||||
pcx = &pcxbuf;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 320
|
||||
|| pcx->ymax >= 256)
|
||||
{
|
||||
Con_Printf ("Bad pcx file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// seek to palette
|
||||
Qseek (f, -768, SEEK_END);
|
||||
Qread (f, palette, 768);
|
||||
|
||||
Qseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
|
||||
|
||||
count = (pcx->xmax+1) * (pcx->ymax+1);
|
||||
pcx_rgb = malloc( count * 4);
|
||||
|
||||
for (y=0 ; y<=pcx->ymax ; y++)
|
||||
{
|
||||
pix = pcx_rgb + 4*y*(pcx->xmax+1);
|
||||
for (x=0 ; x<=pcx->ymax ; )
|
||||
{
|
||||
dataByte = Qgetc(f);
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = Qgetc(f);
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
{
|
||||
pix[0] = palette[dataByte*3];
|
||||
pix[1] = palette[dataByte*3+1];
|
||||
pix[2] = palette[dataByte*3+2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
TARGA LOADING
|
||||
|
||||
=========================================================
|
||||
*/
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
TargaHeader targa_header;
|
||||
byte *targa_rgba;
|
||||
|
||||
int fgetLittleShort (QFile *f)
|
||||
{
|
||||
byte b1, b2;
|
||||
|
||||
b1 = Qgetc(f);
|
||||
b2 = Qgetc(f);
|
||||
|
||||
return (short)(b1 + b2*256);
|
||||
}
|
||||
|
||||
int fgetLittleLong (QFile *f)
|
||||
{
|
||||
byte b1, b2, b3, b4;
|
||||
|
||||
b1 = Qgetc(f);
|
||||
b2 = Qgetc(f);
|
||||
b3 = Qgetc(f);
|
||||
b4 = Qgetc(f);
|
||||
|
||||
return b1 + (b2<<8) + (b3<<16) + (b4<<24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadTGA
|
||||
=============
|
||||
*/
|
||||
void LoadTGA (QFile *fin)
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
unsigned char red = 0, green = 0, blue = 0, alphabyte = 0;
|
||||
|
||||
targa_header.id_length = Qgetc(fin);
|
||||
targa_header.colormap_type = Qgetc(fin);
|
||||
targa_header.image_type = Qgetc(fin);
|
||||
|
||||
targa_header.colormap_index = fgetLittleShort(fin);
|
||||
targa_header.colormap_length = fgetLittleShort(fin);
|
||||
targa_header.colormap_size = Qgetc(fin);
|
||||
targa_header.x_origin = fgetLittleShort(fin);
|
||||
targa_header.y_origin = fgetLittleShort(fin);
|
||||
targa_header.width = fgetLittleShort(fin);
|
||||
targa_header.height = fgetLittleShort(fin);
|
||||
targa_header.pixel_size = Qgetc(fin);
|
||||
targa_header.attributes = Qgetc(fin);
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10)
|
||||
Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
|
||||
|
||||
if (targa_header.colormap_type !=0
|
||||
|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
|
||||
Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
targa_rgba = malloc (numPixels*4);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
Qseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
|
||||
|
||||
if (targa_header.image_type==2) { // Uncompressed, RGB images
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char packetHeader, packetSize, j;
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
packetHeader=Qgetc(fin);
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
Qclose(fin);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_LoadSkys
|
||||
==================
|
||||
*/
|
||||
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
void R_LoadSkys (char * skyname)
|
||||
{
|
||||
int i;
|
||||
QFile *f;
|
||||
char name[64];
|
||||
|
||||
if (stricmp (skyname, "none") == 0)
|
||||
{
|
||||
skyloaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
skyloaded = true;
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
|
||||
snprintf (name, sizeof(name),"env/%s%s.tga", skyname, suf[i]);
|
||||
COM_FOpenFile (name, &f);
|
||||
if (!f)
|
||||
{
|
||||
Con_DPrintf ("Couldn't load %s\n", name);
|
||||
skyloaded = false;
|
||||
continue;
|
||||
}
|
||||
LoadTGA (f);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
|
||||
|
||||
free (targa_rgba);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
if (!skyloaded)
|
||||
Con_Printf ("Unable to load skybox %s, using normal sky\n",
|
||||
skyname);
|
||||
}
|
||||
|
||||
void
|
||||
R_SkyBoxPolyVec(vec5_t v)
|
||||
{
|
||||
// avoid interpolation seams
|
||||
// s = s * (254.0/256.0) + (1.0/256.0);
|
||||
// t = t * (254.0/256.0) + (1.0/256.0);
|
||||
glTexCoord2fv (v);
|
||||
glVertex3f (r_refdef.vieworg[0] + v[2],
|
||||
r_refdef.vieworg[1] + v[3],
|
||||
r_refdef.vieworg[2] + v[4]);
|
||||
}
|
||||
|
||||
#define ftc(x) (x * (254.0/256.0) + (1.0/256.0))
|
||||
|
||||
vec5_t skyvec[6][4] = {
|
||||
{
|
||||
// right
|
||||
{ftc(1), ftc(0), 1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
// back
|
||||
{ftc(1), ftc(0), -1024, 1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, 1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// left
|
||||
{ftc(1), ftc(0), -1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// front
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), 1024, 1024, -1024},
|
||||
{ftc(0), ftc(0), 1024, 1024, 1024}
|
||||
},
|
||||
{
|
||||
// up
|
||||
{ftc(1), ftc(0), 1024, -1024, 1024},
|
||||
{ftc(1), ftc(1), 1024, 1024, 1024},
|
||||
{ftc(0), ftc(1), -1024, 1024, 1024},
|
||||
{ftc(0), ftc(0), -1024, -1024, 1024}
|
||||
},
|
||||
{
|
||||
// down
|
||||
{ftc(1), ftc(0), 1024, 1024, -1024},
|
||||
{ftc(1), ftc(1), 1024, -1024, -1024},
|
||||
{ftc(0), ftc(1), -1024, -1024, -1024},
|
||||
{ftc(0), ftc(0), -1024, 1024, -1024}
|
||||
}
|
||||
};
|
||||
|
||||
#undef ftc
|
||||
|
||||
void
|
||||
R_DrawSkyBox (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, SKY_TEX + i);
|
||||
glBegin(GL_QUADS);
|
||||
for (j = 0; j < 4; j++)
|
||||
R_SkyBoxPolyVec(skyvec[i][j]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange(gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
|
||||
vec3_t domescale;
|
||||
void
|
||||
R_DrawSkyLayer (float s)
|
||||
{
|
||||
int a, b;
|
||||
float x, y, a1x, a1y, a2x, a2y;
|
||||
vec3_t v;
|
||||
|
||||
for (a = 0; a < 16; a++)
|
||||
{
|
||||
a1x = bubble_costable[a*2];
|
||||
a1y = -bubble_sintable[a*2];
|
||||
a2x = bubble_costable[(a+1)*2];
|
||||
a2y = -bubble_sintable[(a+1)*2];
|
||||
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]+domescale[2]);
|
||||
for (b = 1; b < 8; b++)
|
||||
{
|
||||
x = bubble_costable[b*2+16];
|
||||
y = -bubble_sintable[b*2+16];
|
||||
|
||||
v[0] = a1x*x * domescale[0];
|
||||
v[1] = a1y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
|
||||
v[0] = a2x*x * domescale[0];
|
||||
v[1] = a2y*x * domescale[1];
|
||||
v[2] = y * domescale[2];
|
||||
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
|
||||
(v[1] + s) * (1.0 / 128.0));
|
||||
glVertex3f(v[0] + r_refdef.vieworg[0],
|
||||
v[1] + r_refdef.vieworg[1],
|
||||
v[2] + r_refdef.vieworg[2]);
|
||||
}
|
||||
glTexCoord2f(0.5 + s * (1.0 / 128.0), 0.5 + s * (1.0 / 128.0));
|
||||
glVertex3f(r_refdef.vieworg[0],
|
||||
r_refdef.vieworg[1],
|
||||
r_refdef.vieworg[2]-domescale[2]);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_DrawSkyDome (void)
|
||||
{
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
|
||||
// base sky
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*8;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
glEnable (GL_BLEND);
|
||||
|
||||
// clouds
|
||||
if (gl_skymultipass->int_val) {
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
domescale[0] = 512;
|
||||
domescale[1] = 512;
|
||||
domescale[2] = 128;
|
||||
speedscale = realtime*16;
|
||||
speedscale -= (int)speedscale & ~127;
|
||||
R_DrawSkyLayer (speedscale);
|
||||
}
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSky ( void )
|
||||
{
|
||||
if (skyloaded)
|
||||
R_DrawSkyBox();
|
||||
else
|
||||
R_DrawSkyDome();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
/*
|
||||
=============
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
*/
|
||||
void R_InitSky (texture_t *mt)
|
||||
{
|
||||
int i, j, p;
|
||||
byte *src;
|
||||
unsigned int trans[128*128];
|
||||
unsigned int transpix;
|
||||
int r, g, b;
|
||||
unsigned int *rgba;
|
||||
|
||||
src = (byte *)mt + mt->offsets[0];
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
|
||||
r = g = b = 0;
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j + 128];
|
||||
rgba = &d_8to24table[p];
|
||||
trans[(i*128) + j] = *rgba;
|
||||
r += ((byte *)rgba)[0];
|
||||
g += ((byte *)rgba)[1];
|
||||
b += ((byte *)rgba)[2];
|
||||
}
|
||||
|
||||
((byte *)&transpix)[0] = r/(128*128);
|
||||
((byte *)&transpix)[1] = g/(128*128);
|
||||
((byte *)&transpix)[2] = b/(128*128);
|
||||
((byte *)&transpix)[3] = 0;
|
||||
|
||||
|
||||
if (!solidskytexture)
|
||||
solidskytexture = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture );
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
{
|
||||
p = src[i*256 + j];
|
||||
if (p == 0)
|
||||
trans[(i*128) + j] = transpix;
|
||||
else
|
||||
trans[(i*128) + j] = d_8to24table[p];
|
||||
}
|
||||
|
||||
if (!alphaskytexture)
|
||||
alphaskytexture = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
|
100
source/pcx.c
Normal file
100
source/pcx.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
pcx.c
|
||||
|
||||
pcx image handling
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "console.h"
|
||||
#include "pcx.h"
|
||||
#include "qtypes.h"
|
||||
#include "quakefs.h"
|
||||
|
||||
byte *pcx_rgb;
|
||||
|
||||
/*
|
||||
LoadPCX
|
||||
*/
|
||||
void LoadPCX (QFile *f)
|
||||
{
|
||||
pcx_t *pcx, pcxbuf;
|
||||
byte palette[768];
|
||||
byte *pix;
|
||||
int x, y;
|
||||
int dataByte, runLength;
|
||||
int count;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
Qread (f, &pcxbuf, sizeof(pcxbuf));
|
||||
|
||||
pcx = &pcxbuf;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 320
|
||||
|| pcx->ymax >= 256) {
|
||||
Con_Printf ("Bad pcx file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// seek to palette
|
||||
Qseek (f, -768, SEEK_END);
|
||||
Qread (f, palette, 768);
|
||||
|
||||
Qseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
|
||||
|
||||
count = (pcx->xmax+1) * (pcx->ymax+1);
|
||||
pcx_rgb = malloc( count * 4);
|
||||
|
||||
for (y=0 ; y<=pcx->ymax ; y++) {
|
||||
pix = pcx_rgb + 4*y*(pcx->xmax+1);
|
||||
for (x=0 ; x<=pcx->ymax ; ) {
|
||||
dataByte = Qgetc(f);
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0) {
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = Qgetc(f);
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0) {
|
||||
pix[0] = palette[dataByte*3];
|
||||
pix[1] = palette[dataByte*3+1];
|
||||
pix[2] = palette[dataByte*3+2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,25 +29,26 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "input.h"
|
||||
#include "sys.h"
|
||||
#include "screen.h"
|
||||
#include "r_local.h"
|
||||
#include "wad.h"
|
||||
#include "compat.h"
|
||||
#include "draw.h"
|
||||
#include "quakedef.h"
|
||||
#include "keys.h"
|
||||
#include "console.h"
|
||||
#include "msg.h"
|
||||
#include "sbar.h"
|
||||
#include "menu.h"
|
||||
#include "qendian.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "cvar.h"
|
||||
#include "draw.h"
|
||||
#include "keys.h"
|
||||
#include "menu.h"
|
||||
#include "msg.h"
|
||||
#include "pcx.h"
|
||||
#include "qendian.h"
|
||||
#include "quakedef.h"
|
||||
#include "r_local.h"
|
||||
#include "sbar.h"
|
||||
#include "sys.h"
|
||||
#include "vid.h"
|
||||
|
||||
/*
|
||||
|
||||
background clear
|
||||
|
|
|
@ -29,16 +29,17 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "sys.h"
|
||||
#include "cmd.h"
|
||||
#include "msg.h"
|
||||
#include "client.h"
|
||||
#include "console.h"
|
||||
#include "commdef.h"
|
||||
#include "va.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
#include "msg.h"
|
||||
#include "pcx.h"
|
||||
#include "sys.h"
|
||||
#include "va.h"
|
||||
|
||||
cvar_t *baseskin;
|
||||
cvar_t *noskins;
|
||||
|
||||
|
|
226
source/tga.c
Normal file
226
source/tga.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
tga.c
|
||||
|
||||
targa image handling
|
||||
|
||||
Copyright (C) 1996-1997 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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "quakefs.h"
|
||||
#include "sys.h"
|
||||
#include "tga.h"
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
static int
|
||||
fgetLittleShort (QFile *f)
|
||||
{
|
||||
byte b1, b2;
|
||||
|
||||
b1 = Qgetc(f);
|
||||
b2 = Qgetc(f);
|
||||
|
||||
return (short)(b1 + b2*256);
|
||||
}
|
||||
|
||||
static int
|
||||
fgetLittleLong (QFile *f)
|
||||
{
|
||||
byte b1, b2, b3, b4;
|
||||
|
||||
b1 = Qgetc(f);
|
||||
b2 = Qgetc(f);
|
||||
b3 = Qgetc(f);
|
||||
b4 = Qgetc(f);
|
||||
|
||||
return b1 + (b2<<8) + (b3<<16) + (b4<<24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadTGA
|
||||
=============
|
||||
*/
|
||||
byte *
|
||||
LoadTGA (QFile *fin)
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
unsigned char red = 0, green = 0, blue = 0, alphabyte = 0;
|
||||
|
||||
TargaHeader targa_header;
|
||||
byte *targa_rgba;
|
||||
|
||||
targa_header.id_length = Qgetc(fin);
|
||||
targa_header.colormap_type = Qgetc(fin);
|
||||
targa_header.image_type = Qgetc(fin);
|
||||
|
||||
targa_header.colormap_index = fgetLittleShort(fin);
|
||||
targa_header.colormap_length = fgetLittleShort(fin);
|
||||
targa_header.colormap_size = Qgetc(fin);
|
||||
targa_header.x_origin = fgetLittleShort(fin);
|
||||
targa_header.y_origin = fgetLittleShort(fin);
|
||||
targa_header.width = fgetLittleShort(fin);
|
||||
targa_header.height = fgetLittleShort(fin);
|
||||
targa_header.pixel_size = Qgetc(fin);
|
||||
targa_header.attributes = Qgetc(fin);
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10)
|
||||
Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
|
||||
|
||||
if (targa_header.colormap_type !=0
|
||||
|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
|
||||
Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
targa_rgba = malloc (numPixels*4);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
Qseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
|
||||
|
||||
if (targa_header.image_type==2) { // Uncompressed, RGB images
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char packetHeader, packetSize, j;
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
packetHeader=Qgetc(fin);
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
} else { // non run-length packet
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = Qgetc(fin);
|
||||
green = Qgetc(fin);
|
||||
red = Qgetc(fin);
|
||||
alphabyte = Qgetc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
Qclose(fin);
|
||||
return targa_rgba;
|
||||
}
|
Loading…
Reference in a new issue