diff --git a/include/client.h b/include/client.h index f073bd6..cf5ca97 100644 --- a/include/client.h +++ b/include/client.h @@ -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); diff --git a/include/pcx.h b/include/pcx.h new file mode 100644 index 0000000..e0e33ed --- /dev/null +++ b/include/pcx.h @@ -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 diff --git a/include/tga.h b/include/tga.h new file mode 100644 index 0000000..56bd5e1 --- /dev/null +++ b/include/tga.h @@ -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 diff --git a/source/Makefile.am b/source/Makefile.am index 314c913..eda447b 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -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 # diff --git a/source/gl_screen.c b/source/gl_screen.c index 5e985e4..4e17f40 100644 --- a/source/gl_screen.c +++ b/source/gl_screen.c @@ -30,36 +30,19 @@ # include "config.h" #endif -#include #include -#include -#include #include -#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" /* diff --git a/source/gl_sky.c b/source/gl_sky.c new file mode 100644 index 0000000..9a1ad31 --- /dev/null +++ b/source/gl_sky.c @@ -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 + +#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); +} diff --git a/source/gl_warp.c b/source/gl_warp.c index 790c661..4b0ef86 100644 --- a/source/gl_warp.c +++ b/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 -#include -#include -#include -#ifdef HAVE_STRINGS_H -#include -#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=0; row--) { - pixbuf = targa_rgba + row*columns*4; - for(column=0; column0) - row--; - else - goto breakOut; - pixbuf = targa_rgba + row*columns*4; - } - } - } - else { // non run-length packet - for(j=0;j0) - 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); -} diff --git a/source/pcx.c b/source/pcx.c new file mode 100644 index 0000000..e63c7f6 --- /dev/null +++ b/source/pcx.c @@ -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++; + } + } + } +} diff --git a/source/screen.c b/source/screen.c index fd7bbe9..fe2fdad 100644 --- a/source/screen.c +++ b/source/screen.c @@ -29,25 +29,26 @@ #ifdef HAVE_CONFIG_H # include #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 #include +#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 diff --git a/source/skin.c b/source/skin.c index c73654d..8a5ea50 100644 --- a/source/skin.c +++ b/source/skin.c @@ -29,16 +29,17 @@ #ifdef HAVE_CONFIG_H # include #endif -#include "sys.h" -#include "cmd.h" -#include "msg.h" -#include "client.h" -#include "console.h" -#include "commdef.h" -#include "va.h" #include +#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; diff --git a/source/tga.c b/source/tga.c new file mode 100644 index 0000000..6eb957e --- /dev/null +++ b/source/tga.c @@ -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=0; row--) { + pixbuf = targa_rgba + row*columns*4; + for(column=0; column0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } else { // non run-length packet + for(j=0;j0) + row--; + else + goto breakOut; + pixbuf = targa_rgba + row*columns*4; + } + } + } + } + breakOut:; + } + } + + Qclose(fin); + return targa_rgba; +}