mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
Alliteration Annoys Always
This commit is contained in:
parent
bcfd870550
commit
28c809d27e
19 changed files with 2685 additions and 1730 deletions
|
@ -73,7 +73,8 @@ client_POST_LIBS= $(top_builddir)/libs/video/targets/libQFjs.la
|
|||
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
|
||||
cl_tent.c console.c keys.c sbar.c r_part.c r_view.c \
|
||||
nonintel.c gib.c gib_instructions.c gib_vars.c \
|
||||
gib_interpret.c gib_modules.c gib_parse.c gib_stack.c
|
||||
gib_interpret.c gib_modules.c gib_parse.c gib_stack.c \
|
||||
pcx.c tga.c
|
||||
|
||||
server_SOURCES= host.c host_cmd.c pr_cmds.c sv_cvar.c sv_main.c \
|
||||
sv_move.c sv_phys.c sv_progs.c sv_user.c
|
||||
|
@ -122,7 +123,7 @@ nq_x11_DEPENDENCIES=$(client_LIB_DEPS)
|
|||
ogl_SOURCES= noisetextures.c gl_textures.c gl_draw.c gl_dyn_fires.c \
|
||||
gl_dyn_part.c gl_dyn_textures.c gl_mesh.c \
|
||||
gl_refrag.c gl_rlight.c gl_rmain.c gl_rmisc.c gl_rsurf.c \
|
||||
gl_screen.c gl_view.c gl_warp.c
|
||||
gl_screen.c gl_sky.c gl_view.c gl_warp.c
|
||||
|
||||
# ... 3Dfx Voodoo 1 and 2 SVGAlib-based console GL
|
||||
nq_3dfx_SOURCES= $(combined_SOURCES) $(ogl_SOURCES)
|
||||
|
|
|
@ -176,12 +176,10 @@ CL_ClearState (void)
|
|||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Disconnect
|
||||
CL_Disconnect
|
||||
|
||||
Sends a disconnect message to the server
|
||||
This is also called on Host_Error, so it shouldn't cause any errors
|
||||
=====================
|
||||
Sends a disconnect message to the server
|
||||
This is also called on Host_Error, so it shouldn't cause any errors
|
||||
*/
|
||||
void
|
||||
CL_Disconnect (void)
|
||||
|
@ -215,6 +213,7 @@ CL_Disconnect (void)
|
|||
cls.signon = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CL_Disconnect_f (void)
|
||||
{
|
||||
|
@ -225,11 +224,9 @@ CL_Disconnect_f (void)
|
|||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_EstablishConnection
|
||||
CL_EstablishConnection
|
||||
|
||||
Host should be either "local" or a net address to be passed on
|
||||
=====================
|
||||
Host should be either "local" or a net address to be passed on
|
||||
*/
|
||||
void
|
||||
CL_EstablishConnection (char *host)
|
||||
|
@ -255,11 +252,9 @@ CL_EstablishConnection (char *host)
|
|||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_SignonReply
|
||||
CL_SignonReply
|
||||
|
||||
An svc_signonnum has been received, perform a client side setup
|
||||
=====================
|
||||
An svc_signonnum has been received, perform a client side setup
|
||||
*/
|
||||
void
|
||||
CL_SignonReply (void)
|
||||
|
@ -295,18 +290,16 @@ CL_SignonReply (void)
|
|||
break;
|
||||
|
||||
case 4:
|
||||
SCR_EndLoadingPlaque (); // allow normal screen updates
|
||||
// SCR_EndLoadingPlaque (); // allow normal screen updates
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_NextDemo
|
||||
CL_NextDemo
|
||||
|
||||
Called to play the next demo in the demo loop
|
||||
=====================
|
||||
Called to play the next demo in the demo loop
|
||||
*/
|
||||
void
|
||||
CL_NextDemo (void)
|
||||
|
@ -316,8 +309,6 @@ CL_NextDemo (void)
|
|||
if (cls.demonum == -1)
|
||||
return; // don't play demos
|
||||
|
||||
SCR_BeginLoadingPlaque ();
|
||||
|
||||
if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) {
|
||||
cls.demonum = 0;
|
||||
if (!cls.demos[cls.demonum][0]) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
d_sky.c
|
||||
|
||||
@description@
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -39,9 +39,7 @@
|
|||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_Sky_uv_To_st
|
||||
=================
|
||||
D_Sky_uv_To_st
|
||||
*/
|
||||
void
|
||||
D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
||||
|
@ -64,16 +62,14 @@ D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
|||
VectorNormalize (end);
|
||||
|
||||
temp = skytime * skyspeed; // TODO: add D_SetupFrame & set this
|
||||
// there
|
||||
// there
|
||||
*s = (int) ((temp + 6 * (SKYSIZE / 2 - 1) * end[0]) * 0x10000);
|
||||
*t = (int) ((temp + 6 * (SKYSIZE / 2 - 1) * end[1]) * 0x10000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
D_DrawSkyScans8
|
||||
=================
|
||||
D_DrawSkyScans8
|
||||
*/
|
||||
void
|
||||
D_DrawSkyScans8 (espan_t *pspan)
|
||||
|
|
481
nq/source/draw.c
481
nq/source/draw.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
draw.c
|
||||
|
||||
@description@
|
||||
this is the only file outside the refresh that touches the vid buffer
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -29,14 +29,20 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/console.h"
|
||||
#include "QF/draw.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sound.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/zone.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "d_iface.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -53,6 +59,8 @@ byte *draw_chars; // 8*8 graphic characters
|
|||
qpic_t *draw_disc;
|
||||
qpic_t *draw_backtile;
|
||||
|
||||
cvar_t *cl_verstring;
|
||||
|
||||
//=============================================================================
|
||||
/* Support Routines */
|
||||
|
||||
|
@ -73,6 +81,17 @@ Draw_PicFromWad (char *name)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_ClearCache
|
||||
|
||||
This is a no-op in software targets
|
||||
*/
|
||||
void
|
||||
Draw_ClearCache (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
qpic_t *
|
||||
Draw_CachePic (char *path, qboolean alpha)
|
||||
{
|
||||
|
@ -112,12 +131,59 @@ Draw_CachePic (char *path, qboolean alpha)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_TextBox (int x, int y, int width, int lines)
|
||||
{
|
||||
qpic_t *p;
|
||||
int cx, cy;
|
||||
int n;
|
||||
|
||||
// draw left side
|
||||
cx = x;
|
||||
cy = y;
|
||||
p = Draw_CachePic ("gfx/box_tl.lmp", true);
|
||||
Draw_Pic (cx, cy, p);
|
||||
p = Draw_CachePic ("gfx/box_ml.lmp", true);
|
||||
for (n = 0; n < lines; n++) {
|
||||
cy += 8;
|
||||
Draw_Pic (cx, cy, p);
|
||||
}
|
||||
p = Draw_CachePic ("gfx/box_bl.lmp", true);
|
||||
Draw_Pic (cx, cy + 8, p);
|
||||
|
||||
// draw middle
|
||||
cx += 8;
|
||||
while (width > 0) {
|
||||
cy = y;
|
||||
p = Draw_CachePic ("gfx/box_tm.lmp", true);
|
||||
Draw_Pic (cx, cy, p);
|
||||
p = Draw_CachePic ("gfx/box_mm.lmp", true);
|
||||
for (n = 0; n < lines; n++) {
|
||||
cy += 8;
|
||||
if (n == 1)
|
||||
p = Draw_CachePic ("gfx/box_mm2.lmp", true);
|
||||
Draw_Pic (cx, cy, p);
|
||||
}
|
||||
p = Draw_CachePic ("gfx/box_bm.lmp", true);
|
||||
Draw_Pic (cx, cy + 8, p);
|
||||
width -= 2;
|
||||
cx += 16;
|
||||
}
|
||||
|
||||
// draw right side
|
||||
cy = y;
|
||||
p = Draw_CachePic ("gfx/box_tr.lmp", true);
|
||||
Draw_Pic (cx, cy, p);
|
||||
p = Draw_CachePic ("gfx/box_mr.lmp", true);
|
||||
for (n = 0; n < lines; n++) {
|
||||
cy += 8;
|
||||
Draw_Pic (cx, cy, p);
|
||||
}
|
||||
p = Draw_CachePic ("gfx/box_br.lmp", true);
|
||||
Draw_Pic (cx, cy + 8, p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
Draw_Init
|
||||
===============
|
||||
*/
|
||||
void
|
||||
Draw_Init (void)
|
||||
{
|
||||
|
@ -129,21 +195,25 @@ Draw_Init (void)
|
|||
r_rectdesc.height = draw_backtile->height;
|
||||
r_rectdesc.ptexbytes = draw_backtile->data;
|
||||
r_rectdesc.rowbytes = draw_backtile->width;
|
||||
|
||||
cl_verstring =
|
||||
Cvar_Get ("cl_verstring", PROGRAM " " VERSION, CVAR_NONE, NULL,
|
||||
"Client version string");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Init_Cvars (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_Character8
|
||||
|
||||
Draws one 8*8 graphics character with 0 being transparent.
|
||||
It can be clipped to the top of the screen to allow the console to be
|
||||
smoothly scrolled off.
|
||||
================
|
||||
/*
|
||||
Draw_Character8
|
||||
|
||||
Draws one 8*8 graphics character with 0 being transparent.
|
||||
It can be clipped to the top of the screen to allow the console to be
|
||||
smoothly scrolled off.
|
||||
*/
|
||||
void
|
||||
Draw_Character8 (int x, int y, int num)
|
||||
|
@ -159,12 +229,10 @@ Draw_Character8 (int x, int y, int num)
|
|||
if (y <= -8)
|
||||
return; // totally off screen
|
||||
|
||||
#ifdef PARANOID
|
||||
if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
|
||||
Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y);
|
||||
return;
|
||||
if (num < 0 || num > 255)
|
||||
Sys_Error ("Con_DrawCharacter: char %i", num);
|
||||
#endif
|
||||
return;
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
|
@ -230,11 +298,7 @@ Draw_Character8 (int x, int y, int num)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_String8
|
||||
================
|
||||
*/
|
||||
|
||||
void
|
||||
Draw_String8 (int x, int y, char *str)
|
||||
{
|
||||
|
@ -245,155 +309,73 @@ Draw_String8 (int x, int y, char *str)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_DebugChar
|
||||
|
||||
Draws a single character directly to the upper right corner of the screen.
|
||||
This is for debugging lockups by drawing different chars in different parts
|
||||
of the code.
|
||||
================
|
||||
*/
|
||||
void
|
||||
Draw_DebugChar (char num)
|
||||
Draw_AltString8 (int x, int y, char *str)
|
||||
{
|
||||
while (*str) {
|
||||
Draw_Character8 (x, y, (*str) | 0x80);
|
||||
str++;
|
||||
x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Pixel (int x, int y, byte color)
|
||||
{
|
||||
byte *dest;
|
||||
byte *source;
|
||||
int drawline;
|
||||
extern byte *draw_chars;
|
||||
int row, col;
|
||||
unsigned short *pusdest;
|
||||
|
||||
if (!vid.direct)
|
||||
return; // don't have direct FB access, so no
|
||||
//
|
||||
//
|
||||
// debugchars...
|
||||
|
||||
drawline = 8;
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
source = draw_chars + (row << 10) + (col << 3);
|
||||
|
||||
dest = vid.direct + 312;
|
||||
|
||||
while (drawline--) {
|
||||
dest[0] = source[0];
|
||||
dest[1] = source[1];
|
||||
dest[2] = source[2];
|
||||
dest[3] = source[3];
|
||||
dest[4] = source[4];
|
||||
dest[5] = source[5];
|
||||
dest[6] = source[6];
|
||||
dest[7] = source[7];
|
||||
source += 128;
|
||||
dest += 320;
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.conbuffer + y * vid.conrowbytes + x;
|
||||
*dest = color;
|
||||
} else {
|
||||
// FIXME: pre-expand to native format?
|
||||
pusdest = (unsigned short *)
|
||||
((byte *) vid.conbuffer + y * vid.conrowbytes + (x << 1));
|
||||
*pusdest = d_8to16table[color];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_Pic
|
||||
=============
|
||||
*/
|
||||
|
||||
void
|
||||
Draw_Crosshair (void)
|
||||
{
|
||||
int x, y;
|
||||
extern cvar_t *crosshair, *cl_crossx, *cl_crossy, *crosshaircolor;
|
||||
extern vrect_t scr_vrect;
|
||||
byte c = crosshaircolor->int_val;
|
||||
|
||||
if (crosshair->int_val == 2) {
|
||||
x = scr_vrect.x + scr_vrect.width / 2 + cl_crossx->int_val;
|
||||
y = scr_vrect.y + scr_vrect.height / 2 + cl_crossy->int_val;
|
||||
Draw_Pixel (x - 1, y, c);
|
||||
Draw_Pixel (x - 3, y, c);
|
||||
Draw_Pixel (x + 1, y, c);
|
||||
Draw_Pixel (x + 3, y, c);
|
||||
Draw_Pixel (x, y - 1, c);
|
||||
Draw_Pixel (x, y - 3, c);
|
||||
Draw_Pixel (x, y + 1, c);
|
||||
Draw_Pixel (x, y + 3, c);
|
||||
} else if (crosshair->int_val)
|
||||
Draw_Character8 (scr_vrect.x + scr_vrect.width / 2 - 4 +
|
||||
cl_crossx->int_val,
|
||||
scr_vrect.y + scr_vrect.height / 2 - 4 +
|
||||
cl_crossy->int_val, '+');
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Pic (int x, int y, qpic_t *pic)
|
||||
{
|
||||
byte *dest, *source;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
if ((x < 0) ||
|
||||
(x + pic->width > vid.width) ||
|
||||
(y < 0) || (y + pic->height > vid.height)) {
|
||||
Sys_Error ("Draw_Pic: bad coordinates");
|
||||
}
|
||||
|
||||
source = pic->data;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
memcpy (dest, source, pic->width);
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
} else {
|
||||
// FIXME: pretranslate at load time?
|
||||
pusdest = (unsigned short *) vid.buffer + y * (vid.rowbytes >> 1) + x;
|
||||
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
for (u = 0; u < pic->width; u++) {
|
||||
pusdest[u] = d_8to16table[source[u]];
|
||||
}
|
||||
|
||||
pusdest += vid.rowbytes >> 1;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_SubPic
|
||||
=============
|
||||
*/
|
||||
void
|
||||
Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
|
||||
int height)
|
||||
{
|
||||
byte *dest, *source;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
if ((x < 0) ||
|
||||
(x + width > vid.width) || (y < 0) || (y + height > vid.height)) {
|
||||
Sys_Error ("Draw_SubPic: bad coordinates");
|
||||
}
|
||||
|
||||
source = pic->data + srcy * pic->width + srcx;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
for (v = 0; v < height; v++) {
|
||||
memcpy (dest, source, width);
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
} else {
|
||||
// FIXME: pretranslate at load time?
|
||||
pusdest = (unsigned short *) vid.buffer + y * (vid.rowbytes >> 1) + x;
|
||||
|
||||
for (v = 0; v < height; v++) {
|
||||
for (u = srcx; u < (srcx + width); u++) {
|
||||
pusdest[u] = d_8to16table[source[u]];
|
||||
}
|
||||
|
||||
pusdest += vid.rowbytes >> 1;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_TransPic
|
||||
=============
|
||||
*/
|
||||
void
|
||||
Draw_TransPic (int x, int y, qpic_t *pic)
|
||||
{
|
||||
byte *dest, *source, tbyte;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
if (x < 0 || (unsigned) (x + pic->width) > vid.width || y < 0 ||
|
||||
(unsigned) (y + pic->height) > vid.height) {
|
||||
Sys_Error ("Draw_TransPic: bad coordinates");
|
||||
if (x < 0 || (unsigned int) (x + pic->width) > vid.width || y < 0 ||
|
||||
(unsigned int) (y + pic->height) > vid.height) {
|
||||
Sys_Error ("Draw_Pic: bad coordinates");
|
||||
}
|
||||
|
||||
source = pic->data;
|
||||
|
@ -454,11 +436,45 @@ Draw_TransPic (int x, int y, qpic_t *pic)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_TransPicTranslate
|
||||
=============
|
||||
*/
|
||||
void
|
||||
Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
|
||||
int height)
|
||||
{
|
||||
byte *dest, *source;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
if ((x < 0) ||
|
||||
(x + width > vid.width) || (y < 0) || (y + height > vid.height)) {
|
||||
Sys_Error ("Draw_Pic: bad coordinates");
|
||||
}
|
||||
|
||||
source = pic->data + srcy * pic->width + srcx;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
for (v = 0; v < height; v++) {
|
||||
memcpy (dest, source, width);
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
} else {
|
||||
// FIXME: pretranslate at load time?
|
||||
pusdest = (unsigned short *) vid.buffer + y * (vid.rowbytes >> 1) + x;
|
||||
|
||||
for (v = 0; v < height; v++) {
|
||||
for (u = srcx; u < (srcx + width); u++) {
|
||||
pusdest[u] = d_8to16table[source[u]];
|
||||
}
|
||||
|
||||
pusdest += vid.rowbytes >> 1;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte * translation)
|
||||
{
|
||||
|
@ -466,8 +482,8 @@ Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte * translation)
|
|||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
if (x < 0 || (unsigned) (x + pic->width) > vid.width || y < 0 ||
|
||||
(unsigned) (y + pic->height) > vid.height) {
|
||||
if (x < 0 || (unsigned int) (x + pic->width) > vid.width || y < 0 ||
|
||||
(unsigned int) (y + pic->height) > vid.height) {
|
||||
Sys_Error ("Draw_TransPic: bad coordinates");
|
||||
}
|
||||
|
||||
|
@ -529,33 +545,6 @@ Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte * translation)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_CharToConback (int num, byte * dest)
|
||||
{
|
||||
int row, col;
|
||||
byte *source;
|
||||
int drawline;
|
||||
int x;
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
source = draw_chars + (row << 10) + (col << 3);
|
||||
|
||||
drawline = 8;
|
||||
|
||||
while (drawline--) {
|
||||
for (x = 0; x < 8; x++)
|
||||
if (source[x])
|
||||
dest[x] = 0x60 + source[x];
|
||||
source += 128;
|
||||
dest += 320;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Draw_ConsoleBackground
|
||||
*/
|
||||
void
|
||||
Draw_ConsoleBackground (int lines)
|
||||
{
|
||||
|
@ -565,9 +554,9 @@ Draw_ConsoleBackground (int lines)
|
|||
int f, fstep;
|
||||
qpic_t *conback;
|
||||
|
||||
conback = Draw_CachePic ("gfx/conback.lmp", true);
|
||||
conback = Draw_CachePic ("gfx/conback.lmp", false);
|
||||
|
||||
// draw the pic
|
||||
// draw the pic
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.conbuffer;
|
||||
|
||||
|
@ -613,14 +602,12 @@ Draw_ConsoleBackground (int lines)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string)
|
||||
* 8 - 11, lines - 14, cl_verstring->string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_DrawRect8
|
||||
==============
|
||||
*/
|
||||
void
|
||||
R_DrawRect8 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
||||
{
|
||||
|
@ -658,11 +645,6 @@ R_DrawRect8 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
R_DrawRect16
|
||||
==============
|
||||
*/
|
||||
void
|
||||
R_DrawRect16 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
||||
{
|
||||
|
@ -709,12 +691,10 @@ R_DrawRect16 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
|||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_TileClear
|
||||
Draw_TileClear
|
||||
|
||||
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
||||
refresh window.
|
||||
=============
|
||||
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
||||
refresh window.
|
||||
*/
|
||||
void
|
||||
Draw_TileClear (int x, int y, int w, int h)
|
||||
|
@ -768,32 +748,35 @@ Draw_TileClear (int x, int y, int w, int h)
|
|||
vr.x += vr.width;
|
||||
width -= vr.width;
|
||||
tileoffsetx = 0; // only the left tile can be
|
||||
// left-clipped
|
||||
// left-clipped
|
||||
}
|
||||
|
||||
vr.y += vr.height;
|
||||
height -= vr.height;
|
||||
tileoffsety = 0; // only the top tile can be
|
||||
// top-clipped
|
||||
// top-clipped
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Draw_Fill
|
||||
Draw_Fill
|
||||
|
||||
Fills a box of pixels with a single color
|
||||
=============
|
||||
Fills a box of pixels with a single color
|
||||
*/
|
||||
void
|
||||
Draw_Fill (int x, int y, int w, int h, int c)
|
||||
{
|
||||
byte *dest;
|
||||
unsigned short *pusdest;
|
||||
unsigned uc;
|
||||
unsigned int uc;
|
||||
int u, v;
|
||||
|
||||
if (x < 0 || x + w > vid.width || y < 0 || y + h > vid.height) {
|
||||
Con_Printf ("Bad Draw_Fill(%d, %d, %d, %d, %c)\n", x, y, w, h, c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
for (v = 0; v < h; v++, dest += vid.rowbytes)
|
||||
|
@ -808,14 +791,11 @@ Draw_Fill (int x, int y, int w, int h, int c)
|
|||
pusdest[u] = uc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_FadeScreen
|
||||
|
||||
================
|
||||
*/
|
||||
void
|
||||
Draw_FadeScreen (void)
|
||||
{
|
||||
|
@ -843,15 +823,15 @@ Draw_FadeScreen (void)
|
|||
VID_LockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_BeginDisc
|
||||
|
||||
Draws the little blue disc in the corner of the screen.
|
||||
Call before beginning any disc IO.
|
||||
================
|
||||
/*
|
||||
Draw_BeginDisc
|
||||
|
||||
Draws the little blue disc in the corner of the screen.
|
||||
Call before beginning any disc IO.
|
||||
*/
|
||||
void
|
||||
Draw_BeginDisc (void)
|
||||
|
@ -862,12 +842,10 @@ Draw_BeginDisc (void)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_EndDisc
|
||||
Draw_EndDisc
|
||||
|
||||
Erases the disc icon.
|
||||
Call after completing any disc IO
|
||||
================
|
||||
Erases the disc icon.
|
||||
Call after completing any disc IO
|
||||
*/
|
||||
void
|
||||
Draw_EndDisc (void)
|
||||
|
@ -875,42 +853,3 @@ Draw_EndDisc (void)
|
|||
|
||||
D_EndDirectRect (vid.width - 24, 0, 24, 24);
|
||||
}
|
||||
|
||||
void
|
||||
Draw_Crosshair (void)
|
||||
{
|
||||
int x, y;
|
||||
extern cvar_t *crosshair, *cl_crossx, *cl_crossy, *crosshaircolor;
|
||||
extern vrect_t scr_vrect;
|
||||
byte c = (byte) crosshaircolor->value;
|
||||
|
||||
|
||||
if (crosshair->value == 2) {
|
||||
byte *dest;
|
||||
|
||||
x = scr_vrect.x + scr_vrect.width / 2 + cl_crossx->value;
|
||||
y = scr_vrect.y + scr_vrect.height / 2 + cl_crossy->value;
|
||||
|
||||
dest = vid.conbuffer + y * vid.conrowbytes + x;
|
||||
|
||||
dest[-3] = dest[-1] = dest[1] = dest[3] = c;
|
||||
dest[-3 * vid.conrowbytes] = dest[-1 * vid.conrowbytes] =
|
||||
dest[1 * vid.conrowbytes] = dest[3 * vid.conrowbytes] = c;
|
||||
// FIXME: Find a better way to do this...
|
||||
#if 0
|
||||
Draw_Pixel (x - 1, y, c);
|
||||
Draw_Pixel (x - 3, y, c);
|
||||
Draw_Pixel (x + 1, y, c);
|
||||
Draw_Pixel (x + 3, y, c);
|
||||
Draw_Pixel (x, y - 1, c);
|
||||
Draw_Pixel (x, y - 3, c);
|
||||
Draw_Pixel (x, y + 1, c);
|
||||
Draw_Pixel (x, y + 3, c);
|
||||
#endif
|
||||
} else if (crosshair->value) {
|
||||
Draw_Character8 (scr_vrect.x + scr_vrect.width / 2 - 4 +
|
||||
cl_crossx->value,
|
||||
scr_vrect.y + scr_vrect.height / 2 - 4 +
|
||||
cl_crossy->value, '+');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,6 +267,7 @@ gl_lightmode_callback (cvar_t *cvar)
|
|||
R_ForceLightUpdate ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Init (void)
|
||||
{
|
||||
|
@ -315,6 +316,7 @@ Draw_Init (void)
|
|||
glrsurf_init ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Init_Cvars (void)
|
||||
{
|
||||
|
@ -506,8 +508,6 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
|
|||
}
|
||||
|
||||
|
||||
extern int gl_filter_min, gl_filter_max;
|
||||
|
||||
/*
|
||||
Draw_TransPicTranslate
|
||||
|
||||
|
@ -603,7 +603,7 @@ Draw_ConsoleBackground (int lines)
|
|||
else
|
||||
ofs = (vid.conheight - lines) / (float) vid.conheight;
|
||||
|
||||
y = vid.height * 0.5; // 0.5 was scr_consize->value
|
||||
y = vid.height * scr_consize->value;
|
||||
if (cls.state != ca_active || lines > y) {
|
||||
alpha = 1.0;
|
||||
} else {
|
||||
|
@ -642,7 +642,7 @@ Draw_ConsoleBackground (int lines)
|
|||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix ();
|
||||
}
|
||||
// draw version string if not downloading
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string) * 8 - 11,
|
||||
lines - 14, cl_verstring->string);
|
||||
glColor3ubv (lighthalf_v);
|
||||
|
@ -705,11 +705,10 @@ Draw_Fill (int x, int y, int w, int h, int c)
|
|||
glEnable (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
Draw_FadeScreen
|
||||
*/
|
||||
|
||||
void
|
||||
Draw_FadeScreen (void)
|
||||
{
|
||||
|
@ -729,8 +728,10 @@ Draw_FadeScreen (void)
|
|||
Sbar_Changed ();
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/*
|
||||
Draw_BeginDisc
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@
|
|||
#include "net.h"
|
||||
#include "protocol.h"
|
||||
#include "sbar.h"
|
||||
#include "render.h"
|
||||
#include "r_dynamic.h"
|
||||
#include "r_local.h"
|
||||
#include "render.h"
|
||||
|
||||
extern entity_t r_worldentity;
|
||||
extern void GDT_Init ();
|
||||
|
|
File diff suppressed because it is too large
Load diff
343
nq/source/gl_sky.c
Normal file
343
nq/source/gl_sky.c
Normal file
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
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
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/compat.h"
|
||||
#include "QF/console.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/tga.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "render.h"
|
||||
#include "view.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;
|
||||
|
||||
/*
|
||||
R_LoadSkys
|
||||
*/
|
||||
char *suf[6] = { "rt", "bk", "lf", "ft", "up", "dn" };
|
||||
void
|
||||
R_LoadSkys (const char *skyname)
|
||||
{
|
||||
int i;
|
||||
QFile *f;
|
||||
char name[64];
|
||||
|
||||
if (strcasecmp (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 +y
|
||||
{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 -x
|
||||
{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 -y
|
||||
{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 +x
|
||||
{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 +z
|
||||
{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 -z
|
||||
{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] * domescale[0];
|
||||
a1y = -bubble_sintable[a * 2] * domescale[1];
|
||||
a2x = bubble_costable[(a + 1) * 2] * domescale[0];
|
||||
a2y = -bubble_sintable[(a + 1) * 2] * domescale[1];
|
||||
|
||||
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;
|
||||
v[1] = a1y * x;
|
||||
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;
|
||||
v[1] = a2y * x;
|
||||
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)
|
||||
{
|
||||
float l = 1 / (256 * brightness->value);
|
||||
|
||||
glColor3f (lighthalf_v[0] * l, lighthalf_v[1] * l, lighthalf_v[2] * l);
|
||||
|
||||
if (skyloaded)
|
||||
R_DrawSkyBox ();
|
||||
else
|
||||
R_DrawSkyDome ();
|
||||
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
//===============================================================
|
||||
|
||||
/*
|
||||
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);
|
||||
}
|
776
nq/source/gl_sky_clip.c
Normal file
776
nq/source/gl_sky_clip.c
Normal file
|
@ -0,0 +1,776 @@
|
|||
/*
|
||||
gl_sky_clip.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
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "QF/console.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "glquake.h"
|
||||
#include "view.h"
|
||||
|
||||
extern qboolean skyloaded;
|
||||
extern vec5_t skyvec[6][4];
|
||||
|
||||
#define BOX_WIDTH 2056
|
||||
|
||||
/* cube face to sky texture offset conversion */
|
||||
static const int skytex_offs[] = { 3, 0, 4, 1, 2, 5 };
|
||||
|
||||
/* clockwise loop through the cube faces adjoining the current face */
|
||||
static const int face_loop[6][5] = {
|
||||
{1, 2, 4, 5, 1},
|
||||
{0, 5, 3, 2, 0},
|
||||
{0, 1, 3, 4, 0},
|
||||
{1, 5, 4, 2, 1},
|
||||
{0, 2, 3, 5, 0},
|
||||
{0, 4, 3, 1, 0},
|
||||
};
|
||||
|
||||
/* convert axis and face distance into face */
|
||||
static const int faces_table[3][6] = {
|
||||
{-1, 0, 0, -1, 3, 3},
|
||||
{-1, 4, 4, -1, 1, 1},
|
||||
{-1, 2, 2, -1, 5, 5},
|
||||
};
|
||||
|
||||
/* convert face magic bit mask to index into visit array */
|
||||
static const int faces_bit_magic[] = { 2, 1, -1, 0, 3, -1, 4, -1 };
|
||||
|
||||
/* axis the cube face cuts (also index into vec3_t and n % 3 for 0 <= n < 6) */
|
||||
static const int face_axis[] = { 0, 1, 2, 0, 1, 2 };
|
||||
|
||||
/* offset on the axis the cube face cuts */
|
||||
static const vec_t face_offset[] = { 1024, 1024, 1024, -1024, -1024, -1024 };
|
||||
|
||||
/* cube face */
|
||||
struct face_def {
|
||||
int tex; // texture to bind to
|
||||
glpoly_t poly; // describe the polygon of this face
|
||||
float verts[32][VERTEXSIZE];
|
||||
};
|
||||
|
||||
struct visit_def {
|
||||
int face; // face being visited
|
||||
int leave; // vertex departed through
|
||||
};
|
||||
|
||||
/* our cube */
|
||||
struct box_def {
|
||||
/* keep track of which cube faces we visit and in what order */
|
||||
struct visit_def visited_faces[9];
|
||||
int face_visits[6];
|
||||
int face_count;
|
||||
/* the cube faces */
|
||||
struct face_def face[6];
|
||||
};
|
||||
|
||||
/*
|
||||
determine_face
|
||||
|
||||
return the face of the cube which v hits first
|
||||
0 +x
|
||||
1 +y
|
||||
2 +z
|
||||
3 -x
|
||||
4 -y
|
||||
5 -z
|
||||
Also scales v so it touches that face.
|
||||
*/
|
||||
static int
|
||||
determine_face (vec3_t v)
|
||||
{
|
||||
float a[3];
|
||||
float m;
|
||||
int i = 0;
|
||||
|
||||
m = a[0] = fabs (v[0]);
|
||||
a[1] = fabs (v[1]);
|
||||
a[2] = fabs (v[2]);
|
||||
if (a[1] > m) {
|
||||
m = a[1];
|
||||
i = 1;
|
||||
}
|
||||
if (a[2] > m) {
|
||||
m = a[2];
|
||||
i = 2;
|
||||
}
|
||||
if (!m) {
|
||||
Sys_Error ("%s speared by sky poly edge\n", name->string);
|
||||
}
|
||||
if (v[i] < 0)
|
||||
i += 3;
|
||||
VectorScale (v, 1024 / m, v);
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
find_intersect (for want of a better name)
|
||||
|
||||
finds the point of intersection of the plane formed by the eye and the two
|
||||
points on the cube and the edge of the cube defined by the two faces.
|
||||
Currently, this will break if the two points are not on adjoining cube
|
||||
faces (ie either on opposing faces or the same face).
|
||||
|
||||
The equation for the point of intersection of a line and a plane is:
|
||||
|
||||
(x - p).n
|
||||
y = x - _________ v
|
||||
v.n
|
||||
|
||||
where n is the normal to the plane, p is a point on the plane, x is a
|
||||
point on the line, and v is the direction vector of the line. n is found
|
||||
by (x1 - e) cross (x2 - e) and p is taken to be e (e = eye coords) for
|
||||
simplicity. However, because e is at 0,0,0, this simplifies to n = x1
|
||||
cross x2 and p = 0,0,0, so the equation above simplifies to:
|
||||
|
||||
x.n
|
||||
y = x - ___ v
|
||||
v.n
|
||||
*/
|
||||
static int
|
||||
find_intersect (int face1, vec3_t x1, int face2, vec3_t x2, vec3_t y)
|
||||
{
|
||||
vec3_t n; // normal to the plane formed by the
|
||||
|
||||
// eye and the two points on the cube.
|
||||
|
||||
vec3_t x = { 0, 0, 0 }; // point on cube edge of adjoining
|
||||
|
||||
// faces. always on an axis plane.
|
||||
|
||||
vec3_t v = { 0, 0, 0 }; // direction vector of cube edge.
|
||||
|
||||
// always +ve
|
||||
|
||||
vec_t x_n, v_n; // x.n and v.n
|
||||
int axis;
|
||||
vec3_t t;
|
||||
|
||||
x[face_axis[face1]] = face_offset[face1];
|
||||
x[face_axis[face2]] = face_offset[face2];
|
||||
|
||||
axis = 3 - ((face_axis[face1]) + (face_axis[face2]));
|
||||
v[axis] = 1;
|
||||
|
||||
CrossProduct (x1, x2, n);
|
||||
|
||||
x_n = DotProduct (x, n);
|
||||
v_n = DotProduct (v, n);
|
||||
VectorScale (v, x_n / v_n, t);
|
||||
VectorSubtract (x, t, y);
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
/*
|
||||
find_cube_vertex
|
||||
|
||||
get the coords of the vertex common to the three specified faces of the
|
||||
cube. NOTE: this WILL break if the three faces do not share a common
|
||||
vertex. ie works = ((face1 % 3 != face2 % 3)
|
||||
&& (face2 % 3 != face3 % 3)
|
||||
&& (face1 % 3 != face3 % 3))
|
||||
*/
|
||||
static void
|
||||
find_cube_vertex (int face1, int face2, int face3, vec3_t v)
|
||||
{
|
||||
v[face_axis[face1]] = face_offset[face1];
|
||||
v[face_axis[face2]] = face_offset[face2];
|
||||
v[face_axis[face3]] = face_offset[face3];
|
||||
}
|
||||
|
||||
/*
|
||||
set_vertex
|
||||
|
||||
add the vertex to the polygon describing the face of the cube. Offsets
|
||||
the vertex relative to r_refdef.vieworg so the cube is always centered
|
||||
on the player and also calculates the texture coordinates of the vertex
|
||||
(wish I could find a cleaner way of calculating s and t).
|
||||
*/
|
||||
static void
|
||||
set_vertex (struct box_def *box, int face, int ind, vec3_t v)
|
||||
{
|
||||
VectorCopy (v, box->face[face].poly.verts[ind]);
|
||||
VectorAdd (v, r_refdef.vieworg, box->face[face].poly.verts[ind]);
|
||||
switch (face) {
|
||||
case 0:
|
||||
box->face[face].poly.verts[ind][3] = (1024 - v[1] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
case 1:
|
||||
box->face[face].poly.verts[ind][3] = (1024 + v[0] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
case 2:
|
||||
box->face[face].poly.verts[ind][3] = (1024 + v[0] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 + v[1] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
case 3:
|
||||
box->face[face].poly.verts[ind][3] = (1024 + v[1] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
case 4:
|
||||
box->face[face].poly.verts[ind][3] = (1024 - v[0] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
case 5:
|
||||
box->face[face].poly.verts[ind][3] = (1024 + v[0] + 4) / BOX_WIDTH;
|
||||
box->face[face].poly.verts[ind][4] = (1024 - v[1] + 4) / BOX_WIDTH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
add_vertex
|
||||
|
||||
append a vertex to the poly vertex list.
|
||||
*/
|
||||
static void
|
||||
add_vertex (struct box_def *box, int face, vec3_t v)
|
||||
{
|
||||
set_vertex (box, face, box->face[face].poly.numverts++, v);
|
||||
}
|
||||
|
||||
/*
|
||||
insert_cube_vertices
|
||||
|
||||
insert the given cube vertices into the vertex list of the poly in the
|
||||
correct location.
|
||||
*/
|
||||
static void
|
||||
insert_cube_vertices (struct box_def *box, struct visit_def visit, int count,
|
||||
...)
|
||||
{
|
||||
int i;
|
||||
vec3_t **v;
|
||||
va_list args;
|
||||
int face = visit.face;
|
||||
int ind = visit.leave + 1;
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// This is fix for borland alloca "feature" which fails to restore stack
|
||||
// correcly if calling function doesn't have any references to local variables.
|
||||
char dummy[5];
|
||||
|
||||
dummy[0]=0;
|
||||
#endif
|
||||
|
||||
va_start (args, count);
|
||||
v = (vec3_t **) alloca (count * sizeof (vec3_t *));
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
v[i] = va_arg (args, vec3_t *);
|
||||
}
|
||||
va_end (args);
|
||||
|
||||
if (ind == box->face[face].poly.numverts) {
|
||||
// the vertex the sky poly left this cube fase through is very
|
||||
// conveniently the last vertex of the face poly. this means we
|
||||
// can just append the vetexen
|
||||
for (i = 0; i < count; i++)
|
||||
add_vertex (box, face, *v[i]);
|
||||
} else {
|
||||
// we have to insert the cube vertices into the face poly
|
||||
// vertex list
|
||||
glpoly_t *p = &box->face[face].poly;
|
||||
int c = p->numverts - ind;
|
||||
const int vert_size = sizeof (p->verts[0]);
|
||||
|
||||
memmove (p->verts[ind + count], p->verts[ind], c * vert_size);
|
||||
p->numverts += count;
|
||||
for (i = 0; i < count; i++)
|
||||
set_vertex (box, face, ind + i, *v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
cross_cube_edge
|
||||
|
||||
add the vertex formed by the poly edge crossing the cube edge to the
|
||||
polygon for the two faces on that edge. Actually, the two faces define
|
||||
the edge :). The poly edge is going from face 1 to face 2 (for
|
||||
enter/leave purposes).
|
||||
*/
|
||||
static void
|
||||
cross_cube_edge (struct box_def *box, int face1, vec3_t v1, int face2,
|
||||
vec3_t v2)
|
||||
{
|
||||
vec3_t l;
|
||||
int axis;
|
||||
int face = -1;
|
||||
|
||||
axis = find_intersect (face1, v1, face2, v2, l);
|
||||
if (l[axis] > 1024)
|
||||
face = axis;
|
||||
else if (l[axis] < -1024)
|
||||
face = axis + 3;
|
||||
if (face >= 0) {
|
||||
vec3_t x;
|
||||
|
||||
VectorAdd (v1, v2, x);
|
||||
VectorScale (x, 0.5, x);
|
||||
cross_cube_edge (box, face1, v1, face, x);
|
||||
cross_cube_edge (box, face, x, face2, v2);
|
||||
} else {
|
||||
struct visit_def *visit = box->visited_faces;
|
||||
|
||||
visit[box->face_count - 1].leave = box->face[face1].poly.numverts;
|
||||
visit[box->face_count].face = face2;
|
||||
box->face_count++;
|
||||
box->face_visits[face2]++;
|
||||
|
||||
add_vertex (box, face1, l);
|
||||
add_vertex (box, face2, l);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
process_corners
|
||||
|
||||
egad, veddy complicated :)
|
||||
*/
|
||||
static void
|
||||
process_corners (struct box_def *box)
|
||||
{
|
||||
struct visit_def *visit = box->visited_faces;
|
||||
int max_visit = 0;
|
||||
int i;
|
||||
int center = -1;
|
||||
|
||||
if (visit[box->face_count - 1].face == visit[0].face) {
|
||||
box->face_count--;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (max_visit < box->face_visits[i]) {
|
||||
max_visit = box->face_visits[i];
|
||||
center = i;
|
||||
}
|
||||
}
|
||||
|
||||
switch (box->face_count) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 8:
|
||||
// no corners
|
||||
return;
|
||||
case 3:
|
||||
// one corner, no edges
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
find_cube_vertex (visit[0].face, visit[1].face, visit[2].face,
|
||||
v);
|
||||
insert_cube_vertices (box, visit[0], 1, v);
|
||||
insert_cube_vertices (box, visit[1], 1, v);
|
||||
insert_cube_vertices (box, visit[2], 1, v);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (max_visit > 1)
|
||||
return;
|
||||
if (abs (visit[2].face - visit[0].face) == 3
|
||||
&& abs (visit[3].face - visit[1].face) == 3) {
|
||||
// 4 vertices
|
||||
int sum, diff;
|
||||
vec3_t v[4];
|
||||
|
||||
sum =
|
||||
visit[0].face + visit[1].face + visit[2].face +
|
||||
visit[3].face;
|
||||
diff = visit[1].face - visit[0].face;
|
||||
sum %= 3;
|
||||
diff = (diff + 6) % 6;
|
||||
|
||||
center = faces_table[sum][diff];
|
||||
for (i = 0; i < 4; i++) {
|
||||
find_cube_vertex (visit[i].face, visit[(i + 1) & 3].face,
|
||||
center, v[i]);
|
||||
add_vertex (box, center, v[i]);
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
insert_cube_vertices (box, visit[i], 2, v[i],
|
||||
v[(i - 1) & 3]);
|
||||
} else {
|
||||
// 2 vertices
|
||||
int l_f, t_f, r_f, b_f;
|
||||
vec3_t v_l, v_r;
|
||||
|
||||
if (abs (visit[2].face - visit[0].face) == 3) {
|
||||
l_f = 0;
|
||||
t_f = 1;
|
||||
r_f = 2;
|
||||
b_f = 3;
|
||||
} else if (abs (visit[3].face - visit[1].face) == 3) {
|
||||
l_f = 1;
|
||||
t_f = 2;
|
||||
r_f = 3;
|
||||
b_f = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
find_cube_vertex (visit[l_f].face, visit[t_f].face,
|
||||
visit[b_f].face, v_l);
|
||||
find_cube_vertex (visit[r_f].face, visit[t_f].face,
|
||||
visit[b_f].face, v_r);
|
||||
|
||||
insert_cube_vertices (box, visit[t_f], 2, v_r, v_l);
|
||||
insert_cube_vertices (box, visit[b_f], 2, v_l, v_r);
|
||||
|
||||
insert_cube_vertices (box, visit[l_f], 1, v_l);
|
||||
insert_cube_vertices (box, visit[r_f], 1, v_r);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (max_visit > 1) {
|
||||
// one vertex
|
||||
vec3_t v;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
// don't need to check the 5th visit
|
||||
if (visit[(i + 2) % 5].face == visit[(i + 4) % 5].face)
|
||||
break;
|
||||
}
|
||||
find_cube_vertex (visit[i].face, visit[(i + 1) % 5].face,
|
||||
visit[(i + 2) % 5].face, v);
|
||||
insert_cube_vertices (box, visit[i], 1, v);
|
||||
insert_cube_vertices (box, visit[(i + 1) % 5], 1, v);
|
||||
insert_cube_vertices (box, visit[(i + 4) % 5], 1, v);
|
||||
|
||||
} else {
|
||||
// 3 vertices
|
||||
unsigned int sel =
|
||||
(((abs (visit[2].face - visit[0].face) == 3) << 2) |
|
||||
((abs (visit[3].face - visit[1].face) == 3) << 1)
|
||||
| ((abs (visit[4].face - visit[2].face) == 3) << 0));
|
||||
vec3_t v[3];
|
||||
|
||||
center = faces_bit_magic[sel];
|
||||
// printf ("%02o %d %d %d %d %d %d\n", sel, center,
|
||||
// visit[0].face,
|
||||
// visit[1].face, visit[2].face, visit[3].face,
|
||||
// visit[4].face);
|
||||
for (i = 0; i < 3; i++)
|
||||
find_cube_vertex (visit[center].face,
|
||||
visit[(center + 1 + i) % 5].face,
|
||||
visit[(center + 2 + i) % 5].face, v[i]);
|
||||
insert_cube_vertices (box, visit[center], 3, v[0], v[1], v[2]);
|
||||
insert_cube_vertices (box, visit[(center + 1) % 5], 1, v[0]);
|
||||
insert_cube_vertices (box, visit[(center + 2) % 5], 2, v[1],
|
||||
v[0]);
|
||||
insert_cube_vertices (box, visit[(center + 3) % 5], 2, v[2],
|
||||
v[1]);
|
||||
insert_cube_vertices (box, visit[(center + 4) % 5], 1, v[2]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (max_visit > 2)
|
||||
return;
|
||||
for (i = 0; i < 5; i++) {
|
||||
// don't need to check the last point
|
||||
if (visit[(i + 3) % 6].face == visit[(i + 5) % 6].face
|
||||
|| visit[(i + 2) % 6].face == visit[(i + 5) % 6].face)
|
||||
break;
|
||||
}
|
||||
if (visit[(i + 3) % 6].face == visit[(i + 5) % 6].face) {
|
||||
// adjacant vertices
|
||||
vec3_t v[2];
|
||||
|
||||
find_cube_vertex (visit[i].face, visit[(i + 1) % 6].face,
|
||||
visit[(i + 2) % 6].face, v[0]);
|
||||
find_cube_vertex (visit[(i + 1) % 6].face,
|
||||
visit[(i + 2) % 6].face,
|
||||
visit[(i + 3) % 6].face, v[1]);
|
||||
|
||||
insert_cube_vertices (box, visit[(i + 5) % 6], 2, v[2], v[1]);
|
||||
|
||||
insert_cube_vertices (box, visit[i], 1, v[0]);
|
||||
insert_cube_vertices (box, visit[(i + 1) % 6], 2, v[1], v[0]);
|
||||
insert_cube_vertices (box, visit[(i + 2) % 6], 1, v[1]);
|
||||
} else {
|
||||
// opposing vertices
|
||||
vec3_t v[2];
|
||||
|
||||
find_cube_vertex (visit[i].face, visit[(i + 1) % 6].face,
|
||||
visit[(i + 2) % 6].face, v[0]);
|
||||
find_cube_vertex (visit[(i + 3) % 6].face,
|
||||
visit[(i + 4) % 6].face,
|
||||
visit[(i + 5) % 6].face, v[1]);
|
||||
|
||||
insert_cube_vertices (box, visit[i], 1, v[0]);
|
||||
insert_cube_vertices (box, visit[(i + 1) % 6], 1, v[0]);
|
||||
|
||||
insert_cube_vertices (box, visit[(i + 3) % 6], 1, v[1]);
|
||||
insert_cube_vertices (box, visit[(i + 4) % 6], 1, v[1]);
|
||||
|
||||
insert_cube_vertices (box, visit[(i + 2) % 6], 1, v[1]);
|
||||
insert_cube_vertices (box, visit[(i + 5) % 6], 1, v[0]);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
for (i = 0; i < 6; i++) {
|
||||
// don't need to check the last point
|
||||
if (visit[(i + 2) % 6].face == visit[(i + 4) % 6].face
|
||||
&& visit[(i + 4) % 6].face == visit[(i + 6) % 6].face)
|
||||
break;
|
||||
}
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
find_cube_vertex (visit[i].face, visit[(i + 1) % 6].face,
|
||||
visit[(i + 2) % 6].face, v);
|
||||
|
||||
insert_cube_vertices (box, visit[i], 1, v);
|
||||
insert_cube_vertices (box, visit[(i + 1) % 7], 1, v);
|
||||
insert_cube_vertices (box, visit[(i + 6) % 7], 1, v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
render_box
|
||||
|
||||
draws all faces of the cube with 3 or more vertices.
|
||||
*/
|
||||
static void
|
||||
render_box (struct box_def *box)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (box->face[i].poly.numverts <= 2)
|
||||
continue;
|
||||
glBindTexture (GL_TEXTURE_2D, box->face[i].tex);
|
||||
glBegin (GL_POLYGON);
|
||||
for (j = 0; j < box->face[i].poly.numverts; j++) {
|
||||
glTexCoord2fv (box->face[i].poly.verts[j] + 3);
|
||||
glVertex3fv (box->face[i].poly.verts[j]);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSkyBoxPoly (glpoly_t *poly)
|
||||
{
|
||||
int i;
|
||||
struct box_def box;
|
||||
|
||||
/* projected vertex and face of the previous sky poly vertex */
|
||||
vec3_t last_v;
|
||||
int prev_face;
|
||||
|
||||
/* projected vertex and face of the current sky poly vertex */
|
||||
vec3_t v;
|
||||
int face;
|
||||
|
||||
memset (&box, 0, sizeof (box));
|
||||
for (i = 0; i < 6; i++) {
|
||||
box.face[i].tex = SKY_TEX + skytex_offs[i];
|
||||
}
|
||||
|
||||
if (poly->numverts >= 32) {
|
||||
Sys_Error ("too many verts!");
|
||||
}
|
||||
|
||||
VectorSubtract (poly->verts[poly->numverts - 1], r_refdef.vieworg, last_v);
|
||||
prev_face = determine_face (last_v);
|
||||
|
||||
box.visited_faces[0].face = prev_face;
|
||||
box.face_count = 1;
|
||||
|
||||
for (i = 0; i < poly->numverts; i++) {
|
||||
VectorSubtract (poly->verts[i], r_refdef.vieworg, v);
|
||||
face = determine_face (v);
|
||||
if (face != prev_face) {
|
||||
if ((face_axis[face]) == (face_axis[prev_face])) {
|
||||
int x_face;
|
||||
vec3_t x;
|
||||
|
||||
VectorAdd (v, last_v, x);
|
||||
VectorScale (x, 0.5, x);
|
||||
x_face = determine_face (x);
|
||||
|
||||
cross_cube_edge (&box, prev_face, last_v, x_face, x);
|
||||
cross_cube_edge (&box, x_face, x, face, v);
|
||||
} else {
|
||||
cross_cube_edge (&box, prev_face, last_v, face, v);
|
||||
}
|
||||
}
|
||||
add_vertex (&box, face, v);
|
||||
|
||||
VectorCopy (v, last_v);
|
||||
prev_face = face;
|
||||
}
|
||||
|
||||
process_corners (&box);
|
||||
|
||||
render_box (&box);
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSkyDomePoly (glpoly_t *poly)
|
||||
{
|
||||
int i;
|
||||
|
||||
glBegin (GL_POLYGON);
|
||||
for (i = 0; i < poly->numverts; i++) {
|
||||
glVertex3fv (poly->verts[i]);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
void
|
||||
R_DrawSkyChain (msurface_t *sky_chain)
|
||||
{
|
||||
msurface_t *sc = sky_chain;
|
||||
float l = 1 / (256 * brightness->value);
|
||||
|
||||
glColor3f (lighthalf_v[0] * l, lighthalf_v[1] * l, lighthalf_v[2] * l);
|
||||
if (skyloaded) {
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
while (sc) {
|
||||
glpoly_t *p = sc->polys;
|
||||
|
||||
while (p) {
|
||||
R_DrawSkyBoxPoly (p);
|
||||
p = p->next;
|
||||
}
|
||||
sc = sc->texturechain;
|
||||
}
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
} else {
|
||||
glDisable (GL_BLEND);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glColor3f (0, 0, 0);
|
||||
while (sc) {
|
||||
glpoly_t *p = sc->polys;
|
||||
|
||||
while (p) {
|
||||
R_DrawSkyDomePoly (p);
|
||||
p = p->next;
|
||||
}
|
||||
sc = sc->texturechain;
|
||||
}
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glEnable (GL_BLEND);
|
||||
}
|
||||
#if 0
|
||||
// seems to work, but this is the wrong place to do it.
|
||||
glColor4f (1,1,1,0);
|
||||
sc = sky_chain;
|
||||
while (sc) {
|
||||
glpoly_t *p = sc->polys;
|
||||
|
||||
while (p) {
|
||||
int i;
|
||||
glBegin (GL_POLYGON);
|
||||
for (i = 0; i < p->numverts; i++) {
|
||||
glVertex3fv (p->verts[i]);
|
||||
}
|
||||
glEnd ();
|
||||
p = p->next;
|
||||
}
|
||||
sc = sc->texturechain;
|
||||
}
|
||||
#endif
|
||||
glColor3ubv (lighthalf_v);
|
||||
#if 0
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
sc = sky_chain;
|
||||
glColor3f (1, 1, 1);
|
||||
while (sc) {
|
||||
glpoly_t *p = sc->polys;
|
||||
|
||||
while (p) {
|
||||
int i;
|
||||
|
||||
glBegin (GL_LINE_LOOP);
|
||||
for (i = 0; i < p->numverts; i++) {
|
||||
glVertex3fv (p->verts[i]);
|
||||
}
|
||||
glEnd ();
|
||||
p = p->next;
|
||||
}
|
||||
sc = sc->texturechain;
|
||||
}
|
||||
sc = sky_chain;
|
||||
glColor3f (0, 1, 0);
|
||||
glBegin (GL_POINTS);
|
||||
while (sc) {
|
||||
glpoly_t *p = sc->polys;
|
||||
|
||||
while (p) {
|
||||
int i;
|
||||
vec3_t x, c = { 0, 0, 0 };
|
||||
|
||||
for (i = 0; i < p->numverts; i++) {
|
||||
VectorSubtract (p->verts[i], r_refdef.vieworg, x);
|
||||
VectorAdd (x, c, c);
|
||||
}
|
||||
VectorScale (c, 1.0 / p->numverts, c);
|
||||
VectorAdd (c, r_refdef.vieworg, c);
|
||||
glVertex3fv (c);
|
||||
p = p->next;
|
||||
}
|
||||
sc = sc->texturechain;
|
||||
}
|
||||
glEnd ();
|
||||
if (skyloaded) {
|
||||
int i, j;
|
||||
|
||||
glColor3f (1, 0, 0);
|
||||
for (i = 0; i < 6; i++) {
|
||||
vec3_t v;
|
||||
|
||||
glBegin (GL_LINE_LOOP);
|
||||
for (j = 0; j < 4; j++) {
|
||||
memcpy (v, &skyvec[i][j][2], sizeof (v));
|
||||
VectorAdd (v, r_refdef.vieworg, v);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
glColor3ubv (lighthalf_v);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
#endif
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
gl_warp.c
|
||||
|
||||
sky and water polygons
|
||||
water polygons
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -29,41 +29,17 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/compat.h"
|
||||
#include "QF/console.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "render.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;
|
||||
|
@ -173,13 +149,11 @@ SubdividePolygon (int numverts, float *verts)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
GL_SubdivideSurface
|
||||
GL_SubdivideSurface
|
||||
|
||||
Breaks a polygon up along axial 64 unit
|
||||
boundaries so that turbulent and sky warps
|
||||
can be done reasonably.
|
||||
================
|
||||
Breaks a polygon up along axial 64 unit
|
||||
boundaries so that turbulent and sky warps
|
||||
can be done reasonably.
|
||||
*/
|
||||
void
|
||||
GL_SubdivideSurface (msurface_t *fa)
|
||||
|
@ -212,20 +186,19 @@ GL_SubdivideSurface (msurface_t *fa)
|
|||
|
||||
//=========================================================
|
||||
|
||||
|
||||
// speed up sin calculations - Ed
|
||||
float turbsin[] = {
|
||||
# include "gl_warp_sin.h"
|
||||
};
|
||||
|
||||
|
||||
#define TURBSCALE (256.0 / (2 * M_PI))
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
*/
|
||||
void
|
||||
EmitWaterPolys (msurface_t *fa)
|
||||
|
@ -261,602 +234,3 @@ EmitWaterPolys (msurface_t *fa)
|
|||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
Quake 2 environment sky
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
#define SKY_TEX 2000
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
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 (const char *skyname)
|
||||
{
|
||||
int i;
|
||||
QFile *f;
|
||||
char name[64];
|
||||
|
||||
if (strcasecmp (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;
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_ALWAYS);
|
||||
// glDisable (GL_BLEND);
|
||||
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
if (lighthalf)
|
||||
glColor3f (0.5, 0.5, 0.5);
|
||||
else
|
||||
glColor3f (1, 1, 1);
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
glColor3f (1, 1, 1);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
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)
|
||||
{
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_ALWAYS);
|
||||
// glDisable (GL_BLEND);
|
||||
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthRange (gldepthmax, gldepthmax);
|
||||
glDisable (GL_BLEND);
|
||||
if (lighthalf)
|
||||
glColor3f (0.5, 0.5, 0.5);
|
||||
else
|
||||
glColor3f (1, 1, 1);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// glDisable (GL_BLEND);
|
||||
glColor3f (1, 1, 1);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
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 trans[128 * 128];
|
||||
unsigned transpix;
|
||||
int r, g, b;
|
||||
unsigned *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);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EmitSkyPolys (msurface_t *fa)
|
||||
{
|
||||
glpoly_t *p;
|
||||
float *v;
|
||||
int i;
|
||||
float s, t;
|
||||
vec3_t dir;
|
||||
float length;
|
||||
|
||||
for (p = fa->polys; p; p = p->next) {
|
||||
glBegin (GL_POLYGON);
|
||||
for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE) {
|
||||
VectorSubtract (v, r_origin, dir);
|
||||
dir[2] *= 3; // flatten the sphere
|
||||
|
||||
length = dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2];
|
||||
length = sqrt (length);
|
||||
length = 6 * 63 / length;
|
||||
|
||||
dir[0] *= length;
|
||||
dir[1] *= length;
|
||||
|
||||
s = (speedscale + dir[0]) * (1.0 / 128);
|
||||
t = (speedscale + dir[1]) * (1.0 / 128);
|
||||
|
||||
glTexCoord2f (s, t);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
// used when gl_texsort is on
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime * 8;
|
||||
speedscale -= (int) speedscale & ~127;
|
||||
|
||||
for (fa = s; fa; fa = fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime * 16;
|
||||
speedscale -= (int) speedscale & ~127;
|
||||
|
||||
for (fa = s; fa; fa = fa->texturechain)
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
EmitBothSkyLayers
|
||||
|
||||
Does a sky warp on the pre-fragmented glpoly_t chain
|
||||
This will be called for brushmodels, the world
|
||||
will have them chained together.
|
||||
===============
|
||||
*/
|
||||
void
|
||||
EmitBothSkyLayers (msurface_t *fa)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
||||
speedscale = realtime * 8;
|
||||
speedscale -= (int) speedscale & ~127;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glEnable (GL_BLEND);
|
||||
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
||||
speedscale = realtime * 16;
|
||||
speedscale -= (int) speedscale & ~127;
|
||||
|
||||
EmitSkyPolys (fa);
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ Host_Error (char *error, ...)
|
|||
Sys_Error ("Host_Error: recursively entered");
|
||||
inerror = true;
|
||||
|
||||
SCR_EndLoadingPlaque (); // reenable screen updates
|
||||
// SCR_EndLoadingPlaque (); // reenable screen updates
|
||||
|
||||
va_start (argptr, error);
|
||||
vsnprintf (string, sizeof (string), error, argptr);
|
||||
|
|
|
@ -279,7 +279,7 @@ Host_Map_f (void)
|
|||
Host_ShutdownServer (false);
|
||||
|
||||
key_dest = key_game; // remove console or menu
|
||||
SCR_BeginLoadingPlaque ();
|
||||
// SCR_BeginLoadingPlaque ();
|
||||
|
||||
cls.mapstring[0] = 0;
|
||||
for (i = 0; i < Cmd_Argc (); i++) {
|
||||
|
@ -404,7 +404,7 @@ This is sent just before a server changes levels
|
|||
void
|
||||
Host_Reconnect_f (void)
|
||||
{
|
||||
SCR_BeginLoadingPlaque ();
|
||||
// SCR_BeginLoadingPlaque ();
|
||||
cls.signon = 0; // need new connection messages
|
||||
}
|
||||
|
||||
|
|
206
nq/source/pcx.c
Normal file
206
nq/source/pcx.c
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
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
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/console.h"
|
||||
#include "QF/pcx.h"
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/qtypes.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/texture.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/zone.h"
|
||||
|
||||
tex_t *
|
||||
LoadPCX (QFile *f, int convert)
|
||||
{
|
||||
pcx_t *pcx;
|
||||
int pcx_mark;
|
||||
byte *palette;
|
||||
byte *pix;
|
||||
byte *dataByte;
|
||||
int x, y;
|
||||
int runLength = 1;
|
||||
int count;
|
||||
tex_t *tex;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
pcx_mark = Hunk_LowMark ();
|
||||
pcx = Hunk_AllocName (com_filesize, "PCX");
|
||||
Qread (f, pcx, com_filesize);
|
||||
|
||||
pcx->xmax = LittleShort (pcx->xmax);
|
||||
pcx->xmin = LittleShort (pcx->xmin);
|
||||
pcx->ymax = LittleShort (pcx->ymax);
|
||||
pcx->ymin = LittleShort (pcx->ymin);
|
||||
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);
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
palette = ((byte*)pcx) + com_filesize - 768;
|
||||
dataByte = (byte*)&pcx[1];
|
||||
|
||||
count = (pcx->xmax + 1) * (pcx->ymax + 1);
|
||||
if (convert)
|
||||
count *= 4;
|
||||
tex = Hunk_TempAlloc (sizeof (tex_t) + count);
|
||||
tex->width = pcx->xmax + 1;
|
||||
tex->height = pcx->ymax + 1;
|
||||
if (convert) {
|
||||
tex->palette = 0;
|
||||
} else {
|
||||
tex->palette = vid_basepal;
|
||||
}
|
||||
pix = tex->data;
|
||||
|
||||
for (y = 0; y < tex->height; y++) {
|
||||
for (x = 0; x < tex->width;) {
|
||||
runLength = 1;
|
||||
if (dataByte >= palette)
|
||||
break;
|
||||
|
||||
if ((*dataByte & 0xC0) == 0xC0) {
|
||||
runLength = *dataByte++ & 0x3F;
|
||||
if (dataByte >= palette)
|
||||
break;
|
||||
}
|
||||
|
||||
if (convert) {
|
||||
while (count && runLength > 0) {
|
||||
pix[0] = palette[*dataByte * 3];
|
||||
pix[1] = palette[*dataByte * 3 + 1];
|
||||
pix[2] = palette[*dataByte * 3 + 2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
count -= 4;
|
||||
runLength--;
|
||||
x++;
|
||||
}
|
||||
} else {
|
||||
while (count && runLength > 0) {
|
||||
*pix++ = *dataByte;
|
||||
count--;
|
||||
runLength--;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if (runLength)
|
||||
break;
|
||||
dataByte++;
|
||||
}
|
||||
if (runLength)
|
||||
break;
|
||||
}
|
||||
Hunk_FreeToLowMark (pcx_mark);
|
||||
if (count || runLength) {
|
||||
Con_Printf ("PCX was malformed. You should delete it.\n");
|
||||
return 0;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
pcx_t *
|
||||
EncodePCX (byte * data, int width, int height,
|
||||
int rowbytes, byte * palette, qboolean flip, int *length)
|
||||
{
|
||||
int i, j;
|
||||
pcx_t *pcx;
|
||||
byte *pack;
|
||||
|
||||
if (!(pcx = Hunk_TempAlloc (width * height * 2 + 1000))) {
|
||||
Con_Printf ("EncodePCX: not enough memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcx->manufacturer = 0x0a; // PCX id
|
||||
pcx->version = 5; // 256 color
|
||||
pcx->encoding = 1; // uncompressed
|
||||
pcx->bits_per_pixel = 8; // 256 color
|
||||
pcx->xmin = 0;
|
||||
pcx->ymin = 0;
|
||||
pcx->xmax = LittleShort ((short) (width - 1));
|
||||
pcx->ymax = LittleShort ((short) (height - 1));
|
||||
pcx->hres = LittleShort ((short) width);
|
||||
pcx->vres = LittleShort ((short) height);
|
||||
memset (pcx->palette, 0, sizeof (pcx->palette));
|
||||
pcx->color_planes = 1; // chunky image
|
||||
pcx->bytes_per_line = LittleShort ((short) width);
|
||||
pcx->palette_type = LittleShort (2); // not a grey scale
|
||||
memset (pcx->filler, 0, sizeof (pcx->filler));
|
||||
|
||||
// pack the image
|
||||
pack = (byte*)&pcx[1];
|
||||
|
||||
if (flip)
|
||||
data += rowbytes * (height - 1);
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if ((*data & 0xc0) != 0xc0)
|
||||
*pack++ = *data++;
|
||||
else {
|
||||
*pack++ = 0xc1;
|
||||
*pack++ = *data++;
|
||||
}
|
||||
}
|
||||
|
||||
data += rowbytes - width;
|
||||
if (flip)
|
||||
data -= rowbytes * 2;
|
||||
}
|
||||
|
||||
// write the palette
|
||||
*pack++ = 0x0c; // palette ID byte
|
||||
for (i = 0; i < 768; i++)
|
||||
*pack++ = *palette++;
|
||||
|
||||
// write output file
|
||||
*length = pack - (byte *) pcx;
|
||||
return pcx;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
r_draw.c
|
||||
|
||||
@description@
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -78,12 +78,10 @@ int r_ceilv1;
|
|||
qboolean r_lastvertvalid;
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
#ifndef USE_INTEL_ASM
|
||||
|
||||
/*
|
||||
================
|
||||
R_EmitEdge
|
||||
================
|
||||
R_EmitEdge
|
||||
*/
|
||||
void
|
||||
R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
|
||||
|
@ -250,9 +248,7 @@ R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ClipEdge
|
||||
================
|
||||
R_ClipEdge
|
||||
*/
|
||||
void
|
||||
R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
|
||||
|
@ -335,13 +331,11 @@ R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
|
|||
R_EmitEdge (pv0, pv1);
|
||||
}
|
||||
|
||||
#endif // USE_INTEL_ASM
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_EmitCachedEdge
|
||||
================
|
||||
R_EmitCachedEdge
|
||||
*/
|
||||
void
|
||||
R_EmitCachedEdge (void)
|
||||
|
@ -363,15 +357,13 @@ R_EmitCachedEdge (void)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderFace
|
||||
================
|
||||
R_RenderFace
|
||||
*/
|
||||
void
|
||||
R_RenderFace (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex;
|
||||
unsigned mask;
|
||||
unsigned int mask;
|
||||
mplane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
|
@ -534,15 +526,13 @@ R_RenderFace (msurface_t *fa, int clipflags)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderBmodelFace
|
||||
================
|
||||
R_RenderBmodelFace
|
||||
*/
|
||||
void
|
||||
R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
|
||||
{
|
||||
int i;
|
||||
unsigned mask;
|
||||
unsigned int mask;
|
||||
mplane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
|
@ -639,16 +629,14 @@ R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RenderPoly
|
||||
================
|
||||
R_RenderPoly
|
||||
*/
|
||||
void
|
||||
R_RenderPoly (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex, lnumverts, s_axis, t_axis;
|
||||
float dist, lastdist, lzi, scale, u, v, frac;
|
||||
unsigned mask;
|
||||
unsigned int mask;
|
||||
vec3_t local, transformed;
|
||||
clipplane_t *pclip;
|
||||
medge_t *pedges;
|
||||
|
@ -746,19 +734,19 @@ R_RenderPoly (msurface_t *fa, int clipflags)
|
|||
switch (pplane->type) {
|
||||
case PLANE_X:
|
||||
case PLANE_ANYX:
|
||||
s_axis = 1;
|
||||
t_axis = 2;
|
||||
break;
|
||||
s_axis = 1;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
case PLANE_ANYY:
|
||||
s_axis = 0;
|
||||
t_axis = 2;
|
||||
break;
|
||||
s_axis = 0;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
case PLANE_ANYZ:
|
||||
s_axis = 0;
|
||||
t_axis = 1;
|
||||
break;
|
||||
s_axis = 0;
|
||||
t_axis = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
r_nearzi = 0;
|
||||
|
@ -811,9 +799,7 @@ R_RenderPoly (msurface_t *fa, int clipflags)
|
|||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ZDrawSubmodelPolys
|
||||
================
|
||||
R_ZDrawSubmodelPolys
|
||||
*/
|
||||
void
|
||||
R_ZDrawSubmodelPolys (model_t *pmodel)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
r_sky.c
|
||||
|
||||
@description@
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "client.h"
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
int iskyspeed = 8;
|
||||
|
@ -60,11 +59,9 @@ byte newsky[128 * 256]; // newsky and topsky both pack in
|
|||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_InitSky
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
*/
|
||||
void
|
||||
R_InitSky (texture_t *mt)
|
||||
|
@ -97,9 +94,7 @@ R_InitSky (texture_t *mt)
|
|||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_MakeSky
|
||||
=================
|
||||
R_MakeSky
|
||||
*/
|
||||
void
|
||||
R_MakeSky (void)
|
||||
|
@ -107,7 +102,7 @@ R_MakeSky (void)
|
|||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
unsigned *pnewsky;
|
||||
unsigned int *pnewsky;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift = skytime * skyspeed;
|
||||
|
@ -119,7 +114,7 @@ R_MakeSky (void)
|
|||
xlast = xshift;
|
||||
ylast = yshift;
|
||||
|
||||
pnewsky = (unsigned *) &newsky[0];
|
||||
pnewsky = (unsigned int *) &newsky[0];
|
||||
|
||||
for (y = 0; y < SKYSIZE; y++) {
|
||||
baseofs = ((y + yshift) & SKYMASK) * 131;
|
||||
|
@ -132,9 +127,9 @@ R_MakeSky (void)
|
|||
|
||||
// PORT: unaligned dword access to bottommask and bottomsky
|
||||
|
||||
*pnewsky = (*(pnewsky + (128 / sizeof (unsigned))) &
|
||||
*(unsigned *) &bottommask[ofs]) |
|
||||
*(unsigned *) &bottomsky[ofs];
|
||||
*pnewsky = (*(pnewsky + (128 / sizeof (unsigned int))) &
|
||||
*(unsigned int *) &bottommask[ofs]) |
|
||||
*(unsigned int *) &bottomsky[ofs];
|
||||
|
||||
pnewsky++;
|
||||
}
|
||||
|
@ -147,12 +142,12 @@ R_MakeSky (void)
|
|||
*(byte *) pnewsky = (*((byte *) pnewsky + 128) &
|
||||
*(byte *) & bottommask[ofs]) |
|
||||
*(byte *) & bottomsky[ofs];
|
||||
pnewsky = (unsigned *) ((byte *) pnewsky + 1);
|
||||
pnewsky = (unsigned int *) ((byte *) pnewsky + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pnewsky += 128 / sizeof (unsigned);
|
||||
pnewsky += 128 / sizeof (unsigned int);
|
||||
}
|
||||
|
||||
r_skymade = 1;
|
||||
|
@ -160,9 +155,7 @@ R_MakeSky (void)
|
|||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_GenSkyTile
|
||||
=================
|
||||
R_GenSkyTile
|
||||
*/
|
||||
void
|
||||
R_GenSkyTile (void *pdest)
|
||||
|
@ -170,14 +163,14 @@ R_GenSkyTile (void *pdest)
|
|||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
unsigned *pnewsky;
|
||||
unsigned *pd;
|
||||
unsigned int *pnewsky;
|
||||
unsigned int *pd;
|
||||
|
||||
xshift = skytime * skyspeed;
|
||||
yshift = skytime * skyspeed;
|
||||
|
||||
pnewsky = (unsigned *) &newsky[0];
|
||||
pd = (unsigned *) pdest;
|
||||
pnewsky = (unsigned int *) &newsky[0];
|
||||
pd = (unsigned int *) pdest;
|
||||
|
||||
for (y = 0; y < SKYSIZE; y++) {
|
||||
baseofs = ((y + yshift) & SKYMASK) * 131;
|
||||
|
@ -190,10 +183,10 @@ R_GenSkyTile (void *pdest)
|
|||
|
||||
// PORT: unaligned dword access to bottommask and bottomsky
|
||||
|
||||
*pd = (*(pnewsky + (128 / sizeof (unsigned))) &
|
||||
*(unsigned *) &bottommask[ofs]) |
|
||||
*pd = (*(pnewsky + (128 / sizeof (unsigned int))) &
|
||||
*(unsigned int *) &bottommask[ofs]) |
|
||||
*(unsigned int *) &bottomsky[ofs];
|
||||
|
||||
*(unsigned *) &bottomsky[ofs];
|
||||
pnewsky++;
|
||||
pd++;
|
||||
}
|
||||
|
@ -206,21 +199,19 @@ R_GenSkyTile (void *pdest)
|
|||
*(byte *) pd = (*((byte *) pnewsky + 128) &
|
||||
*(byte *) & bottommask[ofs]) |
|
||||
*(byte *) & bottomsky[ofs];
|
||||
pnewsky = (unsigned *) ((byte *) pnewsky + 1);
|
||||
pd = (unsigned *) ((byte *) pd + 1);
|
||||
pnewsky = (unsigned int *) ((byte *) pnewsky + 1);
|
||||
pd = (unsigned int *) ((byte *) pd + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pnewsky += 128 / sizeof (unsigned);
|
||||
pnewsky += 128 / sizeof (unsigned int);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_GenSkyTile16
|
||||
=================
|
||||
R_GenSkyTile16
|
||||
*/
|
||||
void
|
||||
R_GenSkyTile16 (void *pdest)
|
||||
|
@ -258,9 +249,7 @@ R_GenSkyTile16 (void *pdest)
|
|||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_SetSkyFrame
|
||||
==============
|
||||
R_SetSkyFrame
|
||||
*/
|
||||
void
|
||||
R_SetSkyFrame (void)
|
||||
|
@ -281,3 +270,15 @@ R_SetSkyFrame (void)
|
|||
|
||||
r_skymade = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_LoadSkys
|
||||
|
||||
Stub function for loading a skybox. Currently we only have support for
|
||||
skyboxes in GL targets, so we just do nothing here. --KB
|
||||
*/
|
||||
void
|
||||
R_LoadSkys (const char *name)
|
||||
{
|
||||
}
|
||||
|
|
244
nq/source/tga.c
Normal file
244
nq/source/tga.c
Normal file
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
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
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/tga.h"
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriteTGAfile (const char *tganame, byte *data, int width, int height)
|
||||
{
|
||||
TargaHeader header;
|
||||
|
||||
memset (&header, 0, sizeof (header));
|
||||
header.image_type = 2; // uncompressed type
|
||||
header.width = LittleShort (width);
|
||||
header.height = LittleShort (height);
|
||||
header.pixel_size = 24;
|
||||
|
||||
COM_WriteBuffers (tganame, 2, &header, sizeof (header), data,
|
||||
width * height * 3);
|
||||
}
|
|
@ -603,10 +603,8 @@ Draw_ConsoleBackground (int lines)
|
|||
}
|
||||
}
|
||||
|
||||
if (!cls.download)
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string)
|
||||
* 8 - 11, lines - 14, cl_verstring->string);
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string)
|
||||
* 8 - 11, lines - 14, cl_verstring->string);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -642,10 +642,9 @@ Draw_ConsoleBackground (int lines)
|
|||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix ();
|
||||
}
|
||||
// draw version string if not downloading
|
||||
if (!cls.download)
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string) * 8 - 11,
|
||||
lines - 14, cl_verstring->string);
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string) * 8 - 11,
|
||||
lines - 14, cl_verstring->string);
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue