mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
FINALLY, the nq and qw renderers are merged. the view and particle subsystems
are not yet merged due to their dependence on the client, but that will come soon.
This commit is contained in:
parent
55ee68cf38
commit
73e6e1684f
131 changed files with 1434 additions and 25737 deletions
|
@ -1536,6 +1536,9 @@ AC_OUTPUT(
|
|||
libs/models/sprite/Makefile
|
||||
libs/util/Makefile
|
||||
libs/video/Makefile
|
||||
libs/video/renderer/Makefile
|
||||
libs/video/renderer/gl/Makefile
|
||||
libs/video/renderer/sw/Makefile
|
||||
libs/video/targets/Makefile
|
||||
|
||||
qw/Makefile
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SUBDIRS= targets
|
||||
SUBDIRS= renderer targets
|
||||
|
||||
clean-local:
|
||||
rm -f *.a
|
||||
|
|
9
libs/video/renderer/.gitignore
vendored
Normal file
9
libs/video/renderer/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.la
|
||||
*.lo
|
||||
.deps
|
||||
.libs
|
||||
.vimrc
|
||||
Makefile
|
||||
Makefile.in
|
||||
fbset_modes_y.[ch]
|
||||
fbset_modes_l.c
|
30
libs/video/renderer/Makefile.am
Normal file
30
libs/video/renderer/Makefile.am
Normal file
|
@ -0,0 +1,30 @@
|
|||
SUBDIRS= gl sw
|
||||
INCLUDES= -I$(top_srcdir)/include
|
||||
|
||||
if BUILD_GL
|
||||
RENDERER_GL = libQFrenderer_gl.la
|
||||
else
|
||||
RENDERER_GL =
|
||||
endif
|
||||
|
||||
if BUILD_SW
|
||||
RENDERER_SW = libQFrenderer_sw.la
|
||||
else
|
||||
RENDERER_SW =
|
||||
endif
|
||||
|
||||
lib_LTLIBRARIES = $(RENDERER_GL) $(RENDERER_SW)
|
||||
|
||||
common_SOURCES = r_cvar.c r_efrag.c r_ent.c r_graph.c r_main.c
|
||||
|
||||
libQFrenderer_gl_la_LDFLAGS = -version-info 1:0:0
|
||||
libQFrenderer_gl_la_LIBADD = gl/libgl.la
|
||||
libQFrenderer_gl_la_SOURCES = $(common_SOURCES)
|
||||
libQFrenderer_gl_la_DEPENDENCIES = gl/libgl.la
|
||||
|
||||
libQFrenderer_sw_la_LDFLAGS = -version-info 1:0:0
|
||||
libQFrenderer_sw_la_LIBADD = sw/libsw.la
|
||||
libQFrenderer_sw_la_SOURCES = $(common_SOURCES)
|
||||
libQFrenderer_sw_la_DEPENDENCIES = sw/libsw.la
|
||||
|
||||
LIBLIST = libQFrenderer_gl.la libQFrenderer_sw.la
|
9
libs/video/renderer/gl/.gitignore
vendored
Normal file
9
libs/video/renderer/gl/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.la
|
||||
*.lo
|
||||
.deps
|
||||
.libs
|
||||
.vimrc
|
||||
Makefile
|
||||
Makefile.in
|
||||
fbset_modes_y.[ch]
|
||||
fbset_modes_l.c
|
14
libs/video/renderer/gl/Makefile.am
Normal file
14
libs/video/renderer/gl/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
|||
INCLUDES= -I$(top_srcdir)/include
|
||||
|
||||
if BUILD_GL
|
||||
GL = libgl.la
|
||||
else
|
||||
GL =
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = $(GL)
|
||||
|
||||
libgl_la_LDFLAGS = -version-info 1:0:0
|
||||
libgl_la_SOURCES = gl_draw.c gl_dyn_fires.c gl_dyn_textures.c gl_graph.c \
|
||||
gl_rlight.c gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_skin.c \
|
||||
gl_sky.c gl_sky_clip.c gl_textures.c gl_warp.c noisetextures.c
|
|
@ -52,7 +52,6 @@
|
|||
#include "QF/tga.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "host.h"
|
||||
#include "r_cvar.h"
|
||||
#include "r_local.h"
|
||||
#include "sbar.h"
|
||||
|
@ -232,7 +231,7 @@ SCR_CheckDrawCenterString (int swap)
|
|||
if (scr_center_lines > scr_erase_lines)
|
||||
scr_erase_lines = scr_center_lines;
|
||||
|
||||
scr_centertime_off -= host_frametime;
|
||||
scr_centertime_off -= r_frametime;
|
||||
|
||||
if (scr_centertime_off <= 0 && !r_force_fullscreen /*FIXME better test*/)
|
||||
return;
|
||||
|
@ -400,7 +399,7 @@ SCR_DrawTurtle (int swap)
|
|||
if (!scr_showturtle->int_val)
|
||||
return;
|
||||
|
||||
if (host_frametime < 0.1) {
|
||||
if (r_frametime < 0.1) {
|
||||
count = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -523,12 +522,12 @@ SCR_SetUpToDrawConsole (void)
|
|||
scr_conlines = 0; // none visible
|
||||
|
||||
if (scr_conlines < scr_con_current) {
|
||||
scr_con_current -= scr_conspeed->value * host_frametime;
|
||||
scr_con_current -= scr_conspeed->value * r_frametime;
|
||||
if (scr_conlines > scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
|
||||
} else if (scr_conlines > scr_con_current) {
|
||||
scr_con_current += scr_conspeed->value * host_frametime;
|
||||
scr_con_current += scr_conspeed->value * r_frametime;
|
||||
if (scr_conlines < scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
}
|
130
libs/video/renderer/gl/noisetextures.c
Normal file
130
libs/video/renderer/gl/noisetextures.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
noisetextures.c
|
||||
|
||||
Noise texture generators
|
||||
|
||||
noise_plasma
|
||||
Copyright (C) 2001 Ragnvald `Despair` Maartmann-Moe IV.
|
||||
|
||||
noise_diamondsquare (originally fractalnoise)
|
||||
Copyright (C) 2000 Forest `LordHavoc` Hale.
|
||||
|
||||
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/mathlib.h"
|
||||
|
||||
void
|
||||
noise_diamondsquare (unsigned char *noise, int size)
|
||||
{
|
||||
int x, y, g, g2, amplitude, min, max, size1 = size - 1;
|
||||
int *noisebuf;
|
||||
|
||||
#define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
|
||||
noisebuf = calloc (size * size, sizeof (int));
|
||||
|
||||
amplitude = 32767;
|
||||
g2 = size;
|
||||
n (0, 0) = 0;
|
||||
for (; (g = g2 >> 1) >= 1; g2 >>= 1) {
|
||||
// subdivide, diamond-square algorythm (really this has little
|
||||
// to do with squares)
|
||||
// diamond
|
||||
for (y = 0; y < size; y += g2)
|
||||
for (x = 0; x < size; x += g2)
|
||||
n (x + g, y + g) =
|
||||
(n (x, y) + n (x + g2, y) + n (x, y + g2) +
|
||||
n (x + g2, y + g2)) >> 2;
|
||||
// square
|
||||
for (y = 0; y < size; y += g2)
|
||||
for (x = 0; x < size; x += g2) {
|
||||
n (x + g, y) =
|
||||
(n (x, y) + n (x + g2, y) + n (x + g, y - g) +
|
||||
n (x + g, y + g)) >> 2;
|
||||
n (x, y + g) =
|
||||
(n (x, y) + n (x, y + g2) + n (x - g, y + g) +
|
||||
n (x + g, y + g)) >> 2;
|
||||
}
|
||||
// Brownian motion ( at every smaller level, random behavior )
|
||||
amplitude >>= 1;
|
||||
for (y = 0; y < size; y += g)
|
||||
for (x = 0; x < size; x += g)
|
||||
n (x, y) += (rand () & amplitude);
|
||||
}
|
||||
// find range of noise values
|
||||
min = max = 0;
|
||||
for (y = 0; y < size; y++)
|
||||
for (x = 0; x < size; x++) {
|
||||
if (n (x, y) < min)
|
||||
min = n (x, y);
|
||||
if (n (x, y) > max)
|
||||
max = n (x, y);
|
||||
}
|
||||
max -= min;
|
||||
// normalize noise and copy to output
|
||||
for (y = 0; y < size; y++)
|
||||
for (x = 0; x < size; x++)
|
||||
*noise++ = (n (x, y) - min) * 255 / max;
|
||||
free (noisebuf);
|
||||
#undef n
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
noise_plasma (unsigned char *noise, int size)
|
||||
{
|
||||
int a, b, c, d, i, j, k;
|
||||
|
||||
if (128 >= size)
|
||||
d = 64 / size;
|
||||
else
|
||||
d = -size / 64;
|
||||
|
||||
memset(noise, 128, sizeof (*noise));
|
||||
|
||||
for (i=size; i > 0; i/=2) {
|
||||
for (j=0; j < size; j+=i) {
|
||||
for (k=0; k < size; k+=i) {
|
||||
if (d>=0)
|
||||
c = i * d;
|
||||
else
|
||||
c = -i / d;
|
||||
|
||||
c=lhrandom(-c, c);
|
||||
|
||||
for (a=j; a < j+i; a++)
|
||||
for (b=k; b < k+i; b++)
|
||||
noise[a*size+b] += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ qboolean r_inhibit_viewmodel;
|
|||
qboolean r_force_fullscreen;
|
||||
qboolean r_paused;
|
||||
double r_realtime;
|
||||
double r_frametime;
|
||||
dlight_t r_dlights[MAX_DLIGHTS];
|
||||
entity_t *r_view_model;
|
||||
entity_t *r_player_entity;
|
9
libs/video/renderer/sw/.gitignore
vendored
Normal file
9
libs/video/renderer/sw/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.la
|
||||
*.lo
|
||||
.deps
|
||||
.libs
|
||||
.vimrc
|
||||
Makefile
|
||||
Makefile.in
|
||||
fbset_modes_y.[ch]
|
||||
fbset_modes_l.c
|
19
libs/video/renderer/sw/Makefile.am
Normal file
19
libs/video/renderer/sw/Makefile.am
Normal file
|
@ -0,0 +1,19 @@
|
|||
INCLUDES= -I$(top_srcdir)/include
|
||||
|
||||
if BUILD_SW
|
||||
SW = libsw.la
|
||||
else
|
||||
SW =
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = $(SW)
|
||||
|
||||
libsw_la_LDFLAGS = -version-info 1:0:0
|
||||
libsw_la_SOURCES = d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \
|
||||
d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c draw.c screen.c \
|
||||
sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c sw_rdraw.c sw_redge.c \
|
||||
sw_rlight.c sw_rmain.c sw_rmisc.c sw_rsky.c sw_rsprite.c sw_rsurf.c \
|
||||
sw_skin.c \
|
||||
d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S d_spr8.S \
|
||||
d_varsa.S surf16.S surf8.S sw_raclipa.S sw_raliasa.S sw_rdrawa.S \
|
||||
sw_redgea.S sw_rvarsa.S
|
|
@ -32,11 +32,11 @@
|
|||
|
||||
#include "QF/compat.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_cvar.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "host.h"
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
// all global and static refresh variables are collected in a contiguous block
|
||||
// to avoid cache conflicts.
|
|
@ -42,7 +42,6 @@
|
|||
#include "QF/sound.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "d_iface.h"
|
||||
#include "r_cvar.h"
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
gl_screen.c
|
||||
screen.c
|
||||
|
||||
master for refresh, status bar, console, chat, notify, etc
|
||||
|
||||
|
@ -44,15 +44,14 @@
|
|||
#include "QF/draw.h"
|
||||
#include "QF/keys.h"
|
||||
#include "QF/pcx.h"
|
||||
#include "QF/quakefs.h" // MAX_OSPATH
|
||||
#include "QF/render.h" // r_refdef
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/screen.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/texture.h"
|
||||
#include "QF/tga.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "host.h"
|
||||
#include "d_iface.h"
|
||||
#include "r_cvar.h"
|
||||
#include "r_local.h"
|
||||
#include "sbar.h"
|
||||
|
@ -87,28 +86,24 @@ xblited, but sync draw can just ignore it.
|
|||
sync
|
||||
draw
|
||||
|
||||
CenterPrint ()
|
||||
SlowPrint ()
|
||||
Screen_Update ();
|
||||
Con_Printf ();
|
||||
CenterPrint ()
|
||||
SlowPrint ()
|
||||
Screen_Update ();
|
||||
Con_Printf ();
|
||||
|
||||
net
|
||||
turn off messages option
|
||||
|
||||
the refresh is allways rendered, unless the console is full screen
|
||||
the refresh is always rendered, unless the console is full screen
|
||||
|
||||
|
||||
console is:
|
||||
notify lines
|
||||
half
|
||||
full
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int glx, gly, glwidth, glheight;
|
||||
|
||||
// only the refresh window will be updated unless these variables are flagged
|
||||
int scr_copytop;
|
||||
int scr_copyeverything;
|
||||
|
@ -134,10 +129,12 @@ extern int sb_lines;
|
|||
|
||||
viddef_t vid; // global video state
|
||||
|
||||
vrect_t *pconupdate;
|
||||
vrect_t scr_vrect;
|
||||
|
||||
qboolean scr_disabled_for_loading;
|
||||
float scr_disabled_time;
|
||||
|
||||
qboolean scr_skipupdate;
|
||||
|
||||
qboolean block_drawing;
|
||||
|
||||
|
@ -158,8 +155,8 @@ int scr_erase_center;
|
|||
/*
|
||||
SCR_CenterPrint
|
||||
|
||||
Called for important messages that should stay in the center of the screen
|
||||
for a few moments
|
||||
Called for important messages that should stay in the center of the
|
||||
screen for a few moments
|
||||
*/
|
||||
void
|
||||
SCR_CenterPrint (char *str)
|
||||
|
@ -188,7 +185,7 @@ SCR_DrawCenterString (void)
|
|||
int remaining;
|
||||
|
||||
// the finale prints the characters one at a time
|
||||
if (r_force_fullscreen /*FIXME better test*/)
|
||||
if (r_force_fullscreen /*FIXME*/)
|
||||
remaining = scr_printspeed->value * (r_realtime - scr_centertime_start);
|
||||
else
|
||||
remaining = 9999;
|
||||
|
@ -232,9 +229,9 @@ SCR_CheckDrawCenterString (int swap)
|
|||
if (scr_center_lines > scr_erase_lines)
|
||||
scr_erase_lines = scr_center_lines;
|
||||
|
||||
scr_centertime_off -= host_frametime;
|
||||
scr_centertime_off -= r_frametime;
|
||||
|
||||
if (scr_centertime_off <= 0 && !r_force_fullscreen /*FIXME better test*/)
|
||||
if (scr_centertime_off <= 0 && !r_force_fullscreen /*FIXME*/)
|
||||
return;
|
||||
if (key_dest != key_game)
|
||||
return;
|
||||
|
@ -243,6 +240,9 @@ SCR_CheckDrawCenterString (int swap)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
float
|
||||
CalcFov (float fov_x, float width, float height)
|
||||
{
|
||||
|
@ -271,6 +271,7 @@ CalcFov (float fov_x, float width, float height)
|
|||
static void
|
||||
SCR_CalcRefdef (void)
|
||||
{
|
||||
vrect_t vrect;
|
||||
float size;
|
||||
int h;
|
||||
qboolean full = false;
|
||||
|
@ -281,6 +282,8 @@ SCR_CalcRefdef (void)
|
|||
// force the status bar to redraw
|
||||
Sbar_Changed ();
|
||||
|
||||
//========================================
|
||||
|
||||
// bound viewsize
|
||||
Cvar_SetValue (scr_viewsize, bound (30, scr_viewsize->int_val, 120));
|
||||
|
||||
|
@ -301,7 +304,7 @@ SCR_CalcRefdef (void)
|
|||
size = scr_viewsize->int_val;
|
||||
}
|
||||
// intermission is always full screen
|
||||
if (r_force_fullscreen /*FIXME better test*/) {
|
||||
if (r_force_fullscreen /*FIXME*/) {
|
||||
full = true;
|
||||
size = 100.0;
|
||||
sb_lines = 0;
|
||||
|
@ -330,6 +333,23 @@ SCR_CalcRefdef (void)
|
|||
CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
|
||||
|
||||
scr_vrect = r_refdef.vrect;
|
||||
|
||||
// these calculations mirror those in R_Init() for r_refdef, but take no
|
||||
// account of water warping
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
|
||||
R_SetVrect (&vrect, &scr_vrect, r_lineadj);
|
||||
|
||||
// guard against going from one mode to another that's less than half the
|
||||
// vertical resolution
|
||||
if (scr_con_current > vid.height)
|
||||
scr_con_current = vid.height;
|
||||
|
||||
// notify the refresh of the change
|
||||
R_ViewChanged (&vrect, r_lineadj, vid.aspect);
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,15 +381,18 @@ SCR_SizeDown_f (void)
|
|||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
void
|
||||
SCR_Init (void)
|
||||
{
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommand ("screenshot", SCR_ScreenShot_f, "Take a screenshot, saves as qfxxx.tga in the current directory");
|
||||
Cmd_AddCommand ("sizeup", SCR_SizeUp_f, "Increases the screen size");
|
||||
Cmd_AddCommand ("sizedown", SCR_SizeDown_f, "Decreases the screen size");
|
||||
Cmd_AddCommand ("screenshot", SCR_ScreenShot_f, "Take a screenshot and write it as qfxxx.tga in the current directory");
|
||||
Cmd_AddCommand ("sizeup", SCR_SizeUp_f, "Increase the size of the screen");
|
||||
Cmd_AddCommand ("sizedown", SCR_SizeDown_f, "Decrease the size of the screen");
|
||||
|
||||
scr_ram = Draw_PicFromWad ("ram");
|
||||
scr_net = Draw_PicFromWad ("net");
|
||||
|
@ -400,7 +423,7 @@ SCR_DrawTurtle (int swap)
|
|||
if (!scr_showturtle->int_val)
|
||||
return;
|
||||
|
||||
if (host_frametime < 0.1) {
|
||||
if (r_frametime < 0.1) {
|
||||
count = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -413,8 +436,8 @@ SCR_DrawTurtle (int swap)
|
|||
}
|
||||
|
||||
|
||||
extern cvar_t *show_time;
|
||||
extern cvar_t *show_fps;
|
||||
extern cvar_t *show_time;
|
||||
|
||||
void
|
||||
SCR_DrawFPS (int swap)
|
||||
|
@ -436,9 +459,9 @@ SCR_DrawFPS (int swap)
|
|||
lastframetime = t;
|
||||
}
|
||||
snprintf (st, sizeof (st), "%3d FPS", lastfps);
|
||||
|
||||
// FIXME! This is evil. -- Deek
|
||||
// calculate the location of the clock
|
||||
/* Misty: New trick! (for me) the ? makes this work like a if then else -
|
||||
IE: if cl_hudswap->int_val is not null, do first case, else (else is a
|
||||
: here) do second case. Deek taught me this trick */
|
||||
if (show_time->int_val <= 0) {
|
||||
i = 8;
|
||||
} else if (show_time->int_val == 1) {
|
||||
|
@ -446,9 +469,8 @@ SCR_DrawFPS (int swap)
|
|||
} else {
|
||||
i = 80;
|
||||
}
|
||||
|
||||
x = swap ? vid.width - ((strlen (st) * 8) + i) : i;
|
||||
y = vid.height - sb_lines - 8;
|
||||
y = vid.height - (sb_lines + 8);
|
||||
Draw_String8 (x, y, st);
|
||||
}
|
||||
|
||||
|
@ -457,7 +479,7 @@ SCR_DrawFPS (int swap)
|
|||
SCR_DrawTime
|
||||
|
||||
Draw a clock on the screen
|
||||
Written by Misty, rewritten by Deek.
|
||||
Written by Misty, rewritten by Deek
|
||||
*/
|
||||
void
|
||||
SCR_DrawTime (int swap)
|
||||
|
@ -482,9 +504,9 @@ SCR_DrawTime (int swap)
|
|||
} else if (show_time->int_val >= 2) { // US AM/PM display
|
||||
timefmt = "%l:%M %P";
|
||||
}
|
||||
strftime (st, sizeof (st), timefmt, local);
|
||||
|
||||
// Print it at far left/right of screen
|
||||
// Print it next to the fps meter
|
||||
strftime (st, sizeof (st), timefmt, local);
|
||||
x = swap ? (vid.width - ((strlen (st) * 8) + 8)) : 8;
|
||||
y = vid.height - (sb_lines + 8);
|
||||
Draw_String8 (x, y, st);
|
||||
|
@ -508,6 +530,9 @@ SCR_DrawPause (int swap)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
void
|
||||
SCR_SetUpToDrawConsole (void)
|
||||
{
|
||||
|
@ -523,12 +548,12 @@ SCR_SetUpToDrawConsole (void)
|
|||
scr_conlines = 0; // none visible
|
||||
|
||||
if (scr_conlines < scr_con_current) {
|
||||
scr_con_current -= scr_conspeed->value * host_frametime;
|
||||
scr_con_current -= scr_conspeed->value * r_frametime;
|
||||
if (scr_conlines > scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
|
||||
} else if (scr_conlines > scr_con_current) {
|
||||
scr_con_current += scr_conspeed->value * host_frametime;
|
||||
scr_con_current += scr_conspeed->value * r_frametime;
|
||||
if (scr_conlines < scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
}
|
||||
|
@ -572,12 +597,8 @@ SCR_ScreenShot (int width, int height)
|
|||
float fracw, frach;
|
||||
tex_t *tex;
|
||||
|
||||
tex = Hunk_TempAlloc (sizeof (tex_t) + vid.width * vid.height * 3);
|
||||
if (!tex)
|
||||
return 0;
|
||||
|
||||
glReadPixels (glx, gly, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE,
|
||||
tex->data + vid.width * vid.height);
|
||||
// enable direct drawing of console to back buffer
|
||||
D_EnableBackBufferAccess ();
|
||||
|
||||
w = (vid.width < width) ? vid.width : width;
|
||||
h = (vid.height < height) ? vid.height : height;
|
||||
|
@ -585,8 +606,12 @@ SCR_ScreenShot (int width, int height)
|
|||
fracw = (float) vid.width / (float) w;
|
||||
frach = (float) vid.height / (float) h;
|
||||
|
||||
tex = Hunk_TempAlloc (sizeof (tex_t) + w * h);
|
||||
if (!tex)
|
||||
return 0;
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
dest = tex->data + (w * 3 * y);
|
||||
dest = tex->data + (w * y);
|
||||
|
||||
for (x = 0; x < w; x++) {
|
||||
r = g = b = 0;
|
||||
|
@ -602,33 +627,23 @@ SCR_ScreenShot (int width, int height)
|
|||
|
||||
count = 0;
|
||||
for ( /* */ ; dy < dey; dy++) {
|
||||
src = tex->data + (vid.width * 3 * dy) + dx * 3;
|
||||
src = vid.buffer + (vid.rowbytes * dy) + dx;
|
||||
for (nx = dx; nx < dex; nx++) {
|
||||
r += *src++;
|
||||
g += *src++;
|
||||
b += *src++;
|
||||
r += vid_basepal[*src * 3];
|
||||
g += vid_basepal[*src * 3 + 1];
|
||||
b += vid_basepal[*src * 3 + 2];
|
||||
src++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
r /= count;
|
||||
g /= count;
|
||||
b /= count;
|
||||
*dest++ = r;
|
||||
*dest++ = b;
|
||||
*dest++ = g;
|
||||
}
|
||||
}
|
||||
|
||||
// convert to eight bit
|
||||
for (y = 0; y < h; y++) {
|
||||
src = tex->data + (w * 3 * y);
|
||||
dest = tex->data + (w * y);
|
||||
|
||||
for (x = 0; x < w; x++) {
|
||||
*dest++ = MipColor (src[0], src[1], src[2]);
|
||||
src += 3;
|
||||
*dest++ = MipColor (r, g, b);
|
||||
}
|
||||
}
|
||||
// for adapters that can't stay mapped in for linear writes all the time
|
||||
D_DisableBackBufferAccess ();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
@ -636,27 +651,34 @@ SCR_ScreenShot (int width, int height)
|
|||
void
|
||||
SCR_ScreenShot_f (void)
|
||||
{
|
||||
byte *buffer;
|
||||
char pcxname[MAX_OSPATH];
|
||||
pcx_t *pcx;
|
||||
int pcx_len;
|
||||
|
||||
//
|
||||
// find a file name to save it to
|
||||
//
|
||||
if (!COM_NextFilename (pcxname, "qf", ".tga")) {
|
||||
Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
|
||||
if (!COM_NextFilename (pcxname, "qf", ".pcx")) {
|
||||
Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
|
||||
return;
|
||||
}
|
||||
buffer = malloc (glwidth * glheight * 3);
|
||||
glReadPixels (glx, gly, glwidth, glheight, GL_BGR_EXT, GL_UNSIGNED_BYTE,
|
||||
buffer);
|
||||
WriteTGAfile (pcxname, buffer, glwidth, glheight);
|
||||
free (buffer);
|
||||
|
||||
// enable direct drawing of console to back buffer
|
||||
D_EnableBackBufferAccess ();
|
||||
|
||||
// save the pcx file
|
||||
pcx = EncodePCX (vid.buffer, vid.width, vid.height, vid.rowbytes,
|
||||
vid_basepal, false, &pcx_len);
|
||||
COM_WriteFile (pcxname, pcx, pcx_len);
|
||||
|
||||
|
||||
// for adapters that can't stay mapped in for linear writes all the time
|
||||
D_DisableBackBufferAccess ();
|
||||
|
||||
Con_Printf ("Wrote %s\n", pcxname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find closest color in the palette for named color
|
||||
Find closest color in the palette for named color
|
||||
*/
|
||||
int
|
||||
MipColor (int r, int g, int b)
|
||||
|
@ -692,7 +714,7 @@ MipColor (int r, int g, int b)
|
|||
}
|
||||
|
||||
|
||||
// in gl_draw.c
|
||||
// in draw.c
|
||||
extern byte *draw_chars; // 8*8 graphic characters
|
||||
|
||||
void
|
||||
|
@ -716,7 +738,7 @@ SCR_DrawCharToSnap (int num, byte * dest, int width)
|
|||
else
|
||||
dest[x] = 98;
|
||||
source += 128;
|
||||
dest -= width;
|
||||
dest += width;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -728,7 +750,7 @@ SCR_DrawStringToSnap (const char *s, tex_t *tex, int x, int y)
|
|||
byte *buf = tex->data;
|
||||
byte *dest;
|
||||
const unsigned char *p;
|
||||
int width = tex->width;
|
||||
int width = tex->width;
|
||||
|
||||
dest = buf + ((y * width) + x);
|
||||
|
||||
|
@ -740,6 +762,9 @@ SCR_DrawStringToSnap (const char *s, tex_t *tex, int x, int y)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
char *scr_notifystring;
|
||||
|
||||
void
|
||||
|
@ -775,39 +800,9 @@ SCR_DrawNotifyString (void)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
SCR_TileClear (void)
|
||||
{
|
||||
if (r_refdef.vrect.x > 0) {
|
||||
// left
|
||||
Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines);
|
||||
// right
|
||||
Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0,
|
||||
vid.width - r_refdef.vrect.x + r_refdef.vrect.width,
|
||||
vid.height - sb_lines);
|
||||
}
|
||||
if (r_refdef.vrect.y > 0) {
|
||||
// top
|
||||
Draw_TileClear (r_refdef.vrect.x, 0,
|
||||
r_refdef.vrect.x + r_refdef.vrect.width,
|
||||
r_refdef.vrect.y);
|
||||
// bottom
|
||||
Draw_TileClear (r_refdef.vrect.x,
|
||||
r_refdef.vrect.y + r_refdef.vrect.height,
|
||||
r_refdef.vrect.width,
|
||||
vid.height - sb_lines -
|
||||
(r_refdef.vrect.height + r_refdef.vrect.y));
|
||||
}
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
|
||||
extern void R_ForceLightUpdate (void);
|
||||
|
||||
int oldviewsize = 0;
|
||||
unsigned char lighthalf_v[3];
|
||||
qboolean lighthalf;
|
||||
extern cvar_t *gl_lightmode;
|
||||
|
||||
/*
|
||||
SCR_UpdateScreen
|
||||
|
||||
|
@ -820,66 +815,84 @@ extern cvar_t *gl_lightmode;
|
|||
void
|
||||
SCR_UpdateScreen (double realtime, SCR_Func *scr_funcs, int swap)
|
||||
{
|
||||
double time1 = 0, time2;
|
||||
float f;
|
||||
static int oldscr_viewsize;
|
||||
vrect_t vrect;
|
||||
|
||||
if (block_drawing)
|
||||
if (scr_skipupdate || block_drawing)
|
||||
return;
|
||||
|
||||
r_realtime = realtime;
|
||||
if (scr_disabled_for_loading)
|
||||
return;
|
||||
|
||||
vid.numpages = 2 + gl_triplebuffer->int_val;
|
||||
#ifdef _WIN32
|
||||
{ // don't suck up any cpu if minimized
|
||||
extern qboolean Minimized;
|
||||
|
||||
if (Minimized)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
r_realtime = realtime;
|
||||
|
||||
scr_copytop = 0;
|
||||
scr_copyeverything = 0;
|
||||
|
||||
if (scr_disabled_for_loading) {
|
||||
if (r_realtime - scr_disabled_time > 60) {
|
||||
scr_disabled_for_loading = false;
|
||||
Con_Printf ("load failed.\n");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (!scr_initialized || !con_initialized)
|
||||
return; // not initialized yet
|
||||
|
||||
if (scr_viewsize->int_val != oldscr_viewsize) {
|
||||
oldscr_viewsize = scr_viewsize->int_val;
|
||||
vid.recalc_refdef = 1;
|
||||
}
|
||||
|
||||
if (!scr_initialized || !con_initialized) // not initialized yet
|
||||
return;
|
||||
|
||||
if (oldviewsize != scr_viewsize->int_val) {
|
||||
oldviewsize = scr_viewsize->int_val;
|
||||
//
|
||||
// check for vid changes
|
||||
//
|
||||
if (oldfov != scr_fov->int_val) {
|
||||
oldfov = scr_fov->int_val;
|
||||
vid.recalc_refdef = true;
|
||||
}
|
||||
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
|
||||
if (r_speeds->int_val) {
|
||||
time1 = Sys_DoubleTime ();
|
||||
c_brush_polys = 0;
|
||||
c_alias_polys = 0;
|
||||
}
|
||||
|
||||
if (oldfov != scr_fov->value) { // determine size of refresh window
|
||||
oldfov = scr_fov->value;
|
||||
if (oldscreensize != scr_viewsize->int_val) {
|
||||
oldscreensize = scr_viewsize->int_val;
|
||||
vid.recalc_refdef = true;
|
||||
}
|
||||
|
||||
if (vid.recalc_refdef)
|
||||
if (vid.recalc_refdef) {
|
||||
// something changed, so reorder the screen
|
||||
SCR_CalcRefdef ();
|
||||
|
||||
}
|
||||
//
|
||||
// do 3D refresh drawing, and then update the screen
|
||||
//
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing
|
||||
// directly
|
||||
|
||||
if (scr_fullupdate++ < vid.numpages) { // clear the entire screen
|
||||
scr_copyeverything = 1;
|
||||
Draw_TileClear (0, 0, vid.width, vid.height);
|
||||
Sbar_Changed ();
|
||||
}
|
||||
|
||||
pconupdate = NULL;
|
||||
|
||||
|
||||
SCR_SetUpToDrawConsole ();
|
||||
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay
|
||||
// mapped in
|
||||
// for linear writes all the time
|
||||
|
||||
VID_LockBuffer ();
|
||||
V_RenderView ();
|
||||
VID_UnlockBuffer ();
|
||||
|
||||
GL_Set2D ();
|
||||
D_EnableBackBufferAccess (); // of all overlay stuff if drawing
|
||||
// directly
|
||||
|
||||
// draw any areas not covered by the refresh
|
||||
SCR_TileClear ();
|
||||
|
||||
if (r_force_fullscreen /*FIXME better test*/ == 1 && key_dest == key_game) {
|
||||
if (r_force_fullscreen /*FIXME*/ == 1 && key_dest == key_game) {
|
||||
Sbar_IntermissionOverlay ();
|
||||
} else if (r_force_fullscreen /*FIXME better test*/ == 2 && key_dest == key_game) {
|
||||
} else if (r_force_fullscreen /*FIXME*/ == 2 && key_dest == key_game) {
|
||||
Sbar_FinaleOverlay ();
|
||||
SCR_CheckDrawCenterString (swap);
|
||||
} else {
|
||||
|
@ -889,59 +902,42 @@ SCR_UpdateScreen (double realtime, SCR_Func *scr_funcs, int swap)
|
|||
}
|
||||
}
|
||||
|
||||
// also makes polyblend apply to whole screen
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
|
||||
if (lighthalf) { // LordHavoc: render was done at half brightness
|
||||
f = 2;
|
||||
} else {
|
||||
f = 1;
|
||||
D_DisableBackBufferAccess (); // for adapters that can't stay
|
||||
// mapped in
|
||||
// for linear writes all the time
|
||||
if (pconupdate) {
|
||||
D_UpdateRects (pconupdate);
|
||||
}
|
||||
|
||||
if (f >= 1.002) { // Make sure we don't get bit by roundoff errors
|
||||
glBlendFunc (GL_DST_COLOR, GL_ONE);
|
||||
glBegin (GL_QUADS);
|
||||
while (f >= 1.002) { // precision
|
||||
if (f >= 2)
|
||||
glColor3f (1, 1, 1);
|
||||
else
|
||||
glColor3f (f - 1, f - 1, f - 1);
|
||||
glVertex2f (0, 0);
|
||||
glVertex2f (vid.width, 0);
|
||||
glVertex2f (vid.width, vid.height);
|
||||
glVertex2f (0, vid.height);
|
||||
f *= 0.5;
|
||||
}
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (v_blend[3]) {
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glColor4fv (v_blend);
|
||||
glVertex2f (0, 0);
|
||||
glVertex2f (vid.width, 0);
|
||||
glVertex2f (vid.width, vid.height);
|
||||
glVertex2f (0, vid.height);
|
||||
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
||||
V_UpdatePalette ();
|
||||
|
||||
if (r_speeds->int_val) {
|
||||
// glFinish ();
|
||||
time2 = Sys_DoubleTime ();
|
||||
Con_Printf ("%3i ms %4i wpoly %4i epoly\n",
|
||||
(int) ((time2 - time1) * 1000), c_brush_polys,
|
||||
c_alias_polys);
|
||||
}
|
||||
//
|
||||
// update one of three areas
|
||||
//
|
||||
if (scr_copyeverything) {
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
glFinish ();
|
||||
GL_EndRendering ();
|
||||
VID_Update (&vrect);
|
||||
} else if (scr_copytop) {
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height - sb_lines;
|
||||
vrect.pnext = 0;
|
||||
|
||||
VID_Update (&vrect);
|
||||
} else {
|
||||
vrect.x = scr_vrect.x;
|
||||
vrect.y = scr_vrect.y;
|
||||
vrect.width = scr_vrect.width;
|
||||
vrect.height = scr_vrect.height;
|
||||
vrect.pnext = 0;
|
||||
|
||||
VID_Update (&vrect);
|
||||
}
|
||||
}
|
179
libs/video/renderer/sw/surf16.S
Normal file
179
libs/video/renderer/sw/surf16.S
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
surf16.S
|
||||
|
||||
x86 assembly-language 16 bpp surface block drawing code.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
k: .long 0
|
||||
loopentry: .long 0
|
||||
|
||||
.align 4
|
||||
blockjumptable16:
|
||||
.long LEnter2_16
|
||||
.long LEnter4_16
|
||||
.long 0, LEnter8_16
|
||||
.long 0, 0, 0, LEnter16_16
|
||||
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf16Start)
|
||||
C(R_Surf16Start):
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock16)
|
||||
C(R_DrawSurfaceBlock16):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl C(blocksize),%eax
|
||||
movl C(prowdestbase),%edi
|
||||
movl C(pbasesource),%esi
|
||||
movl C(sourcesstep),%ebx
|
||||
movl blockjumptable16-4(,%eax,2),%ecx
|
||||
movl %eax,k
|
||||
movl %ecx,loopentry
|
||||
movl C(lightleft),%edx
|
||||
movl C(lightright),%ebp
|
||||
|
||||
Lblockloop16:
|
||||
|
||||
subl %edx,%ebp
|
||||
movb C(blockdivshift),%cl
|
||||
sarl %cl,%ebp
|
||||
jns Lp1_16
|
||||
testl C(blockdivmask),%ebp
|
||||
jz Lp1_16
|
||||
incl %ebp
|
||||
Lp1_16:
|
||||
|
||||
subl %eax,%eax
|
||||
subl %ecx,%ecx // high words must be 0 in loop for addressing
|
||||
|
||||
jmp *loopentry
|
||||
|
||||
.align 4
|
||||
|
||||
#include "block16.h"
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(lightleft),%edx
|
||||
movl C(lightright),%ebp
|
||||
movl C(sourcetstep),%eax
|
||||
movl C(lightrightstep),%ecx
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
addl %eax,%esi
|
||||
addl %ecx,%ebp
|
||||
|
||||
movl C(lightleftstep),%eax
|
||||
movl C(surfrowbytes),%ecx
|
||||
|
||||
addl %eax,%edx
|
||||
addl %ecx,%edi
|
||||
|
||||
movl %esi,C(pbasesource)
|
||||
movl %ebp,C(lightright)
|
||||
movl k,%eax
|
||||
movl %edx,C(lightleft)
|
||||
decl %eax
|
||||
movl %edi,C(prowdestbase)
|
||||
movl %eax,k
|
||||
jnz Lblockloop16
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
.globl C(R_Surf16End)
|
||||
C(R_Surf16End):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Code patching routines
|
||||
//----------------------------------------------------------------------
|
||||
.data
|
||||
|
||||
.align 4
|
||||
LPatchTable16:
|
||||
.long LBPatch0-4
|
||||
.long LBPatch1-4
|
||||
.long LBPatch2-4
|
||||
.long LBPatch3-4
|
||||
.long LBPatch4-4
|
||||
.long LBPatch5-4
|
||||
.long LBPatch6-4
|
||||
.long LBPatch7-4
|
||||
.long LBPatch8-4
|
||||
.long LBPatch9-4
|
||||
.long LBPatch10-4
|
||||
.long LBPatch11-4
|
||||
.long LBPatch12-4
|
||||
.long LBPatch13-4
|
||||
.long LBPatch14-4
|
||||
.long LBPatch15-4
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf16Patch)
|
||||
C(R_Surf16Patch):
|
||||
pushl %ebx
|
||||
|
||||
movl C(colormap),%eax
|
||||
movl $LPatchTable16,%ebx
|
||||
movl $16,%ecx
|
||||
LPatchLoop16:
|
||||
movl (%ebx),%edx
|
||||
addl $4,%ebx
|
||||
movl %eax,(%edx)
|
||||
decl %ecx
|
||||
jnz LPatchLoop16
|
||||
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#endif // USE_INTEL_ASM
|
791
libs/video/renderer/sw/surf8.S
Normal file
791
libs/video/renderer/sw/surf8.S
Normal file
|
@ -0,0 +1,791 @@
|
|||
/*
|
||||
surf8.S
|
||||
|
||||
Intel x86 assembly-language 8bpp surface block drawing code
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
.data
|
||||
|
||||
sb_v: .long 0
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Start)
|
||||
C(R_Surf8Start):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 0
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip0)
|
||||
C(R_DrawSurfaceBlock8_mip0):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip0:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $4,%ecx
|
||||
orl $0xF0000000,%ebp
|
||||
|
||||
sarl $4,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip0:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 14(%esi),%cl
|
||||
|
||||
sarl $4,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 15(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch0:
|
||||
movb 13(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch1:
|
||||
movb 12(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch2:
|
||||
|
||||
movb 11(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch3:
|
||||
|
||||
movb 10(%esi),%cl
|
||||
movl %eax,12(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch4:
|
||||
movb 9(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch5:
|
||||
movb 8(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch6:
|
||||
|
||||
movb 7(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch7:
|
||||
|
||||
movb 6(%esi),%cl
|
||||
movl %eax,8(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch8:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch9:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch10:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch11:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch12:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch13:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch14:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch15:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
|
||||
addl C(sourcetstep),%esi
|
||||
addl C(surfrowbytes),%edi
|
||||
|
||||
addl C(lightrightstep),%edx
|
||||
addl C(lightdeltastep),%ebp
|
||||
|
||||
movl %edx,C(lightright)
|
||||
jc Lblockloop8_mip0
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip0
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip0:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip0
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 1
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip1)
|
||||
C(R_DrawSurfaceBlock8_mip1):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip1:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $3,%ecx
|
||||
orl $0x70000000,%ebp
|
||||
|
||||
sarl $3,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip1:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 6(%esi),%cl
|
||||
|
||||
sarl $3,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 7(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch22:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch23:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch24:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch25:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch26:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch27:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch28:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch29:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip1
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip1
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip1:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip1
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 2
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip2)
|
||||
C(R_DrawSurfaceBlock8_mip2):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip2:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $2,%ecx
|
||||
orl $0x30000000,%ebp
|
||||
|
||||
sarl $2,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip2:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 2(%esi),%cl
|
||||
|
||||
sarl $2,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 3(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch18:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch19:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch20:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch21:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip2
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip2
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip2:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip2
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 3
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip3)
|
||||
C(R_DrawSurfaceBlock8_mip3):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip3:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
movl %ebp,C(lightdelta)
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $1,%ecx
|
||||
|
||||
sarl $1,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
sarl $1,%ebp
|
||||
orl $0xF0000000,%ebx
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
movb 1(%esi),%bl
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movb %dh,%bh
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch16:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch17:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
movl C(lightdelta),%ebp
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %eax,%ebp
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
sarl $1,%ebp
|
||||
addl %eax,%edx
|
||||
|
||||
movb %dh,%bh
|
||||
movb 1(%esi),%bl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch30:
|
||||
movl C(sourcetstep),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch31:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(surfrowbytes),%ebp
|
||||
|
||||
addl %edx,%esi
|
||||
addl %ebp,%edi
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip3
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip3:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip3
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
.globl C(R_Surf8End)
|
||||
C(R_Surf8End):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Code patching routines
|
||||
//----------------------------------------------------------------------
|
||||
.data
|
||||
|
||||
.align 4
|
||||
LPatchTable8:
|
||||
.long LBPatch0-4
|
||||
.long LBPatch1-4
|
||||
.long LBPatch2-4
|
||||
.long LBPatch3-4
|
||||
.long LBPatch4-4
|
||||
.long LBPatch5-4
|
||||
.long LBPatch6-4
|
||||
.long LBPatch7-4
|
||||
.long LBPatch8-4
|
||||
.long LBPatch9-4
|
||||
.long LBPatch10-4
|
||||
.long LBPatch11-4
|
||||
.long LBPatch12-4
|
||||
.long LBPatch13-4
|
||||
.long LBPatch14-4
|
||||
.long LBPatch15-4
|
||||
.long LBPatch16-4
|
||||
.long LBPatch17-4
|
||||
.long LBPatch18-4
|
||||
.long LBPatch19-4
|
||||
.long LBPatch20-4
|
||||
.long LBPatch21-4
|
||||
.long LBPatch22-4
|
||||
.long LBPatch23-4
|
||||
.long LBPatch24-4
|
||||
.long LBPatch25-4
|
||||
.long LBPatch26-4
|
||||
.long LBPatch27-4
|
||||
.long LBPatch28-4
|
||||
.long LBPatch29-4
|
||||
.long LBPatch30-4
|
||||
.long LBPatch31-4
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Patch)
|
||||
C(R_Surf8Patch):
|
||||
pushl %ebx
|
||||
|
||||
movl C(colormap),%eax
|
||||
movl $LPatchTable8,%ebx
|
||||
movl $32,%ecx
|
||||
LPatchLoop8:
|
||||
movl (%ebx),%edx
|
||||
addl $4,%ebx
|
||||
movl %eax,(%edx)
|
||||
decl %ecx
|
||||
jnz LPatchLoop8
|
||||
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
#endif // USE_INTEL_ASM
|
|
@ -37,9 +37,7 @@
|
|||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "host.h"
|
||||
#include "r_local.h"
|
||||
#include "sbar.h"
|
||||
|
||||
void
|
||||
R_CheckVariables (void)
|
|
@ -41,9 +41,6 @@ EXTRA_PROGRAMS= nq-3dfx nq-fbdev nq-glx nq-mgl nq-sdl \
|
|||
noinst_LIBRARIES= libqfnet.a
|
||||
|
||||
math_ASM= cl_math.S
|
||||
soft_ASM= d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S d_spr8.S \
|
||||
d_varsa.S sw_raclipa.S sw_raliasa.S sw_rdrawa.S sw_redgea.S \
|
||||
sw_rvarsa.S surf16.S surf8.S
|
||||
common_ASM= sys_ia32.S worlda.S $(math_ASM)
|
||||
|
||||
common_SOURCES= game.c host_skin.c skin.c wad.c world.c com.c $(common_ASM)
|
||||
|
@ -74,7 +71,7 @@ client_LIB_DEPS= libqfnet.a $(qf_client_LIBS)
|
|||
|
||||
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_screen.c \
|
||||
cl_parse.c cl_tent.c \
|
||||
console.c keys.c sbar.c r_cvar.c r_efrag.c r_ent.c r_graph.c r_main.c \
|
||||
console.c keys.c sbar.c \
|
||||
r_part.c r_view.c nonintel.c locs.c pcx.c tga.c
|
||||
|
||||
server_SOURCES= host.c host_cmd.c pr_cmds.c sv_cvar.c sv_main.c \
|
||||
|
@ -86,66 +83,57 @@ combined_SOURCES= $(common_SOURCES) $(client_SOURCES) $(server_SOURCES) \
|
|||
# Software-rendering targets
|
||||
#
|
||||
# ... Common stuff
|
||||
soft_SOURCES= d_edge.c d_fill.c d_init.c d_modech.c d_part.c d_polyse.c \
|
||||
d_scan.c d_sky.c d_sprite.c d_surf.c d_vars.c d_zpoint.c \
|
||||
draw.c screen.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c \
|
||||
sw_rdraw.c \
|
||||
sw_redge.c sw_rlight.c sw_rmain.c sw_rmisc.c sw_rpart.c \
|
||||
sw_rsky.c sw_rsprite.c sw_rsurf.c sw_skin.c sw_view.c \
|
||||
$(soft_ASM)
|
||||
soft_SOURCES= sw_rpart.c sw_view.c
|
||||
|
||||
# ... Linux FBDev
|
||||
nq_fbdev_SOURCES= $(combined_SOURCES) $(soft_SOURCES)
|
||||
nq_fbdev_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIBS)
|
||||
nq_fbdev_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIB_DEPS)
|
||||
nq_fbdev_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIBS)
|
||||
nq_fbdev_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIB_DEPS)
|
||||
|
||||
# ... SciTech MGL
|
||||
nq_mgl_SOURCES= $(combined_SOURCES) $(soft_SOURCES)
|
||||
nq_mgl_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIBS) $(MGL_LIBS)
|
||||
nq_mgl_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIB_DEPS)
|
||||
nq_mgl_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIBS) $(MGL_LIBS)
|
||||
nq_mgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Sam Lantinga's Simple DirectMedia Layer, version 1.0 and higher
|
||||
nq_sdl_SOURCES= $(combined_SOURCES) $(soft_SOURCES)
|
||||
nq_sdl_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIBS) $(SDL_LIBS)
|
||||
nq_sdl_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIB_DEPS)
|
||||
nq_sdl_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIBS) $(SDL_LIBS)
|
||||
nq_sdl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Linux SVGAlib
|
||||
nq_svga_SOURCES= $(combined_SOURCES) $(soft_SOURCES)
|
||||
nq_svga_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIBS) $(SVGA_LIBS)
|
||||
nq_svga_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIB_DEPS)
|
||||
nq_svga_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIBS) $(SVGA_LIBS)
|
||||
nq_svga_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIB_DEPS)
|
||||
|
||||
# ... X11
|
||||
nq_x11_SOURCES= $(combined_SOURCES) $(soft_SOURCES)
|
||||
nq_x11_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB)
|
||||
nq_x11_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIB_DEPS)
|
||||
nq_x11_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB)
|
||||
nq_x11_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIB_DEPS)
|
||||
|
||||
|
||||
# OpenGL-using targets
|
||||
# ... Common stuff
|
||||
ogl_SOURCES= noisetextures.c gl_textures.c gl_draw.c gl_dyn_fires.c \
|
||||
gl_dyn_part.c gl_dyn_textures.c gl_graph.c gl_rlight.c \
|
||||
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_skin.c \
|
||||
gl_sky.c gl_sky_clip.c gl_view.c gl_warp.c
|
||||
ogl_SOURCES= gl_dyn_part.c gl_view.c
|
||||
|
||||
# ... 3Dfx Voodoo 1 and 2 SVGAlib-based console GL
|
||||
nq_3dfx_SOURCES= $(combined_SOURCES) $(ogl_SOURCES)
|
||||
nq_3dfx_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIBS) $(TDFXGL_LIBS) $(SVGA_LIBS) $(DL_LIBS)
|
||||
nq_3dfx_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIB_DEPS)
|
||||
nq_3dfx_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIBS) $(TDFXGL_LIBS) $(SVGA_LIBS) $(DL_LIBS)
|
||||
nq_3dfx_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIB_DEPS)
|
||||
|
||||
# ... OpenGL in X Window
|
||||
nq_glx_SOURCES= $(combined_SOURCES) $(ogl_SOURCES)
|
||||
nq_glx_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIBS) $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(DL_LIBS)
|
||||
nq_glx_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIB_DEPS)
|
||||
nq_glx_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIBS) $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(DL_LIBS)
|
||||
nq_glx_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Simple Directmedia Layer, version 1.1 and higher, in GL mode
|
||||
nq_sgl_SOURCES= $(combined_SOURCES) $(ogl_SOURCES)
|
||||
nq_sgl_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIBS) $(X_LIBS) $(SDL_LIBS) $(GLX_LIBS) $(DL_LIBS)
|
||||
nq_sgl_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIB_DEPS)
|
||||
nq_sgl_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIBS) $(X_LIBS) $(SDL_LIBS) $(GLX_LIBS) $(DL_LIBS)
|
||||
nq_sgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... SGI/Microsoft WGL (Windows OpenGL)
|
||||
nq_wgl_SOURCES= $(combined_SOURCES) $(ogl_SOURCES) conproc.c
|
||||
nq_wgl_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIBS) $(GLX_LIBS) -lgdi32 -lcomctl32 -lwinmm
|
||||
nq_wgl_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIB_DEPS)
|
||||
nq_wgl_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIBS) $(GLX_LIBS) -lgdi32 -lcomctl32 -lwinmm
|
||||
nq_wgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIB_DEPS)
|
||||
|
||||
# Dedicated Server
|
||||
ded_SOURCES= sys_unixd.c sv_ded.c
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
d_copy.S
|
||||
|
||||
x86 assembly-language screen copying code.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
.data
|
||||
|
||||
LCopyWidth: .long 0
|
||||
LBlockSrcStep: .long 0
|
||||
LBlockDestStep: .long 0
|
||||
LSrcDelta: .long 0
|
||||
LDestDelta: .long 0
|
||||
|
||||
#define bufptr 4+16
|
||||
|
||||
// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since
|
||||
// no Mode X mode is wider than 360, all the data should fit in the cache for
|
||||
// the passes for the next 3 planes
|
||||
|
||||
.text
|
||||
|
||||
.globl C(VGA_UpdatePlanarScreen)
|
||||
C(VGA_UpdatePlanarScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockSrcStep
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockDestStep
|
||||
|
||||
movl $0x3C4,%edx
|
||||
movb $2,%al
|
||||
outb %al,%dx // point the SC to the Map Mask
|
||||
incl %edx
|
||||
|
||||
movl bufptr(%esp),%esi
|
||||
movl C(VGA_pagebase),%edi
|
||||
movl C(VGA_height),%ebp
|
||||
shrl $1,%ebp
|
||||
|
||||
movl C(VGA_width),%ecx
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LSrcDelta
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $2,%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LDestDelta
|
||||
shrl $4,%ecx
|
||||
movl %ecx,LCopyWidth
|
||||
|
||||
LRowLoop:
|
||||
movb $1,%al
|
||||
|
||||
LPlaneLoop:
|
||||
outb %al,%dx
|
||||
movb $2,%ah
|
||||
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
LRowSetLoop:
|
||||
movl LCopyWidth,%ecx
|
||||
LColumnLoop:
|
||||
movb 12(%esi),%bh
|
||||
movb 8(%esi),%bl
|
||||
shll $16,%ebx
|
||||
movb 4(%esi),%bh
|
||||
movb (%esi),%bl
|
||||
movl %ebx,(%edi)
|
||||
addl $16,%esi
|
||||
addl $4,%edi
|
||||
decl %ecx
|
||||
jnz LColumnLoop
|
||||
|
||||
addl LDestDelta,%edi
|
||||
addl LSrcDelta,%esi
|
||||
decb %ah
|
||||
jnz LRowSetLoop
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
incl %esi
|
||||
|
||||
shlb $1,%al
|
||||
cmpb $16,%al
|
||||
jnz LPlaneLoop
|
||||
|
||||
subl $4,%esi
|
||||
addl LBlockSrcStep,%esi
|
||||
addl LBlockDestStep,%edi
|
||||
decl %ebp
|
||||
jnz LRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#define srcptr 4+16
|
||||
#define destptr 8+16
|
||||
#define width 12+16
|
||||
#define height 16+16
|
||||
#define srcrowbytes 20+16
|
||||
#define destrowbytes 24+16
|
||||
|
||||
.globl C(VGA_UpdateLinearScreen)
|
||||
C(VGA_UpdateLinearScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
cld
|
||||
movl srcptr(%esp),%esi
|
||||
movl destptr(%esp),%edi
|
||||
movl width(%esp),%ebx
|
||||
movl srcrowbytes(%esp),%eax
|
||||
subl %ebx,%eax
|
||||
movl destrowbytes(%esp),%edx
|
||||
subl %ebx,%edx
|
||||
shrl $2,%ebx
|
||||
movl height(%esp),%ebp
|
||||
LLRowLoop:
|
||||
movl %ebx,%ecx
|
||||
rep/movsl (%esi),(%edi)
|
||||
addl %eax,%esi
|
||||
addl %edx,%edi
|
||||
decl %ebp
|
||||
jnz LLRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
#endif /* USE_INTEL_ASM */
|
|
@ -1,422 +0,0 @@
|
|||
/*
|
||||
d_scan.c
|
||||
|
||||
Portable C scan-level rasterization code, all pixel depths.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "client.h"
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
unsigned char *r_turb_pbase, *r_turb_pdest;
|
||||
fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
|
||||
int *r_turb_turb;
|
||||
int r_turb_spancount;
|
||||
|
||||
void D_DrawTurbulent8Span (void);
|
||||
|
||||
|
||||
/*
|
||||
D_WarpScreen
|
||||
|
||||
this performs a slight compression of the screen at the same time as
|
||||
the sine warp, to keep the edges from wrapping
|
||||
*/
|
||||
void
|
||||
D_WarpScreen (void)
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
byte *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
byte **row;
|
||||
byte *rowptr[1024];
|
||||
int column[1280];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_vrect.width;
|
||||
hratio = h / (float) scr_vrect.height;
|
||||
|
||||
for (v = 0; v < scr_vrect.height + AMP2 * 2; v++) {
|
||||
rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
|
||||
(screenwidth * (int) ((float) v * hratio * h / (h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_vrect.width + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = intsintable + ((int) (cl.time * SPEED) & (CYCLE - 1));
|
||||
dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
|
||||
|
||||
for (v = 0; v < scr_vrect.height; v++, dest += vid.rowbytes) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_vrect.width; u += 4) {
|
||||
dest[u + 0] = row[turb[u + 0]][col[u + 0]];
|
||||
dest[u + 1] = row[turb[u + 1]][col[u + 1]];
|
||||
dest[u + 2] = row[turb[u + 2]][col[u + 2]];
|
||||
dest[u + 3] = row[turb[u + 3]][col[u + 3]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawTurbulent8Span (void)
|
||||
{
|
||||
int sturb, tturb;
|
||||
|
||||
do {
|
||||
sturb =
|
||||
((r_turb_s + r_turb_turb[(r_turb_t >> 16) & (CYCLE - 1)]) >> 16) &
|
||||
63;
|
||||
tturb =
|
||||
((r_turb_t + r_turb_turb[(r_turb_s >> 16) & (CYCLE - 1)]) >> 16) &
|
||||
63;
|
||||
*r_turb_pdest++ = *(r_turb_pbase + (tturb << 6) + sturb);
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
void
|
||||
Turbulent8 (espan_t *pspan)
|
||||
{
|
||||
int count;
|
||||
fixed16_t snext, tnext;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz16stepu, tdivz16stepu, zi16stepu;
|
||||
|
||||
r_turb_turb = sintable + ((int) (cl.time * SPEED) & (CYCLE - 1));
|
||||
|
||||
r_turb_sstep = 0; // keep compiler happy
|
||||
r_turb_tstep = 0; // ditto
|
||||
|
||||
r_turb_pbase = (unsigned char *) cacheblock;
|
||||
|
||||
sdivz16stepu = d_sdivzstepu * 16;
|
||||
tdivz16stepu = d_tdivzstepu * 16;
|
||||
zi16stepu = d_zistepu * 16;
|
||||
|
||||
do {
|
||||
r_turb_pdest = (unsigned char *) ((byte *) d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = d_sdivzorigin + dv * d_sdivzstepv + du * d_sdivzstepu;
|
||||
tdivz = d_tdivzorigin + dv * d_tdivzstepv + du * d_tdivzstepu;
|
||||
zi = d_ziorigin + dv * d_zistepv + du * d_zistepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
r_turb_s = (int) (sdivz * z) + sadjust;
|
||||
if (r_turb_s > bbextents)
|
||||
r_turb_s = bbextents;
|
||||
else if (r_turb_s < 0)
|
||||
r_turb_s = 0;
|
||||
|
||||
r_turb_t = (int) (tdivz * z) + tadjust;
|
||||
if (r_turb_t > bbextentt)
|
||||
r_turb_t = bbextentt;
|
||||
else if (r_turb_t < 0)
|
||||
r_turb_t = 0;
|
||||
|
||||
do {
|
||||
// calculate s and t at the far end of the span
|
||||
if (count >= 16)
|
||||
r_turb_spancount = 16;
|
||||
else
|
||||
r_turb_spancount = count;
|
||||
|
||||
count -= r_turb_spancount;
|
||||
|
||||
if (count) {
|
||||
// calculate s/z, t/z, zi->fixed s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
sdivz += sdivz16stepu;
|
||||
tdivz += tdivz16stepu;
|
||||
zi += zi16stepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 16)
|
||||
snext = 16; // prevent round-off error on <0
|
||||
// steps from
|
||||
// from causing overstepping & running off the
|
||||
// edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 16)
|
||||
tnext = 16; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
r_turb_sstep = (snext - r_turb_s) >> 4;
|
||||
r_turb_tstep = (tnext - r_turb_t) >> 4;
|
||||
} else {
|
||||
// calculate s/z, t/z, zi->fixed s and t at last pixel in
|
||||
// span (so can't step off polygon), clamp, calculate s and t
|
||||
// steps across span by division, biasing steps low so we
|
||||
// don't run off the texture
|
||||
spancountminus1 = (float) (r_turb_spancount - 1);
|
||||
sdivz += d_sdivzstepu * spancountminus1;
|
||||
tdivz += d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * spancountminus1;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 16)
|
||||
snext = 16; // prevent round-off error on <0 steps
|
||||
// from causing overstepping & running
|
||||
// off the edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 16)
|
||||
tnext = 16; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
if (r_turb_spancount > 1) {
|
||||
r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
|
||||
r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
r_turb_s = r_turb_s & ((CYCLE << 16) - 1);
|
||||
r_turb_t = r_turb_t & ((CYCLE << 16) - 1);
|
||||
|
||||
D_DrawTurbulent8Span ();
|
||||
|
||||
r_turb_s = snext;
|
||||
r_turb_t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawSpans8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount;
|
||||
unsigned char *pbase, *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
pbase = (unsigned char *) cacheblock;
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8;
|
||||
|
||||
do {
|
||||
pdest = (unsigned char *) ((byte *) d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = d_sdivzorigin + dv * d_sdivzstepv + du * d_sdivzstepu;
|
||||
tdivz = d_tdivzorigin + dv * d_tdivzstepv + du * d_tdivzstepu;
|
||||
zi = d_ziorigin + dv * d_zistepv + du * d_zistepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
s = (int) (sdivz * z) + sadjust;
|
||||
if (s > bbextents)
|
||||
s = bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int) (tdivz * z) + tadjust;
|
||||
if (t > bbextentt)
|
||||
t = bbextentt;
|
||||
else if (t < 0)
|
||||
t = 0;
|
||||
|
||||
do {
|
||||
// calculate s and t at the far end of the span
|
||||
if (count >= 8)
|
||||
spancount = 8;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count) {
|
||||
// calculate s/z, t/z, zi->fixed s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
sdivz += sdivz8stepu;
|
||||
tdivz += tdivz8stepu;
|
||||
zi += zi8stepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from
|
||||
// from causing overstepping & running off the
|
||||
// edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
} else {
|
||||
// calculate s/z, t/z, zi->fixed s and t at last pixel in span
|
||||
// (so can't step off polygon), clamp, calculate s and t steps
|
||||
// across span by division, biasing steps low so we don't run
|
||||
// off the texture
|
||||
spancountminus1 = (float) (spancount - 1);
|
||||
sdivz += d_sdivzstepu * spancountminus1;
|
||||
tdivz += d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * spancountminus1;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0 steps
|
||||
// from from causing overstepping &
|
||||
// running off the edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
if (spancount > 1) {
|
||||
sstep = (snext - s) / (spancount - 1);
|
||||
tstep = (tnext - t) / (spancount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
*pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawZSpans (espan_t *pspan)
|
||||
{
|
||||
int count, doublecount, izistep;
|
||||
int izi;
|
||||
short *pdest;
|
||||
unsigned int ltemp;
|
||||
double zi;
|
||||
float du, dv;
|
||||
|
||||
// FIXME: check for clamping/range problems
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial 1/z
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
zi = d_ziorigin + dv * d_zistepv + du * d_zistepu;
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izi = (int) (zi * 0x8000 * 0x10000);
|
||||
|
||||
if ((long) pdest & 0x02) {
|
||||
*pdest++ = (short) (izi >> 16);
|
||||
izi += izistep;
|
||||
count--;
|
||||
}
|
||||
|
||||
if ((doublecount = count >> 1) > 0) {
|
||||
do {
|
||||
ltemp = izi >> 16;
|
||||
izi += izistep;
|
||||
ltemp |= izi & 0xFFFF0000;
|
||||
izi += izistep;
|
||||
*(int *) pdest = ltemp;
|
||||
pdest += 2;
|
||||
} while (--doublecount > 0);
|
||||
}
|
||||
|
||||
if (count & 1)
|
||||
*pdest = (short) (izi >> 16);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
d_vars.c
|
||||
|
||||
global refresh variables
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "host.h"
|
||||
|
||||
// all global and static refresh variables are collected in a contiguous block
|
||||
// to avoid cache conflicts.
|
||||
|
||||
// global refresh variables -----------------------------
|
||||
|
||||
// FIXME: make into one big structure, like cl or sv
|
||||
// FIXME: do separately for refresh engine and driver
|
||||
|
||||
float d_sdivzstepu, d_tdivzstepu, d_zistepu;
|
||||
float d_sdivzstepv, d_tdivzstepv, d_zistepv;
|
||||
float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
|
||||
|
||||
fixed16_t sadjust, tadjust, bbextents, bbextentt;
|
||||
|
||||
pixel_t *cacheblock;
|
||||
int cachewidth;
|
||||
pixel_t *d_viewbuffer;
|
||||
short *d_pzbuffer;
|
||||
unsigned int d_zrowbytes;
|
||||
unsigned int d_zwidth;
|
||||
|
||||
#endif // !USE_INTEL_ASM
|
834
nq/source/draw.c
834
nq/source/draw.c
|
@ -1,834 +0,0 @@
|
|||
/*
|
||||
draw.c
|
||||
|
||||
this is the only file outside the refresh that touches the vid buffer
|
||||
|
||||
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/draw.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/sound.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "d_iface.h"
|
||||
#include "r_cvar.h"
|
||||
|
||||
typedef struct {
|
||||
vrect_t rect;
|
||||
int width;
|
||||
int height;
|
||||
byte *ptexbytes;
|
||||
int rowbytes;
|
||||
} rectdesc_t;
|
||||
|
||||
static rectdesc_t r_rectdesc;
|
||||
|
||||
byte *draw_chars; // 8*8 graphic characters
|
||||
qpic_t *draw_disc;
|
||||
qpic_t *draw_backtile;
|
||||
|
||||
|
||||
/* Support Routines */
|
||||
|
||||
typedef struct cachepic_s {
|
||||
char name[MAX_QPATH];
|
||||
cache_user_t cache;
|
||||
} cachepic_t;
|
||||
|
||||
#define MAX_CACHED_PICS 128
|
||||
cachepic_t cachepics[MAX_CACHED_PICS];
|
||||
int numcachepics;
|
||||
|
||||
|
||||
qpic_t *
|
||||
Draw_PicFromWad (char *name)
|
||||
{
|
||||
return W_GetLumpName (name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_ClearCache
|
||||
|
||||
This is a no-op in software targets
|
||||
*/
|
||||
void
|
||||
Draw_ClearCache (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
qpic_t *
|
||||
Draw_CachePic (char *path, qboolean alpha)
|
||||
{
|
||||
cachepic_t *pic;
|
||||
int i;
|
||||
qpic_t *dat;
|
||||
|
||||
for (pic = cachepics, i = 0; i < numcachepics; pic++, i++)
|
||||
if (!strcmp (path, pic->name))
|
||||
break;
|
||||
|
||||
if (i == numcachepics) {
|
||||
if (numcachepics == MAX_CACHED_PICS)
|
||||
Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
|
||||
numcachepics++;
|
||||
strcpy (pic->name, path);
|
||||
}
|
||||
|
||||
dat = Cache_Check (&pic->cache);
|
||||
|
||||
if (dat)
|
||||
return dat;
|
||||
|
||||
// load the pic from disk
|
||||
COM_LoadCacheFile (path, &pic->cache);
|
||||
|
||||
dat = (qpic_t *) pic->cache.data;
|
||||
if (!dat) {
|
||||
Sys_Error ("Draw_CachePic: failed to load %s", path);
|
||||
}
|
||||
|
||||
SwapPic (dat);
|
||||
|
||||
return dat;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Init (void)
|
||||
{
|
||||
draw_chars = W_GetLumpName ("conchars");
|
||||
draw_disc = W_GetLumpName ("disc");
|
||||
draw_backtile = W_GetLumpName ("backtile");
|
||||
|
||||
r_rectdesc.width = draw_backtile->width;
|
||||
r_rectdesc.height = draw_backtile->height;
|
||||
r_rectdesc.ptexbytes = draw_backtile->data;
|
||||
r_rectdesc.rowbytes = draw_backtile->width;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
byte *dest;
|
||||
byte *source;
|
||||
unsigned short *pusdest;
|
||||
int drawline;
|
||||
int row, col;
|
||||
|
||||
num &= 255;
|
||||
|
||||
if (y <= -8)
|
||||
return; // totally off screen
|
||||
|
||||
if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
|
||||
return;
|
||||
if (num < 0 || num > 255)
|
||||
return;
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
source = draw_chars + (row << 10) + (col << 3);
|
||||
|
||||
if (y < 0) { // clipped
|
||||
drawline = 8 + y;
|
||||
source -= 128 * y;
|
||||
y = 0;
|
||||
} else
|
||||
drawline = 8;
|
||||
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.conbuffer + y * vid.conrowbytes + x;
|
||||
|
||||
while (drawline--) {
|
||||
if (source[0])
|
||||
dest[0] = source[0];
|
||||
if (source[1])
|
||||
dest[1] = source[1];
|
||||
if (source[2])
|
||||
dest[2] = source[2];
|
||||
if (source[3])
|
||||
dest[3] = source[3];
|
||||
if (source[4])
|
||||
dest[4] = source[4];
|
||||
if (source[5])
|
||||
dest[5] = source[5];
|
||||
if (source[6])
|
||||
dest[6] = source[6];
|
||||
if (source[7])
|
||||
dest[7] = source[7];
|
||||
source += 128;
|
||||
dest += vid.conrowbytes;
|
||||
}
|
||||
} else {
|
||||
// FIXME: pre-expand to native format?
|
||||
pusdest = (unsigned short *)
|
||||
((byte *) vid.conbuffer + y * vid.conrowbytes + (x << 1));
|
||||
|
||||
while (drawline--) {
|
||||
if (source[0])
|
||||
pusdest[0] = d_8to16table[source[0]];
|
||||
if (source[1])
|
||||
pusdest[1] = d_8to16table[source[1]];
|
||||
if (source[2])
|
||||
pusdest[2] = d_8to16table[source[2]];
|
||||
if (source[3])
|
||||
pusdest[3] = d_8to16table[source[3]];
|
||||
if (source[4])
|
||||
pusdest[4] = d_8to16table[source[4]];
|
||||
if (source[5])
|
||||
pusdest[5] = d_8to16table[source[5]];
|
||||
if (source[6])
|
||||
pusdest[6] = d_8to16table[source[6]];
|
||||
if (source[7])
|
||||
pusdest[7] = d_8to16table[source[7]];
|
||||
|
||||
source += 128;
|
||||
pusdest += (vid.conrowbytes >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_String8 (int x, int y, char *str)
|
||||
{
|
||||
while (*str) {
|
||||
Draw_Character8 (x, y, *str);
|
||||
str++;
|
||||
x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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;
|
||||
unsigned short *pusdest;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Crosshair (int swap)
|
||||
{
|
||||
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, tbyte;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
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;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
if (pic->width & 7) { // general
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
for (u = 0; u < pic->width; u++)
|
||||
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = tbyte;
|
||||
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
} else { // unwound
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
for (u = 0; u < pic->width; u += 8) {
|
||||
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = tbyte;
|
||||
if ((tbyte = source[u + 1]) != TRANSPARENT_COLOR)
|
||||
dest[u + 1] = tbyte;
|
||||
if ((tbyte = source[u + 2]) != TRANSPARENT_COLOR)
|
||||
dest[u + 2] = tbyte;
|
||||
if ((tbyte = source[u + 3]) != TRANSPARENT_COLOR)
|
||||
dest[u + 3] = tbyte;
|
||||
if ((tbyte = source[u + 4]) != TRANSPARENT_COLOR)
|
||||
dest[u + 4] = tbyte;
|
||||
if ((tbyte = source[u + 5]) != TRANSPARENT_COLOR)
|
||||
dest[u + 5] = tbyte;
|
||||
if ((tbyte = source[u + 6]) != TRANSPARENT_COLOR)
|
||||
dest[u + 6] = tbyte;
|
||||
if ((tbyte = source[u + 7]) != TRANSPARENT_COLOR)
|
||||
dest[u + 7] = tbyte;
|
||||
}
|
||||
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++) {
|
||||
tbyte = source[u];
|
||||
|
||||
if (tbyte != TRANSPARENT_COLOR) {
|
||||
pusdest[u] = d_8to16table[tbyte];
|
||||
}
|
||||
}
|
||||
|
||||
pusdest += vid.rowbytes >> 1;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
byte *dest, *source, tbyte;
|
||||
unsigned short *pusdest;
|
||||
int v, u;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
source = pic->data;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.buffer + y * vid.rowbytes + x;
|
||||
|
||||
if (pic->width & 7) { // general
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
for (u = 0; u < pic->width; u++)
|
||||
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = translation[tbyte];
|
||||
|
||||
dest += vid.rowbytes;
|
||||
source += pic->width;
|
||||
}
|
||||
} else { // unwound
|
||||
for (v = 0; v < pic->height; v++) {
|
||||
for (u = 0; u < pic->width; u += 8) {
|
||||
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
|
||||
dest[u] = translation[tbyte];
|
||||
if ((tbyte = source[u + 1]) != TRANSPARENT_COLOR)
|
||||
dest[u + 1] = translation[tbyte];
|
||||
if ((tbyte = source[u + 2]) != TRANSPARENT_COLOR)
|
||||
dest[u + 2] = translation[tbyte];
|
||||
if ((tbyte = source[u + 3]) != TRANSPARENT_COLOR)
|
||||
dest[u + 3] = translation[tbyte];
|
||||
if ((tbyte = source[u + 4]) != TRANSPARENT_COLOR)
|
||||
dest[u + 4] = translation[tbyte];
|
||||
if ((tbyte = source[u + 5]) != TRANSPARENT_COLOR)
|
||||
dest[u + 5] = translation[tbyte];
|
||||
if ((tbyte = source[u + 6]) != TRANSPARENT_COLOR)
|
||||
dest[u + 6] = translation[tbyte];
|
||||
if ((tbyte = source[u + 7]) != TRANSPARENT_COLOR)
|
||||
dest[u + 7] = translation[tbyte];
|
||||
}
|
||||
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++) {
|
||||
tbyte = source[u];
|
||||
|
||||
if (tbyte != TRANSPARENT_COLOR) {
|
||||
pusdest[u] = d_8to16table[tbyte];
|
||||
}
|
||||
}
|
||||
|
||||
pusdest += vid.rowbytes >> 1;
|
||||
source += pic->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_ConsoleBackground (int lines)
|
||||
{
|
||||
int x, y, v;
|
||||
byte *src, *dest;
|
||||
unsigned short *pusdest;
|
||||
int f, fstep;
|
||||
qpic_t *conback;
|
||||
|
||||
conback = Draw_CachePic ("gfx/conback.lmp", false);
|
||||
|
||||
// draw the pic
|
||||
if (r_pixbytes == 1) {
|
||||
dest = vid.conbuffer;
|
||||
|
||||
for (y = 0; y < lines; y++, dest += vid.conrowbytes) {
|
||||
v = (vid.conheight - lines + y) * 200 / vid.conheight;
|
||||
src = conback->data + v * 320;
|
||||
if (vid.conwidth == 320)
|
||||
memcpy (dest, src, vid.conwidth);
|
||||
else {
|
||||
f = 0;
|
||||
fstep = 320 * 0x10000 / vid.conwidth;
|
||||
for (x = 0; x < vid.conwidth; x += 4) {
|
||||
dest[x] = src[f >> 16];
|
||||
f += fstep;
|
||||
dest[x + 1] = src[f >> 16];
|
||||
f += fstep;
|
||||
dest[x + 2] = src[f >> 16];
|
||||
f += fstep;
|
||||
dest[x + 3] = src[f >> 16];
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pusdest = (unsigned short *) vid.conbuffer;
|
||||
|
||||
for (y = 0; y < lines; y++, pusdest += (vid.conrowbytes >> 1)) {
|
||||
// FIXME: pre-expand to native format?
|
||||
// FIXME: does the endian switching go away in production?
|
||||
v = (vid.conheight - lines + y) * 200 / vid.conheight;
|
||||
src = conback->data + v * 320;
|
||||
f = 0;
|
||||
fstep = 320 * 0x10000 / vid.conwidth;
|
||||
for (x = 0; x < vid.conwidth; x += 4) {
|
||||
pusdest[x] = d_8to16table[src[f >> 16]];
|
||||
f += fstep;
|
||||
pusdest[x + 1] = d_8to16table[src[f >> 16]];
|
||||
f += fstep;
|
||||
pusdest[x + 2] = d_8to16table[src[f >> 16]];
|
||||
f += fstep;
|
||||
pusdest[x + 3] = d_8to16table[src[f >> 16]];
|
||||
f += fstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string)
|
||||
* 8 - 11, lines - 14, cl_verstring->string);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_DrawRect8 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
||||
{
|
||||
byte t;
|
||||
int i, j, srcdelta, destdelta;
|
||||
byte *pdest;
|
||||
|
||||
pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x;
|
||||
|
||||
srcdelta = rowbytes - prect->width;
|
||||
destdelta = vid.rowbytes - prect->width;
|
||||
|
||||
if (transparent) {
|
||||
for (i = 0; i < prect->height; i++) {
|
||||
for (j = 0; j < prect->width; j++) {
|
||||
t = *psrc;
|
||||
if (t != TRANSPARENT_COLOR) {
|
||||
*pdest = t;
|
||||
}
|
||||
|
||||
psrc++;
|
||||
pdest++;
|
||||
}
|
||||
|
||||
psrc += srcdelta;
|
||||
pdest += destdelta;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < prect->height; i++) {
|
||||
memcpy (pdest, psrc, prect->width);
|
||||
psrc += rowbytes;
|
||||
pdest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_DrawRect16 (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
|
||||
{
|
||||
byte t;
|
||||
int i, j, srcdelta, destdelta;
|
||||
unsigned short *pdest;
|
||||
|
||||
// FIXME: would it be better to pre-expand native-format versions?
|
||||
|
||||
pdest = (unsigned short *) vid.buffer +
|
||||
(prect->y * (vid.rowbytes >> 1)) + prect->x;
|
||||
|
||||
srcdelta = rowbytes - prect->width;
|
||||
destdelta = (vid.rowbytes >> 1) - prect->width;
|
||||
|
||||
if (transparent) {
|
||||
for (i = 0; i < prect->height; i++) {
|
||||
for (j = 0; j < prect->width; j++) {
|
||||
t = *psrc;
|
||||
if (t != TRANSPARENT_COLOR) {
|
||||
*pdest = d_8to16table[t];
|
||||
}
|
||||
|
||||
psrc++;
|
||||
pdest++;
|
||||
}
|
||||
|
||||
psrc += srcdelta;
|
||||
pdest += destdelta;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < prect->height; i++) {
|
||||
for (j = 0; j < prect->width; j++) {
|
||||
*pdest = d_8to16table[*psrc];
|
||||
psrc++;
|
||||
pdest++;
|
||||
}
|
||||
|
||||
psrc += srcdelta;
|
||||
pdest += destdelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_TileClear
|
||||
|
||||
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)
|
||||
{
|
||||
int width, height, tileoffsetx, tileoffsety;
|
||||
byte *psrc;
|
||||
vrect_t vr;
|
||||
|
||||
r_rectdesc.rect.x = x;
|
||||
r_rectdesc.rect.y = y;
|
||||
r_rectdesc.rect.width = w;
|
||||
r_rectdesc.rect.height = h;
|
||||
|
||||
vr.y = r_rectdesc.rect.y;
|
||||
height = r_rectdesc.rect.height;
|
||||
|
||||
tileoffsety = vr.y % r_rectdesc.height;
|
||||
|
||||
while (height > 0) {
|
||||
vr.x = r_rectdesc.rect.x;
|
||||
width = r_rectdesc.rect.width;
|
||||
|
||||
if (tileoffsety != 0)
|
||||
vr.height = r_rectdesc.height - tileoffsety;
|
||||
else
|
||||
vr.height = r_rectdesc.height;
|
||||
|
||||
if (vr.height > height)
|
||||
vr.height = height;
|
||||
|
||||
tileoffsetx = vr.x % r_rectdesc.width;
|
||||
|
||||
while (width > 0) {
|
||||
if (tileoffsetx != 0)
|
||||
vr.width = r_rectdesc.width - tileoffsetx;
|
||||
else
|
||||
vr.width = r_rectdesc.width;
|
||||
|
||||
if (vr.width > width)
|
||||
vr.width = width;
|
||||
|
||||
psrc = r_rectdesc.ptexbytes +
|
||||
(tileoffsety * r_rectdesc.rowbytes) + tileoffsetx;
|
||||
|
||||
if (r_pixbytes == 1) {
|
||||
R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
|
||||
} else {
|
||||
R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0);
|
||||
}
|
||||
|
||||
vr.x += vr.width;
|
||||
width -= vr.width;
|
||||
tileoffsetx = 0; // only the left tile can be left-clipped
|
||||
}
|
||||
|
||||
vr.y += vr.height;
|
||||
height -= vr.height;
|
||||
tileoffsety = 0; // only the top tile can be top-clipped
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_Fill
|
||||
|
||||
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 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)
|
||||
for (u = 0; u < w; u++)
|
||||
dest[u] = c;
|
||||
} else {
|
||||
uc = d_8to16table[c];
|
||||
|
||||
pusdest = (unsigned short *) vid.buffer + y * (vid.rowbytes >> 1) + x;
|
||||
for (v = 0; v < h; v++, pusdest += (vid.rowbytes >> 1))
|
||||
for (u = 0; u < w; u++)
|
||||
pusdest[u] = uc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_FadeScreen (void)
|
||||
{
|
||||
int x, y;
|
||||
byte *pbuf;
|
||||
|
||||
VID_UnlockBuffer ();
|
||||
S_ExtraUpdate ();
|
||||
VID_LockBuffer ();
|
||||
|
||||
for (y = 0; y < vid.height; y++) {
|
||||
int t;
|
||||
|
||||
pbuf = (byte *) (vid.buffer + vid.rowbytes * y);
|
||||
t = (y & 1) << 1;
|
||||
|
||||
for (x = 0; x < vid.width; x++) {
|
||||
if ((x & 3) != t)
|
||||
pbuf[x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
VID_UnlockBuffer ();
|
||||
S_ExtraUpdate ();
|
||||
VID_LockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_BeginDisc
|
||||
|
||||
Draws the little blue disc in the corner of the screen.
|
||||
Call before beginning any disc IO.
|
||||
*/
|
||||
void
|
||||
Draw_BeginDisc (void)
|
||||
{
|
||||
|
||||
D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_EndDisc
|
||||
|
||||
Erases the disc icon.
|
||||
Call after completing any disc IO
|
||||
*/
|
||||
void
|
||||
Draw_EndDisc (void)
|
||||
{
|
||||
|
||||
D_EndDirectRect (vid.width - 24, 0, 24, 24);
|
||||
}
|
|
@ -712,6 +712,7 @@ _Host_Frame (float time)
|
|||
r_paused = cl.paused;
|
||||
r_active = cls.state == ca_active;
|
||||
r_view_model = &cl.viewent;
|
||||
r_frametime = host_frametime;
|
||||
|
||||
CL_UpdateScreen (cl.time);
|
||||
|
||||
|
|
|
@ -97,78 +97,66 @@ client_LIB_DEPS= libqfnet.a $(qf_client_LIBS)
|
|||
client_SOURCES= cl_cam.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c cl_input.c \
|
||||
cl_main.c cl_misc.c cl_ngraph.c cl_parse.c cl_screen.c cl_pred.c \
|
||||
cl_skin.c cl_slist.c cl_tent.c \
|
||||
console.c keys.c locs.c nonintel.c pcx.c r_cvar.c r_efrag.c \
|
||||
r_ent.c r_graph.c r_main.c r_view.c sbar.c skin.c teamplay.c tga.c \
|
||||
console.c keys.c locs.c nonintel.c pcx.c \
|
||||
r_view.c sbar.c skin.c teamplay.c tga.c \
|
||||
wad.c cl_math.S $(syscl_SRC)
|
||||
|
||||
# Software-rendering clients
|
||||
#
|
||||
# ... Common stuff
|
||||
|
||||
soft_SOURCES= d_edge.c d_fill.c d_init.c d_modech.c \
|
||||
d_part.c d_polyse.c d_scan.c d_sky.c d_sprite.c d_surf.c \
|
||||
d_vars.c d_zpoint.c draw.c sw_graph.c sw_raclip.c sw_ralias.c sw_rbsp.c \
|
||||
sw_rdraw.c sw_redge.c sw_rlight.c sw_rmain.c sw_rmisc.c \
|
||||
sw_rpart.c sw_rsky.c sw_rsprite.c sw_rsurf.c sw_skin.c \
|
||||
sw_view.c screen.c \
|
||||
\
|
||||
d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S d_spr8.S \
|
||||
d_varsa.S sw_raclipa.S sw_raliasa.S sw_rdrawa.S sw_redgea.S \
|
||||
sw_rvarsa.S surf16.S surf8.S
|
||||
soft_SOURCES= sw_rpart.c sw_view.c
|
||||
|
||||
# ... Linux FBDev
|
||||
qw_client_fbdev_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES)
|
||||
qw_client_fbdev_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIBS)
|
||||
qw_client_fbdev_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIB_DEPS)
|
||||
qw_client_fbdev_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIBS)
|
||||
qw_client_fbdev_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFfbdev.la $(client_LIB_DEPS)
|
||||
|
||||
# ... SciTech MGL
|
||||
qw_client_mgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES)
|
||||
qw_client_mgl_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIBS) $(MGL_LIBS)
|
||||
qw_client_mgl_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIB_DEPS)
|
||||
qw_client_mgl_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIBS) $(MGL_LIBS)
|
||||
qw_client_mgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFmgl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Simple DirectMedia Layer, version 1.0 and higher
|
||||
qw_client_sdl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES)
|
||||
qw_client_sdl_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIBS) $(SDL_LIBS)
|
||||
qw_client_sdl_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIB_DEPS)
|
||||
qw_client_sdl_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIBS) $(SDL_LIBS)
|
||||
qw_client_sdl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsdl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Linux SVGAlib
|
||||
qw_client_svga_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES)
|
||||
qw_client_svga_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIBS) $(SVGA_LIBS)
|
||||
qw_client_svga_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIB_DEPS)
|
||||
qw_client_svga_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIBS) $(SVGA_LIBS)
|
||||
qw_client_svga_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFsvga.la $(client_LIB_DEPS)
|
||||
|
||||
# ... X11
|
||||
qw_client_x11_SOURCES= $(common_SOURCES) $(client_SOURCES) $(soft_SOURCES)
|
||||
qw_client_x11_LDADD= ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB)
|
||||
qw_client_x11_DEPENDENCIES=../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIB_DEPS)
|
||||
qw_client_x11_LDADD= ../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB)
|
||||
qw_client_x11_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_sw.la ../../libs/models/libQFmodels_sw.la ../../libs/video/targets/libQFx11.la $(client_LIB_DEPS)
|
||||
|
||||
|
||||
# OpenGL-using clients
|
||||
#
|
||||
# ... Common stuff
|
||||
ogl_SOURCES= noisetextures.c gl_textures.c gl_draw.c gl_dyn_fires.c \
|
||||
gl_dyn_part.c gl_dyn_textures.c gl_graph.c gl_rlight.c \
|
||||
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_skin.c \
|
||||
gl_sky.c gl_sky_clip.c gl_view.c gl_warp.c
|
||||
ogl_SOURCES= gl_dyn_part.c gl_view.c
|
||||
|
||||
# ... 3Dfx Voodoo 1 and 2 SVGAlib-based console GL
|
||||
qw_client_3dfx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES)
|
||||
qw_client_3dfx_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIBS) $(TDFXGL_LIBS) $(SVGA_LIBS) $(DL_LIBS)
|
||||
qw_client_3dfx_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIB_DEPS)
|
||||
qw_client_3dfx_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIBS) $(TDFXGL_LIBS) $(SVGA_LIBS) $(DL_LIBS)
|
||||
qw_client_3dfx_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFtdfx.la $(client_LIB_DEPS)
|
||||
|
||||
# ... OpenGL in X Window
|
||||
qw_client_glx_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES)
|
||||
qw_client_glx_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIBS) $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(DL_LIBS)
|
||||
qw_client_glx_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIB_DEPS)
|
||||
qw_client_glx_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIBS) $(GLX_LIBS) $(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(DL_LIBS)
|
||||
qw_client_glx_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFglx.la $(client_LIB_DEPS)
|
||||
|
||||
# ... Simple DirectMedia Layer, version 1.1 and higher, in GL mode
|
||||
qw_client_sgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES)
|
||||
qw_client_sgl_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIBS) $(SDL_LIBS) $(X_LIBS) $(GLX_LIBS) $(DL_LIBS)
|
||||
qw_client_sgl_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIB_DEPS)
|
||||
qw_client_sgl_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIBS) $(SDL_LIBS) $(X_LIBS) $(GLX_LIBS) $(DL_LIBS)
|
||||
qw_client_sgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFsgl.la $(client_LIB_DEPS)
|
||||
|
||||
# ... SGI/Microsoft WGL (Windows OpenGL)
|
||||
qw_client_wgl_SOURCES= $(common_SOURCES) $(client_SOURCES) $(ogl_SOURCES)
|
||||
qw_client_wgl_LDADD= ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIBS) $(GLX_LIBS) -lgdi32 -lwinmm
|
||||
qw_client_wgl_DEPENDENCIES=../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIB_DEPS)
|
||||
qw_client_wgl_LDADD= ../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIBS) $(GLX_LIBS) -lgdi32 -lwinmm
|
||||
qw_client_wgl_DEPENDENCIES=../../libs/video/renderer/libQFrenderer_gl.la ../../libs/models/libQFmodels_gl.la ../../libs/video/targets/libQFwgl.la $(client_LIB_DEPS)
|
||||
|
||||
# Stuff that doesn't get linked into an executable NEEDS to be mentioned here,
|
||||
# or it won't be distributed with 'make dist'
|
||||
|
|
|
@ -1496,6 +1496,7 @@ Host_Frame (float time)
|
|||
r_paused = cl.paused;
|
||||
r_active = cls.state == ca_active;
|
||||
r_view_model = &cl.viewent;
|
||||
r_frametime = host_frametime;
|
||||
|
||||
// don't allow cheats in multiplayer
|
||||
if (!atoi (Info_ValueForKey (cl.serverinfo, "watervis")))
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
d_copy.S
|
||||
|
||||
x86 assembly-language screen copying code.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
.data
|
||||
|
||||
LCopyWidth: .long 0
|
||||
LBlockSrcStep: .long 0
|
||||
LBlockDestStep: .long 0
|
||||
LSrcDelta: .long 0
|
||||
LDestDelta: .long 0
|
||||
|
||||
#define bufptr 4+16
|
||||
|
||||
// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since
|
||||
// no Mode X mode is wider than 360, all the data should fit in the cache for
|
||||
// the passes for the next 3 planes
|
||||
|
||||
.text
|
||||
|
||||
.globl C(VGA_UpdatePlanarScreen)
|
||||
C(VGA_UpdatePlanarScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockSrcStep
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $1,%eax
|
||||
movl %eax,LBlockDestStep
|
||||
|
||||
movl $0x3C4,%edx
|
||||
movb $2,%al
|
||||
outb %al,%dx // point the SC to the Map Mask
|
||||
incl %edx
|
||||
|
||||
movl bufptr(%esp),%esi
|
||||
movl C(VGA_pagebase),%edi
|
||||
movl C(VGA_height),%ebp
|
||||
shrl $1,%ebp
|
||||
|
||||
movl C(VGA_width),%ecx
|
||||
movl C(VGA_bufferrowbytes),%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LSrcDelta
|
||||
movl C(VGA_rowbytes),%eax
|
||||
shll $2,%eax
|
||||
subl %ecx,%eax
|
||||
movl %eax,LDestDelta
|
||||
shrl $4,%ecx
|
||||
movl %ecx,LCopyWidth
|
||||
|
||||
LRowLoop:
|
||||
movb $1,%al
|
||||
|
||||
LPlaneLoop:
|
||||
outb %al,%dx
|
||||
movb $2,%ah
|
||||
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
LRowSetLoop:
|
||||
movl LCopyWidth,%ecx
|
||||
LColumnLoop:
|
||||
movb 12(%esi),%bh
|
||||
movb 8(%esi),%bl
|
||||
shll $16,%ebx
|
||||
movb 4(%esi),%bh
|
||||
movb (%esi),%bl
|
||||
movl %ebx,(%edi)
|
||||
addl $16,%esi
|
||||
addl $4,%edi
|
||||
decl %ecx
|
||||
jnz LColumnLoop
|
||||
|
||||
addl LDestDelta,%edi
|
||||
addl LSrcDelta,%esi
|
||||
decb %ah
|
||||
jnz LRowSetLoop
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
incl %esi
|
||||
|
||||
shlb $1,%al
|
||||
cmpb $16,%al
|
||||
jnz LPlaneLoop
|
||||
|
||||
subl $4,%esi
|
||||
addl LBlockSrcStep,%esi
|
||||
addl LBlockDestStep,%edi
|
||||
decl %ebp
|
||||
jnz LRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#define srcptr 4+16
|
||||
#define destptr 8+16
|
||||
#define width 12+16
|
||||
#define height 16+16
|
||||
#define srcrowbytes 20+16
|
||||
#define destrowbytes 24+16
|
||||
|
||||
.globl C(VGA_UpdateLinearScreen)
|
||||
C(VGA_UpdateLinearScreen):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
cld
|
||||
movl srcptr(%esp),%esi
|
||||
movl destptr(%esp),%edi
|
||||
movl width(%esp),%ebx
|
||||
movl srcrowbytes(%esp),%eax
|
||||
subl %ebx,%eax
|
||||
movl destrowbytes(%esp),%edx
|
||||
subl %ebx,%edx
|
||||
shrl $2,%ebx
|
||||
movl height(%esp),%ebp
|
||||
LLRowLoop:
|
||||
movl %ebx,%ecx
|
||||
rep/movsl (%esi),(%edi)
|
||||
addl %eax,%esi
|
||||
addl %edx,%edi
|
||||
decl %ebp
|
||||
jnz LLRowLoop
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
|
||||
ret
|
||||
#endif /* USE_INTEL_ASM */
|
1044
qw/source/d_draw.S
1044
qw/source/d_draw.S
File diff suppressed because it is too large
Load diff
|
@ -1,981 +0,0 @@
|
|||
/*
|
||||
d_draw16.S
|
||||
|
||||
x86 assembly-language horizontal 8-bpp span-drawing code, with
|
||||
16-pixel subdivision.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with no transparency and
|
||||
// 16-pixel subdivision.
|
||||
//
|
||||
// Assumes there is at least one span in pspans, and that every span
|
||||
// contains at least one pixel
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $4096,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $4096,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $4096,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $4096,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawSpans16)
|
||||
C(D_DrawSpans16):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-16 steps, for 16-long segments; also set up cacheblock
|
||||
// and span list pointers
|
||||
//
|
||||
// TODO: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_16
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_16
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_16
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
fstps zi16stepu
|
||||
fstps tdivz16stepu
|
||||
fstps sdivz16stepu
|
||||
|
||||
LSpanLoop:
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl espan_t_v(%ebx)
|
||||
fildl espan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(1) // 1/z | z*64k | t/z | s/z
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ecx
|
||||
movl espan_t_v(%ebx),%eax
|
||||
movl %ebx,pspantemp // preserve spans pointer
|
||||
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ecx,%edi
|
||||
movl espan_t_u(%ebx),%ecx
|
||||
addl %ecx,%edi // pdest = &pdestspan[scans->u];
|
||||
movl espan_t_count(%ebx),%ecx
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1
|
||||
flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1
|
||||
fmul %st(2),%st(0) // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1
|
||||
fxch %st(1) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(2) // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 |
|
||||
// C(d_tdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
movl C(cachewidth),%edx
|
||||
imull %edx,%eax // (tfrac >> 16) * cachewidth
|
||||
addl %ebx,%esi
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 16-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
movb (%esi),%bl // get first source texel
|
||||
subl $16,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
movl %ecx,counttemp // remember count of remaining pixels
|
||||
|
||||
movl C(tadjust),%ecx
|
||||
movb %bl,(%edi) // store first dest pixel
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $4096,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $20,%eax // tstep >>= 16;
|
||||
jz LZero
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
imull %ebx,%eax
|
||||
jmp LSetUp1
|
||||
|
||||
LZero:
|
||||
sarl $20,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
|
||||
LSetUp1:
|
||||
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $12,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $12,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
|
||||
movl %ecx,tstep
|
||||
addl %ecx,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none)
|
||||
addl %ebp,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%ecx,4),%esi // point to next source texel
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb (%esi),%al
|
||||
addl %ebp,%ebx
|
||||
movb %al,1(%edi)
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
movl counttemp,%ecx
|
||||
cmpl $16,%ecx // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %ecx
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // C(d_zistepu) | spancountminus1
|
||||
fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1
|
||||
fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1
|
||||
fxch %st(1) // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1
|
||||
faddp %st(0),%st(3) // C(d_tdivzstepu)*scm1 | scm1
|
||||
fxch %st(1) // scm1 | C(d_tdivzstepu)*scm1
|
||||
fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1
|
||||
faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1
|
||||
flds fp_64k // 64k | C(d_sdivzstepu)*scm1
|
||||
fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi16stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz16stepu
|
||||
fxch %st(2)
|
||||
flds tdivz16stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
movl %ecx,counttemp
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,14(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl $16,%edi
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl counttemp,%ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $16,%ecx // are there multiple segments remaining?
|
||||
movb %al,-1(%edi)
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movb (%esi),%al // load first texel in segment
|
||||
movl C(tadjust),%ebx
|
||||
movb %al,(%edi) // store first pixel in segment
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $4096,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $4096,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
|
||||
imull reciprocal_table_16-8(,%ecx,4) // sstep = (snext - s) /
|
||||
// (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table_16-8(,%ecx,4) // tstep = (tnext - t) /
|
||||
// (spancount-1)
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl entryvec_table_16(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
movl %ebx,jumptemp // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
imull %ebx,%edx
|
||||
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ecx,%edx
|
||||
addl %eax,%edx
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
jmp *jumptemp // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movb (%esi),%al // load first texel in segment
|
||||
subl $15,%edi // adjust for hardwired offset
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Entry2_16, Entry3_16, Entry4_16, Entry5_16
|
||||
.globl Entry6_16, Entry7_16, Entry8_16, Entry9_16
|
||||
.globl Entry10_16, Entry11_16, Entry12_16, Entry13_16
|
||||
.globl Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
Entry2_16:
|
||||
subl $14,%edi // adjust for hardwired offsets
|
||||
movb (%esi),%al
|
||||
jmp LEntry2_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry3_16:
|
||||
subl $13,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
jmp LEntry3_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry4_16:
|
||||
subl $12,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry4_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry5_16:
|
||||
subl $11,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry5_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry6_16:
|
||||
subl $10,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry6_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry7_16:
|
||||
subl $9,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry7_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry8_16:
|
||||
subl $8,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry8_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry9_16:
|
||||
subl $7,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry9_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry10_16:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry10_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry11_16:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry11_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry12_16:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry12_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry13_16:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry13_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry14_16:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry14_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry15_16:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
jmp LEntry15_16
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Entry16_16:
|
||||
addl %eax,%edx
|
||||
movb (%esi),%al
|
||||
sbbl %ecx,%ecx
|
||||
addl %ebp,%ebx
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
|
||||
addl tstep,%edx
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,1(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry15_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,2(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry14_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,3(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry13_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,4(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry12_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,5(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry11_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,6(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry10_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,7(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry9_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,8(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry8_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,9(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry7_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,10(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry6_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,11(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry5_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,12(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
addl tstep,%edx
|
||||
LEntry4_16:
|
||||
sbbl %ecx,%ecx
|
||||
movb %al,13(%edi)
|
||||
addl %ebp,%ebx
|
||||
movb (%esi),%al
|
||||
adcl advancetable+4(,%ecx,4),%esi
|
||||
LEntry3_16:
|
||||
movb %al,14(%edi)
|
||||
movb (%esi),%al
|
||||
LEntry2_16:
|
||||
|
||||
LEndSpan:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
movl pspantemp,%ebx // restore spans pointer
|
||||
movl espan_t_pnext(%ebx),%ebx // point to next span
|
||||
testl %ebx,%ebx // any more spans?
|
||||
movb %al,15(%edi)
|
||||
jnz LSpanLoop // more spans
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // USE_INTEL_ASM
|
|
@ -1,294 +0,0 @@
|
|||
/*
|
||||
d_edge.c
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
static int miplevel;
|
||||
|
||||
float scale_for_mip;
|
||||
extern int screenwidth;
|
||||
int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
int vstartscan;
|
||||
|
||||
vec3_t transformed_modelorg;
|
||||
|
||||
|
||||
void
|
||||
D_DrawPoly (void)
|
||||
{
|
||||
// this driver takes spans, not polygons
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
D_MipLevelForScale (float scale)
|
||||
{
|
||||
int lmiplevel;
|
||||
|
||||
if (scale >= d_scalemip[0])
|
||||
lmiplevel = 0;
|
||||
else if (scale >= d_scalemip[1])
|
||||
lmiplevel = 1;
|
||||
else if (scale >= d_scalemip[2])
|
||||
lmiplevel = 2;
|
||||
else
|
||||
lmiplevel = 3;
|
||||
|
||||
if (lmiplevel < d_minmip)
|
||||
lmiplevel = d_minmip;
|
||||
|
||||
return lmiplevel;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: clean this up
|
||||
void
|
||||
D_DrawSolidSurface (surf_t *surf, int color)
|
||||
{
|
||||
espan_t *span;
|
||||
byte *pdest;
|
||||
int u, u2, pix;
|
||||
|
||||
pix = (color << 24) | (color << 16) | (color << 8) | color;
|
||||
for (span = surf->spans; span; span = span->pnext) {
|
||||
pdest = (byte *) d_viewbuffer + screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
((byte *) pdest)[u] = pix;
|
||||
|
||||
if (u2 - u < 8) {
|
||||
for (u++; u <= u2; u++)
|
||||
((byte *) pdest)[u] = pix;
|
||||
} else {
|
||||
for (u++; u & 3; u++)
|
||||
((byte *) pdest)[u] = pix;
|
||||
|
||||
u2 -= 4;
|
||||
for (; u <= u2; u += 4)
|
||||
*(int *) ((byte *) pdest + u) = pix;
|
||||
u2 += 4;
|
||||
for (; u <= u2; u++)
|
||||
((byte *) pdest)[u] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_CalcGradients (msurface_t *pface)
|
||||
{
|
||||
mplane_t *pplane;
|
||||
float mipscale;
|
||||
vec3_t p_temp1;
|
||||
vec3_t p_saxis, p_taxis;
|
||||
float t;
|
||||
|
||||
pplane = pface->plane;
|
||||
|
||||
mipscale = 1.0 / (float) (1 << miplevel);
|
||||
|
||||
TransformVector (pface->texinfo->vecs[0], p_saxis);
|
||||
TransformVector (pface->texinfo->vecs[1], p_taxis);
|
||||
|
||||
t = xscaleinv * mipscale;
|
||||
d_sdivzstepu = p_saxis[0] * t;
|
||||
d_tdivzstepu = p_taxis[0] * t;
|
||||
|
||||
t = yscaleinv * mipscale;
|
||||
d_sdivzstepv = -p_saxis[1] * t;
|
||||
d_tdivzstepv = -p_taxis[1] * t;
|
||||
|
||||
d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
|
||||
ycenter * d_sdivzstepv;
|
||||
d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
|
||||
ycenter * d_tdivzstepv;
|
||||
|
||||
VectorScale (transformed_modelorg, mipscale, p_temp1);
|
||||
|
||||
t = 0x10000 * mipscale;
|
||||
sadjust = ((fixed16_t) (DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
((pface->texturemins[0] << 16) >> miplevel)
|
||||
+ pface->texinfo->vecs[0][3] * t;
|
||||
tadjust = ((fixed16_t) (DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
|
||||
((pface->texturemins[1] << 16) >> miplevel)
|
||||
+ pface->texinfo->vecs[1][3] * t;
|
||||
|
||||
// -1 (-epsilon) so we never wander off the edge of the texture
|
||||
bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
|
||||
bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DrawSurfaces (void)
|
||||
{
|
||||
surf_t *s;
|
||||
msurface_t *pface;
|
||||
surfcache_t *pcurrentcache;
|
||||
vec3_t world_transformed_modelorg;
|
||||
vec3_t local_modelorg;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
TransformVector (modelorg, transformed_modelorg);
|
||||
VectorCopy (transformed_modelorg, world_transformed_modelorg);
|
||||
|
||||
// TODO: could preset a lot of this at mode set time
|
||||
if (r_drawflat->int_val) {
|
||||
for (s = &surfaces[1]; s < surface_p; s++) {
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
D_DrawSolidSurface (s, (int) ((long) s->data & 0xFF));
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
} else {
|
||||
for (s = &surfaces[1]; s < surface_p; s++) {
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
r_drawnpolycount++;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
if (s->flags & SURF_DRAWSKY) {
|
||||
if (!r_skymade) {
|
||||
R_MakeSky ();
|
||||
}
|
||||
|
||||
D_DrawSkyScans8 (s->spans);
|
||||
D_DrawZSpans (s->spans);
|
||||
} else if (s->flags & SURF_DRAWBACKGROUND) {
|
||||
// set up a gradient for the background surface that places
|
||||
// it
|
||||
// effectively at infinity distance from the viewpoint
|
||||
d_zistepu = 0;
|
||||
d_zistepv = 0;
|
||||
d_ziorigin = -0.9;
|
||||
|
||||
D_DrawSolidSurface (s, r_clearcolor->int_val & 0xFF);
|
||||
D_DrawZSpans (s->spans);
|
||||
} else if (s->flags & SURF_DRAWTURB) {
|
||||
pface = s->data;
|
||||
miplevel = 0;
|
||||
cacheblock = (pixel_t *)
|
||||
((byte *) pface->texinfo->texture +
|
||||
pface->texinfo->texture->offsets[0]);
|
||||
cachewidth = 64;
|
||||
|
||||
if (s->insubmodel) {
|
||||
// FIXME: we don't want to do all this for every polygon!
|
||||
// TODO: store once at start of frame
|
||||
currententity = s->entity; // FIXME: make this passed in
|
||||
// to R_RotateBmodel ()
|
||||
VectorSubtract (r_origin, currententity->origin,
|
||||
local_modelorg);
|
||||
TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
R_RotateBmodel (); // FIXME: don't mess with the
|
||||
// frustum, make entity passed in
|
||||
}
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
Turbulent8 (s->spans);
|
||||
D_DrawZSpans (s->spans);
|
||||
|
||||
if (s->insubmodel) {
|
||||
// restore the old drawing state
|
||||
// FIXME: we don't want to do this every time!
|
||||
// TODO: speed up
|
||||
|
||||
currententity = &r_worldentity;
|
||||
VectorCopy (world_transformed_modelorg,
|
||||
transformed_modelorg);
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
R_TransformFrustum ();
|
||||
}
|
||||
} else {
|
||||
if (s->insubmodel) {
|
||||
// FIXME: we don't want to do all this for every polygon!
|
||||
// TODO: store once at start of frame
|
||||
currententity = s->entity; // FIXME: make this passed in
|
||||
// to R_RotateBmodel ()
|
||||
VectorSubtract (r_origin, currententity->origin,
|
||||
local_modelorg);
|
||||
TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
R_RotateBmodel (); // FIXME: don't mess with the
|
||||
// frustum, make entity passed in
|
||||
}
|
||||
|
||||
pface = s->data;
|
||||
miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
|
||||
* pface->texinfo->mipadjust);
|
||||
|
||||
// FIXME: make this passed in to D_CacheSurface
|
||||
pcurrentcache = D_CacheSurface (pface, miplevel);
|
||||
|
||||
cacheblock = (pixel_t *) pcurrentcache->data;
|
||||
cachewidth = pcurrentcache->width;
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
(*d_drawspans) (s->spans);
|
||||
|
||||
D_DrawZSpans (s->spans);
|
||||
|
||||
if (s->insubmodel) {
|
||||
// restore the old drawing state
|
||||
// FIXME: we don't want to do this every time!
|
||||
// TODO: speed up
|
||||
|
||||
VectorCopy (world_transformed_modelorg,
|
||||
transformed_modelorg);
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
R_TransformFrustum ();
|
||||
currententity = &r_worldentity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
d_fill.c
|
||||
|
||||
clears a specified rectangle to the specified color
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_iface.h"
|
||||
|
||||
|
||||
void
|
||||
D_FillRect (vrect_t *rect, int color)
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
unsigned char *dest;
|
||||
unsigned int *ldest;
|
||||
|
||||
rx = rect->x;
|
||||
ry = rect->y;
|
||||
rwidth = rect->width;
|
||||
rheight = rect->height;
|
||||
|
||||
if (rx < 0) {
|
||||
rwidth += rx;
|
||||
rx = 0;
|
||||
}
|
||||
if (ry < 0) {
|
||||
rheight += ry;
|
||||
ry = 0;
|
||||
}
|
||||
if (rx + rwidth > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if (ry + rheight > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = ((byte *) vid.buffer + ry * vid.rowbytes + rx);
|
||||
|
||||
if (((rwidth & 0x03) == 0) && (((long) dest & 0x03) == 0)) {
|
||||
// faster aligned dword clear
|
||||
ldest = (unsigned int *) dest;
|
||||
color += color << 16;
|
||||
|
||||
rwidth >>= 2;
|
||||
color += color << 8;
|
||||
|
||||
for (ry = 0; ry < rheight; ry++) {
|
||||
for (rx = 0; rx < rwidth; rx++)
|
||||
ldest[rx] = color;
|
||||
ldest = (unsigned int *) ((byte *) ldest + vid.rowbytes);
|
||||
}
|
||||
} else {
|
||||
// slower byte-by-byte clear for unaligned cases
|
||||
for (ry = 0; ry < rheight; ry++) {
|
||||
for (rx = 0; rx < rwidth; rx++)
|
||||
dest[rx] = color;
|
||||
dest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
d_init.c
|
||||
|
||||
rasterization driver initialization
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/compat.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "d_local.h"
|
||||
#include "r_cvar.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
surfcache_t *d_initial_rover;
|
||||
qboolean d_roverwrapped;
|
||||
int d_minmip;
|
||||
float d_scalemip[NUM_MIPS - 1];
|
||||
|
||||
static float basemip[NUM_MIPS - 1] = { 1.0, 0.5 * 0.8, 0.25 * 0.8 };
|
||||
|
||||
extern int d_aflatcolor;
|
||||
|
||||
void (*d_drawspans) (espan_t *pspan);
|
||||
|
||||
|
||||
void
|
||||
D_Init (void)
|
||||
{
|
||||
r_skydirect = 1;
|
||||
|
||||
r_drawpolys = false;
|
||||
r_worldpolysbacktofront = false;
|
||||
r_recursiveaffinetriangles = true;
|
||||
r_pixbytes = 1;
|
||||
r_aliasuvscale = 1.0;
|
||||
|
||||
vid.surf_cache_size = D_SurfaceCacheForRes;
|
||||
vid.flush_caches = D_FlushCaches;
|
||||
vid.init_caches = D_InitCaches;
|
||||
|
||||
VID_InitBuffers ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_CopyRects (vrect_t *prects, int transparent)
|
||||
{
|
||||
|
||||
// this function is only required if the CPU doesn't have direct access to the
|
||||
// back buffer, and there's some driver interface function that the driver
|
||||
// doesn't support and requires Quake to do in software (such as drawing the
|
||||
// console); Quake will then draw into wherever the driver points vid.buffer
|
||||
// and will call this function before swapping buffers
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_EnableBackBufferAccess (void)
|
||||
{
|
||||
|
||||
VID_LockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_TurnZOn (void)
|
||||
{
|
||||
// not needed for software version
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DisableBackBufferAccess (void)
|
||||
{
|
||||
VID_UnlockBuffer ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_SetupFrame (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (r_dowarp)
|
||||
d_viewbuffer = r_warpbuffer;
|
||||
else
|
||||
d_viewbuffer = (void *) (byte *) vid.buffer;
|
||||
|
||||
if (r_dowarp)
|
||||
screenwidth = WARP_WIDTH;
|
||||
else
|
||||
screenwidth = vid.rowbytes;
|
||||
|
||||
d_roverwrapped = false;
|
||||
d_initial_rover = sc_rover;
|
||||
|
||||
d_minmip = bound (0, d_mipcap->value, 3);
|
||||
|
||||
for (i = 0; i < (NUM_MIPS - 1); i++)
|
||||
d_scalemip[i] = basemip[i] * d_mipscale->value;
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
if (d_subdiv16->int_val)
|
||||
d_drawspans = D_DrawSpans16;
|
||||
else
|
||||
d_drawspans = D_DrawSpans8;
|
||||
#else
|
||||
d_drawspans = D_DrawSpans8;
|
||||
#endif
|
||||
|
||||
d_aflatcolor = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_UpdateRects (vrect_t *prect)
|
||||
{
|
||||
// the software driver draws these directly to the vid buffer
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
d_modech.c
|
||||
|
||||
called when mode has just changed
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift;
|
||||
|
||||
int d_scantable[MAXHEIGHT];
|
||||
short *zspantable[MAXHEIGHT];
|
||||
|
||||
|
||||
void
|
||||
D_Patch (void)
|
||||
{
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
static qboolean protectset8 = false;
|
||||
|
||||
if (!protectset8) {
|
||||
Sys_MakeCodeWriteable ((int) D_PolysetAff8Start,
|
||||
(int) D_PolysetAff8End -
|
||||
(int) D_PolysetAff8Start);
|
||||
protectset8 = true;
|
||||
}
|
||||
#endif // USE_INTEL_ASM
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_ViewChanged (void)
|
||||
{
|
||||
int rowbytes;
|
||||
|
||||
if (r_dowarp)
|
||||
rowbytes = WARP_WIDTH;
|
||||
else
|
||||
rowbytes = vid.rowbytes;
|
||||
|
||||
scale_for_mip = xscale;
|
||||
if (yscale > xscale)
|
||||
scale_for_mip = yscale;
|
||||
|
||||
d_zrowbytes = vid.width * 2;
|
||||
d_zwidth = vid.width;
|
||||
|
||||
d_pix_min = r_refdef.vrect.width / 320;
|
||||
if (d_pix_min < 1)
|
||||
d_pix_min = 1;
|
||||
|
||||
d_pix_max = (int) ((float) r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
|
||||
d_pix_shift = 8 - (int) ((float) r_refdef.vrect.width / 320.0 + 0.5);
|
||||
if (d_pix_max < 1)
|
||||
d_pix_max = 1;
|
||||
|
||||
if (pixelAspect > 1.4)
|
||||
d_y_aspect_shift = 1;
|
||||
else
|
||||
d_y_aspect_shift = 0;
|
||||
|
||||
d_vrectx = r_refdef.vrect.x;
|
||||
d_vrecty = r_refdef.vrect.y;
|
||||
d_vrectright_particle = r_refdef.vrectright - d_pix_max;
|
||||
d_vrectbottom_particle =
|
||||
r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift);
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vid.height; i++) {
|
||||
d_scantable[i] = i * rowbytes;
|
||||
zspantable[i] = d_pzbuffer + i * d_zwidth;
|
||||
}
|
||||
}
|
||||
|
||||
D_Patch ();
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
d_part.c
|
||||
|
||||
software driver module for drawing particles
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
void
|
||||
D_EndParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_StartParticles (void)
|
||||
{
|
||||
// not used by software driver
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawParticle (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pparticle->org, r_origin, local);
|
||||
|
||||
transformed[0] = DotProduct (local, r_pright);
|
||||
transformed[1] = DotProduct (local, r_pup);
|
||||
transformed[2] = DotProduct (local, r_ppn);
|
||||
|
||||
if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
return;
|
||||
|
||||
// project the point
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int) (xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int) (ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > d_vrectbottom_particle) ||
|
||||
(u > d_vrectright_particle) || (v < d_vrecty) || (u < d_vrectx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * v) + u;
|
||||
pdest = d_viewbuffer + d_scantable[v] + u;
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
pix = izi >> d_pix_shift;
|
||||
|
||||
if (pix < d_pix_min)
|
||||
pix = d_pix_min;
|
||||
else if (pix > d_pix_max)
|
||||
pix = d_pix_max;
|
||||
|
||||
switch (pix) {
|
||||
case 1:
|
||||
count = 1 << d_y_aspect_shift;
|
||||
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
count = 2 << d_y_aspect_shift;
|
||||
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
count = 3 << d_y_aspect_shift;
|
||||
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
count = 4 << d_y_aspect_shift;
|
||||
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pparticle->color;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pparticle->color;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
count = pix << d_y_aspect_shift;
|
||||
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
|
||||
for (i = 0; i < pix; i++) {
|
||||
if (pz[i] <= izi) {
|
||||
pz[i] = izi;
|
||||
pdest[i] = pparticle->color;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
|
@ -1,484 +0,0 @@
|
|||
/*
|
||||
d_parta.S
|
||||
|
||||
x86 assembly-language 8-bpp particle-drawing code.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "d_ifacea.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle drawing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//FIXME: comments, full optimization
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp particle queueing code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
#define P 12+4
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawParticle)
|
||||
C(D_DrawParticle):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl P(%esp),%edi
|
||||
|
||||
// FIXME: better FP overlap in general here
|
||||
|
||||
// transform point
|
||||
// VectorSubtract (p->org, r_origin, local);
|
||||
flds C(r_origin)
|
||||
fsubrs pt_org(%edi)
|
||||
flds pt_org+4(%edi)
|
||||
fsubs C(r_origin)+4
|
||||
flds pt_org+8(%edi)
|
||||
fsubs C(r_origin)+8
|
||||
fxch %st(2) // local[0] | local[1] | local[2]
|
||||
|
||||
// transformed[2] = DotProduct(local, r_ppn);
|
||||
flds C(r_ppn) // r_ppn[0] | local[0] | local[1] | local[2]
|
||||
fmul %st(1),%st(0) // dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+4 // r_ppn[1] | dot0 | local[0] | local[1] | local[2]
|
||||
fmul %st(3),%st(0) // dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
flds C(r_ppn)+8 // r_ppn[2] | dot1 | dot0 | local[0] |
|
||||
// local[1] | local[2]
|
||||
fmul %st(5),%st(0) // dot2 | dot1 | dot0 | local[0] | local[1] | local[2]
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[0] | local[1] | local[2]
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[0] | local[1] |
|
||||
// local[2]
|
||||
faddp %st(0),%st(1) // z | local[0] | local[1] | local[2]
|
||||
fld %st(0) // z | z | local[0] | local[1] |
|
||||
// local[2]
|
||||
fdivrs float_1 // 1/z | z | local[0] | local[1] | local[2]
|
||||
fxch %st(1) // z | 1/z | local[0] | local[1] | local[2]
|
||||
|
||||
// if (transformed[2] < PARTICLE_Z_CLIP)
|
||||
// return;
|
||||
fcomps float_particle_z_clip // 1/z | local[0] | local[1] | local[2]
|
||||
fxch %st(3) // local[2] | local[0] | local[1] | 1/z
|
||||
|
||||
flds C(r_pup) // r_pup[0] | local[2] | local[0] | local[1] | 1/z
|
||||
fmul %st(2),%st(0) // dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+4 // r_pup[1] | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jnz LPop6AndDone
|
||||
|
||||
// transformed[1] = DotProduct(local, r_pup);
|
||||
fmul %st(4),%st(0) // dot1 | dot0 | local[2] | local[0] | local[1] | 1/z
|
||||
flds C(r_pup)+8 // r_pup[2] | dot1 | dot0 | local[2] |
|
||||
// local[0] | local[1] | 1/z
|
||||
fmul %st(3),%st(0) // dot2 | dot1 | dot0 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
fxch %st(2) // dot0 | dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[2] | local[0] |
|
||||
// local[1] | 1/z
|
||||
faddp %st(0),%st(1) // y | local[2] | local[0] | local[1] | 1/z
|
||||
fxch %st(3) // local[1] | local[2] | local[0] | y | 1/z
|
||||
|
||||
// transformed[0] = DotProduct(local, r_pright);
|
||||
fmuls C(r_pright)+4 // dot1 | local[2] | local[0] | y | 1/z
|
||||
fxch %st(2) // local[0] | local[2] | dot1 | y | 1/z
|
||||
fmuls C(r_pright) // dot0 | local[2] | dot1 | y | 1/z
|
||||
fxch %st(1) // local[2] | dot0 | dot1 | y | 1/z
|
||||
fmuls C(r_pright)+8 // dot2 | dot0 | dot1 | y | 1/z
|
||||
fxch %st(2) // dot1 | dot0 | dot2 | y | 1/z
|
||||
faddp %st(0),%st(1) // dot1 + dot0 | dot2 | y | 1/z
|
||||
|
||||
faddp %st(0),%st(1) // x | y | 1/z
|
||||
fxch %st(1) // y | x | 1/z
|
||||
|
||||
// project the point
|
||||
fmul %st(2),%st(0) // y/z | x | 1/z
|
||||
fxch %st(1) // x | y/z | 1/z
|
||||
fmul %st(2),%st(0) // x/z | y/z | 1/z
|
||||
fxch %st(1) // y/z | x/z | 1/z
|
||||
fsubrs C(ycenter) // v | x/z | 1/z
|
||||
fxch %st(1) // x/z | v | 1/z
|
||||
fadds C(xcenter) // u | v | 1/z
|
||||
// FIXME: preadjust xcenter and ycenter
|
||||
fxch %st(1) // v | u | 1/z
|
||||
fadds float_point5 // v | u | 1/z
|
||||
fxch %st(1) // u | v | 1/z
|
||||
fadds float_point5 // u | v | 1/z
|
||||
fxch %st(2) // 1/z | v | u
|
||||
fmuls DP_32768 // 1/z * 0x8000 | v | u
|
||||
fxch %st(2) // u | v | 1/z * 0x8000
|
||||
|
||||
// FIXME: use Terje's fp->int trick here?
|
||||
// FIXME: check we're getting proper rounding here
|
||||
fistpl DP_u // v | 1/z * 0x8000
|
||||
fistpl DP_v // 1/z * 0x8000
|
||||
|
||||
movl DP_u,%eax
|
||||
movl DP_v,%edx
|
||||
|
||||
// if ((v > d_vrectbottom_particle) ||
|
||||
// (u > d_vrectright_particle) ||
|
||||
// (v < d_vrecty) ||
|
||||
// (u < d_vrectx))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
movl C(d_vrectbottom_particle),%ebx
|
||||
movl C(d_vrectright_particle),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jg LPop1AndDone
|
||||
cmpl %ecx,%eax
|
||||
jg LPop1AndDone
|
||||
movl C(d_vrecty),%ebx
|
||||
movl C(d_vrectx),%ecx
|
||||
cmpl %ebx,%edx
|
||||
jl LPop1AndDone
|
||||
|
||||
cmpl %ecx,%eax
|
||||
jl LPop1AndDone
|
||||
|
||||
flds pt_color(%edi) // color | 1/z * 0x8000
|
||||
// FIXME: use Terje's fast fp->int trick?
|
||||
fistpl DP_Color // 1/z * 0x8000
|
||||
|
||||
movl C(d_viewbuffer),%ebx
|
||||
|
||||
addl %eax,%ebx
|
||||
movl C(d_scantable)(,%edx,4),%edi // point to the pixel
|
||||
|
||||
imull C(d_zrowbytes),%edx // point to the z pixel
|
||||
|
||||
leal (%edx,%eax,2),%edx
|
||||
movl C(d_pzbuffer),%eax
|
||||
|
||||
fistpl izi
|
||||
|
||||
addl %ebx,%edi
|
||||
addl %eax,%edx
|
||||
|
||||
// pix = izi >> d_pix_shift;
|
||||
|
||||
movl izi,%eax
|
||||
movl C(d_pix_shift),%ecx
|
||||
shrl %cl,%eax
|
||||
movl izi,%ebp
|
||||
|
||||
// if (pix < d_pix_min)
|
||||
// pix = d_pix_min;
|
||||
// else if (pix > d_pix_max)
|
||||
// pix = d_pix_max;
|
||||
|
||||
movl C(d_pix_min),%ebx
|
||||
movl C(d_pix_max),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jnl LTestPixMax
|
||||
movl %ebx,%eax
|
||||
jmp LTestDone
|
||||
|
||||
LTestPixMax:
|
||||
cmpl %ecx,%eax
|
||||
jng LTestDone
|
||||
movl %ecx,%eax
|
||||
LTestDone:
|
||||
|
||||
movb DP_Color,%ch
|
||||
|
||||
movl C(d_y_aspect_shift),%ebx
|
||||
testl %ebx,%ebx
|
||||
jnz LDefault
|
||||
|
||||
cmpl $4,%eax
|
||||
ja LDefault
|
||||
|
||||
jmp *DP_EntryTable-4(,%eax,4)
|
||||
|
||||
// 1x1
|
||||
.globl DP_1x1
|
||||
DP_1x1:
|
||||
cmpw %bp,(%edx) // just one pixel to do
|
||||
jg LDone
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
jmp LDone
|
||||
|
||||
// 2x2
|
||||
.globl DP_2x2
|
||||
DP_2x2:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L2x2_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L2x2_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L2x2_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L2x2_2:
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L2x2_3
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L2x2_3:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L2x2_4
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L2x2_4:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// 3x3
|
||||
.globl DP_3x3
|
||||
DP_3x3:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L3x3_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L3x3_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L3x3_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L3x3_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L3x3_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L3x3_3:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L3x3_4
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L3x3_4:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L3x3_5
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L3x3_5:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L3x3_6
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L3x3_6:
|
||||
|
||||
cmpw %bp,(%edx,%esi,2)
|
||||
jg L3x3_7
|
||||
movw %bp,(%edx,%esi,2)
|
||||
movb %ch,(%edi,%ebx,2)
|
||||
L3x3_7:
|
||||
cmpw %bp,2(%edx,%esi,2)
|
||||
jg L3x3_8
|
||||
movw %bp,2(%edx,%esi,2)
|
||||
movb %ch,1(%edi,%ebx,2)
|
||||
L3x3_8:
|
||||
cmpw %bp,4(%edx,%esi,2)
|
||||
jg L3x3_9
|
||||
movw %bp,4(%edx,%esi,2)
|
||||
movb %ch,2(%edi,%ebx,2)
|
||||
L3x3_9:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
|
||||
// 4x4
|
||||
.globl DP_4x4
|
||||
DP_4x4:
|
||||
pushl %esi
|
||||
movl C(screenwidth),%ebx
|
||||
movl C(d_zrowbytes),%esi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_1
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_1:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_2
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_2:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_3
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_3:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_4
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_4:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_5
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_5:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_6
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_6:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_7
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_7:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_8
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_8:
|
||||
|
||||
leal (%edx,%esi,2),%edx
|
||||
leal (%edi,%ebx,2),%edi
|
||||
|
||||
cmpw %bp,(%edx)
|
||||
jg L4x4_9
|
||||
movw %bp,(%edx)
|
||||
movb %ch,(%edi)
|
||||
L4x4_9:
|
||||
cmpw %bp,2(%edx)
|
||||
jg L4x4_10
|
||||
movw %bp,2(%edx)
|
||||
movb %ch,1(%edi)
|
||||
L4x4_10:
|
||||
cmpw %bp,4(%edx)
|
||||
jg L4x4_11
|
||||
movw %bp,4(%edx)
|
||||
movb %ch,2(%edi)
|
||||
L4x4_11:
|
||||
cmpw %bp,6(%edx)
|
||||
jg L4x4_12
|
||||
movw %bp,6(%edx)
|
||||
movb %ch,3(%edi)
|
||||
L4x4_12:
|
||||
|
||||
cmpw %bp,(%edx,%esi,1)
|
||||
jg L4x4_13
|
||||
movw %bp,(%edx,%esi,1)
|
||||
movb %ch,(%edi,%ebx,1)
|
||||
L4x4_13:
|
||||
cmpw %bp,2(%edx,%esi,1)
|
||||
jg L4x4_14
|
||||
movw %bp,2(%edx,%esi,1)
|
||||
movb %ch,1(%edi,%ebx,1)
|
||||
L4x4_14:
|
||||
cmpw %bp,4(%edx,%esi,1)
|
||||
jg L4x4_15
|
||||
movw %bp,4(%edx,%esi,1)
|
||||
movb %ch,2(%edi,%ebx,1)
|
||||
L4x4_15:
|
||||
cmpw %bp,6(%edx,%esi,1)
|
||||
jg L4x4_16
|
||||
movw %bp,6(%edx,%esi,1)
|
||||
movb %ch,3(%edi,%ebx,1)
|
||||
L4x4_16:
|
||||
|
||||
popl %esi
|
||||
jmp LDone
|
||||
|
||||
// default case, handling any size particle
|
||||
LDefault:
|
||||
|
||||
// count = pix << d_y_aspect_shift;
|
||||
|
||||
movl %eax,%ebx
|
||||
movl %eax,DP_Pix
|
||||
movb C(d_y_aspect_shift),%cl
|
||||
shll %cl,%ebx
|
||||
|
||||
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
|
||||
// {
|
||||
// for (i=0 ; i<pix ; i++)
|
||||
// {
|
||||
// if (pz[i] <= izi)
|
||||
// {
|
||||
// pz[i] = izi;
|
||||
// pdest[i] = color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
LGenRowLoop:
|
||||
movl DP_Pix,%eax
|
||||
|
||||
LGenColLoop:
|
||||
cmpw %bp,-2(%edx,%eax,2)
|
||||
jg LGSkip
|
||||
movw %bp,-2(%edx,%eax,2)
|
||||
movb %ch,-1(%edi,%eax,1)
|
||||
LGSkip:
|
||||
decl %eax // --pix
|
||||
jnz LGenColLoop
|
||||
|
||||
addl C(d_zrowbytes),%edx
|
||||
addl C(screenwidth),%edi
|
||||
|
||||
decl %ebx // --count
|
||||
jnz LGenRowLoop
|
||||
|
||||
LDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
LPop6AndDone:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
LPop1AndDone:
|
||||
fstp %st(0)
|
||||
jmp LDone
|
||||
|
||||
#endif // USE_INTEL_ASM
|
1751
qw/source/d_polysa.S
1751
qw/source/d_polysa.S
File diff suppressed because it is too large
Load diff
|
@ -1,965 +0,0 @@
|
|||
/*
|
||||
d_polyse.c
|
||||
|
||||
routines for drawing sets of polygons sharing the same texture
|
||||
(used for Alias models)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "r_local.h"
|
||||
#include "d_local.h"
|
||||
|
||||
// TODO: put in span spilling to shrink list size
|
||||
// !!! if this is changed, it must be changed in d_polysa.s too !!!
|
||||
#define DPS_MAXSPANS MAXHEIGHT+1
|
||||
// 1 extra for spanpackage that marks end
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct {
|
||||
void *pdest;
|
||||
short *pz;
|
||||
int count;
|
||||
byte *ptex;
|
||||
int sfrac, tfrac, light, zi;
|
||||
} spanpackage_t;
|
||||
|
||||
typedef struct {
|
||||
int isflattop;
|
||||
int numleftedges;
|
||||
int *pleftedgevert0;
|
||||
int *pleftedgevert1;
|
||||
int *pleftedgevert2;
|
||||
int numrightedges;
|
||||
int *prightedgevert0;
|
||||
int *prightedgevert1;
|
||||
int *prightedgevert2;
|
||||
} edgetable;
|
||||
|
||||
int r_p0[6], r_p1[6], r_p2[6];
|
||||
|
||||
byte *d_pcolormap;
|
||||
|
||||
int d_aflatcolor;
|
||||
int d_xdenom;
|
||||
|
||||
edgetable *pedgetable;
|
||||
|
||||
edgetable edgetables[12] = {
|
||||
{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2},
|
||||
{0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},
|
||||
{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
|
||||
{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0},
|
||||
{0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},
|
||||
{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
|
||||
{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1},
|
||||
{0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},
|
||||
{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
|
||||
{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
|
||||
{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
|
||||
{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
|
||||
};
|
||||
|
||||
// FIXME: some of these can become statics
|
||||
int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
|
||||
int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
|
||||
int r_zistepx, r_zistepy;
|
||||
int d_aspancount, d_countextrastep;
|
||||
|
||||
spanpackage_t *a_spans;
|
||||
spanpackage_t *d_pedgespanpackage;
|
||||
static int ystart;
|
||||
byte *d_pdest, *d_ptex;
|
||||
short *d_pz;
|
||||
int d_sfrac, d_tfrac, d_light, d_zi;
|
||||
int d_ptexextrastep, d_sfracextrastep;
|
||||
int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
|
||||
int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
|
||||
int d_sfracbasestep, d_tfracbasestep;
|
||||
int d_ziextrastep, d_zibasestep;
|
||||
int d_pzextrastep, d_pzbasestep;
|
||||
|
||||
typedef struct {
|
||||
int quotient;
|
||||
int remainder;
|
||||
} adivtab_t;
|
||||
|
||||
static adivtab_t adivtab[32 * 32] = {
|
||||
#include "adivtab.h"
|
||||
};
|
||||
|
||||
byte *skintable[MAX_LBM_HEIGHT];
|
||||
int skinwidth;
|
||||
byte *skinstart;
|
||||
|
||||
void D_PolysetDrawSpans8 (spanpackage_t * pspanpackage);
|
||||
void D_PolysetCalcGradients (int skinwidth);
|
||||
void D_DrawSubdiv (void);
|
||||
void D_DrawNonSubdiv (void);
|
||||
void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
|
||||
void D_PolysetSetEdgeTable (void);
|
||||
void D_RasterizeAliasPolySmooth (void);
|
||||
void D_PolysetScanLeftEdge (int height);
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
|
||||
void
|
||||
D_PolysetDraw (void)
|
||||
{
|
||||
spanpackage_t spans[DPS_MAXSPANS + 1 +
|
||||
((CACHE_SIZE - 1) / sizeof (spanpackage_t)) + 1];
|
||||
|
||||
// one extra because of cache line pretouching
|
||||
|
||||
a_spans = (spanpackage_t *)
|
||||
(((long) &spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
|
||||
if (r_affinetridesc.drawtype) {
|
||||
D_DrawSubdiv ();
|
||||
} else {
|
||||
D_DrawNonSubdiv ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
|
||||
{
|
||||
int i, z;
|
||||
short *zbuf;
|
||||
|
||||
for (i = 0; i < numverts; i++, fv++) {
|
||||
// valid triangle coordinates for filling can include the bottom and
|
||||
// right clip edges, due to the fill rule; these shouldn't be drawn
|
||||
if ((fv->v[0] < r_refdef.vrectright) &&
|
||||
(fv->v[1] < r_refdef.vrectbottom)) {
|
||||
z = fv->v[5] >> 16;
|
||||
zbuf = zspantable[fv->v[1]] + fv->v[0];
|
||||
if (z >= *zbuf) {
|
||||
int pix;
|
||||
|
||||
*zbuf = z;
|
||||
pix = skintable[fv->v[3] >> 16][fv->v[2] >> 16];
|
||||
pix = ((byte *) acolormap)[pix + (fv->v[4] & 0xFF00)];
|
||||
d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DrawSubdiv (void)
|
||||
{
|
||||
mtriangle_t *ptri;
|
||||
finalvert_t *pfv, *index0, *index1, *index2;
|
||||
int i;
|
||||
int lnumtriangles;
|
||||
|
||||
pfv = r_affinetridesc.pfinalverts;
|
||||
ptri = r_affinetridesc.ptriangles;
|
||||
lnumtriangles = r_affinetridesc.numtriangles;
|
||||
|
||||
for (i = 0; i < lnumtriangles; i++) {
|
||||
index0 = pfv + ptri[i].vertindex[0];
|
||||
index1 = pfv + ptri[i].vertindex[1];
|
||||
index2 = pfv + ptri[i].vertindex[2];
|
||||
|
||||
if (((index0->v[1] - index1->v[1]) *
|
||||
(index0->v[0] - index2->v[0]) -
|
||||
(index0->v[0] - index1->v[0]) *
|
||||
(index0->v[1] - index2->v[1])) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
d_pcolormap = &((byte *) acolormap)[index0->v[4] & 0xFF00];
|
||||
|
||||
if (ptri[i].facesfront) {
|
||||
D_PolysetRecursiveTriangle (index0->v, index1->v, index2->v);
|
||||
} else {
|
||||
int s0, s1, s2;
|
||||
|
||||
s0 = index0->v[2];
|
||||
s1 = index1->v[2];
|
||||
s2 = index2->v[2];
|
||||
|
||||
if (index0->flags & ALIAS_ONSEAM)
|
||||
index0->v[2] += r_affinetridesc.seamfixupX16;
|
||||
if (index1->flags & ALIAS_ONSEAM)
|
||||
index1->v[2] += r_affinetridesc.seamfixupX16;
|
||||
if (index2->flags & ALIAS_ONSEAM)
|
||||
index2->v[2] += r_affinetridesc.seamfixupX16;
|
||||
|
||||
D_PolysetRecursiveTriangle (index0->v, index1->v, index2->v);
|
||||
|
||||
index0->v[2] = s0;
|
||||
index1->v[2] = s1;
|
||||
index2->v[2] = s2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DrawNonSubdiv (void)
|
||||
{
|
||||
mtriangle_t *ptri;
|
||||
finalvert_t *pfv, *index0, *index1, *index2;
|
||||
int i;
|
||||
int lnumtriangles;
|
||||
|
||||
pfv = r_affinetridesc.pfinalverts;
|
||||
ptri = r_affinetridesc.ptriangles;
|
||||
lnumtriangles = r_affinetridesc.numtriangles;
|
||||
|
||||
for (i = 0; i < lnumtriangles; i++, ptri++) {
|
||||
index0 = pfv + ptri->vertindex[0];
|
||||
index1 = pfv + ptri->vertindex[1];
|
||||
index2 = pfv + ptri->vertindex[2];
|
||||
|
||||
d_xdenom = (index0->v[1] - index1->v[1]) *
|
||||
(index0->v[0] - index2->v[0]) -
|
||||
(index0->v[0] - index1->v[0]) * (index0->v[1] - index2->v[1]);
|
||||
|
||||
if (d_xdenom >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r_p0[0] = index0->v[0]; // u
|
||||
r_p0[1] = index0->v[1]; // v
|
||||
r_p0[2] = index0->v[2]; // s
|
||||
r_p0[3] = index0->v[3]; // t
|
||||
r_p0[4] = index0->v[4]; // light
|
||||
r_p0[5] = index0->v[5]; // iz
|
||||
|
||||
r_p1[0] = index1->v[0];
|
||||
r_p1[1] = index1->v[1];
|
||||
r_p1[2] = index1->v[2];
|
||||
r_p1[3] = index1->v[3];
|
||||
r_p1[4] = index1->v[4];
|
||||
r_p1[5] = index1->v[5];
|
||||
|
||||
r_p2[0] = index2->v[0];
|
||||
r_p2[1] = index2->v[1];
|
||||
r_p2[2] = index2->v[2];
|
||||
r_p2[3] = index2->v[3];
|
||||
r_p2[4] = index2->v[4];
|
||||
r_p2[5] = index2->v[5];
|
||||
|
||||
if (!ptri->facesfront) {
|
||||
if (index0->flags & ALIAS_ONSEAM)
|
||||
r_p0[2] += r_affinetridesc.seamfixupX16;
|
||||
if (index1->flags & ALIAS_ONSEAM)
|
||||
r_p1[2] += r_affinetridesc.seamfixupX16;
|
||||
if (index2->flags & ALIAS_ONSEAM)
|
||||
r_p2[2] += r_affinetridesc.seamfixupX16;
|
||||
}
|
||||
|
||||
D_PolysetSetEdgeTable ();
|
||||
D_RasterizeAliasPolySmooth ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
|
||||
{
|
||||
int *temp;
|
||||
int d;
|
||||
int new[6];
|
||||
int z;
|
||||
short *zbuf;
|
||||
|
||||
d = lp2[0] - lp1[0];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
d = lp2[1] - lp1[1];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
|
||||
d = lp3[0] - lp2[0];
|
||||
if (d < -1 || d > 1)
|
||||
goto split2;
|
||||
d = lp3[1] - lp2[1];
|
||||
if (d < -1 || d > 1)
|
||||
goto split2;
|
||||
|
||||
d = lp1[0] - lp3[0];
|
||||
if (d < -1 || d > 1)
|
||||
goto split3;
|
||||
d = lp1[1] - lp3[1];
|
||||
if (d < -1 || d > 1) {
|
||||
split3:
|
||||
temp = lp1;
|
||||
lp1 = lp3;
|
||||
lp3 = lp2;
|
||||
lp2 = temp;
|
||||
|
||||
goto split;
|
||||
}
|
||||
|
||||
return; // entire tri is filled
|
||||
|
||||
split2:
|
||||
temp = lp1;
|
||||
lp1 = lp2;
|
||||
lp2 = lp3;
|
||||
lp3 = temp;
|
||||
|
||||
split:
|
||||
// split this edge
|
||||
new[0] = (lp1[0] + lp2[0]) >> 1;
|
||||
new[1] = (lp1[1] + lp2[1]) >> 1;
|
||||
new[2] = (lp1[2] + lp2[2]) >> 1;
|
||||
new[3] = (lp1[3] + lp2[3]) >> 1;
|
||||
new[5] = (lp1[5] + lp2[5]) >> 1;
|
||||
|
||||
// draw the point if splitting a leading edge
|
||||
if (lp2[1] > lp1[1])
|
||||
goto nodraw;
|
||||
if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
|
||||
goto nodraw;
|
||||
|
||||
|
||||
z = new[5] >> 16;
|
||||
zbuf = zspantable[new[1]] + new[0];
|
||||
if (z >= *zbuf) {
|
||||
int pix;
|
||||
|
||||
*zbuf = z;
|
||||
pix = d_pcolormap[skintable[new[3] >> 16][new[2] >> 16]];
|
||||
d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;
|
||||
}
|
||||
|
||||
nodraw:
|
||||
// recursively continue
|
||||
D_PolysetRecursiveTriangle (lp3, lp1, new);
|
||||
D_PolysetRecursiveTriangle (lp3, new, lp2);
|
||||
}
|
||||
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
void
|
||||
D_PolysetUpdateTables (void)
|
||||
{
|
||||
int i;
|
||||
byte *s;
|
||||
|
||||
if (r_affinetridesc.skinwidth != skinwidth ||
|
||||
r_affinetridesc.pskin != skinstart) {
|
||||
skinwidth = r_affinetridesc.skinwidth;
|
||||
skinstart = r_affinetridesc.pskin;
|
||||
s = skinstart;
|
||||
for (i = 0; i < MAX_LBM_HEIGHT; i++, s += skinwidth)
|
||||
skintable[i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_PolysetScanLeftEdge (int height)
|
||||
{
|
||||
|
||||
do {
|
||||
d_pedgespanpackage->pdest = d_pdest;
|
||||
d_pedgespanpackage->pz = d_pz;
|
||||
d_pedgespanpackage->count = d_aspancount;
|
||||
d_pedgespanpackage->ptex = d_ptex;
|
||||
|
||||
d_pedgespanpackage->sfrac = d_sfrac;
|
||||
d_pedgespanpackage->tfrac = d_tfrac;
|
||||
|
||||
// FIXME: need to clamp l, s, t, at both ends?
|
||||
d_pedgespanpackage->light = d_light;
|
||||
d_pedgespanpackage->zi = d_zi;
|
||||
|
||||
d_pedgespanpackage++;
|
||||
|
||||
errorterm += erroradjustup;
|
||||
if (errorterm >= 0) {
|
||||
d_pdest += d_pdestextrastep;
|
||||
d_pz += d_pzextrastep;
|
||||
d_aspancount += d_countextrastep;
|
||||
d_ptex += d_ptexextrastep;
|
||||
d_sfrac += d_sfracextrastep;
|
||||
d_ptex += d_sfrac >> 16;
|
||||
|
||||
d_sfrac &= 0xFFFF;
|
||||
d_tfrac += d_tfracextrastep;
|
||||
if (d_tfrac & 0x10000) {
|
||||
d_ptex += r_affinetridesc.skinwidth;
|
||||
d_tfrac &= 0xFFFF;
|
||||
}
|
||||
d_light += d_lightextrastep;
|
||||
d_zi += d_ziextrastep;
|
||||
errorterm -= erroradjustdown;
|
||||
} else {
|
||||
d_pdest += d_pdestbasestep;
|
||||
d_pz += d_pzbasestep;
|
||||
d_aspancount += ubasestep;
|
||||
d_ptex += d_ptexbasestep;
|
||||
d_sfrac += d_sfracbasestep;
|
||||
d_ptex += d_sfrac >> 16;
|
||||
d_sfrac &= 0xFFFF;
|
||||
d_tfrac += d_tfracbasestep;
|
||||
if (d_tfrac & 0x10000) {
|
||||
d_ptex += r_affinetridesc.skinwidth;
|
||||
d_tfrac &= 0xFFFF;
|
||||
}
|
||||
d_light += d_lightbasestep;
|
||||
d_zi += d_zibasestep;
|
||||
}
|
||||
} while (--height);
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
void
|
||||
D_PolysetSetUpForLineScan (fixed8_t startvertu, fixed8_t startvertv,
|
||||
fixed8_t endvertu, fixed8_t endvertv)
|
||||
{
|
||||
double dm, dn;
|
||||
int tm, tn;
|
||||
adivtab_t *ptemp;
|
||||
|
||||
// TODO: implement x86 version
|
||||
|
||||
errorterm = -1;
|
||||
|
||||
tm = endvertu - startvertu;
|
||||
tn = endvertv - startvertv;
|
||||
|
||||
if (((tm <= 16) && (tm >= -15)) && ((tn <= 16) && (tn >= -15))) {
|
||||
ptemp = &adivtab[((tm + 15) << 5) + (tn + 15)];
|
||||
ubasestep = ptemp->quotient;
|
||||
erroradjustup = ptemp->remainder;
|
||||
erroradjustdown = tn;
|
||||
} else {
|
||||
dm = (double) tm;
|
||||
dn = (double) tn;
|
||||
|
||||
FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
|
||||
|
||||
erroradjustdown = dn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_PolysetCalcGradients (int skinwidth)
|
||||
{
|
||||
float xstepdenominv, ystepdenominv, t0, t1;
|
||||
float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
|
||||
|
||||
p00_minus_p20 = r_p0[0] - r_p2[0];
|
||||
p01_minus_p21 = r_p0[1] - r_p2[1];
|
||||
p10_minus_p20 = r_p1[0] - r_p2[0];
|
||||
p11_minus_p21 = r_p1[1] - r_p2[1];
|
||||
|
||||
xstepdenominv = 1.0 / (float) d_xdenom;
|
||||
|
||||
ystepdenominv = -xstepdenominv;
|
||||
|
||||
// ceil () for light so positive steps are exaggerated, negative steps
|
||||
// diminished, pushing us away from underflow toward overflow. Underflow is
|
||||
// very visible, overflow is very unlikely, because of ambient lighting
|
||||
t0 = r_p0[4] - r_p2[4];
|
||||
t1 = r_p1[4] - r_p2[4];
|
||||
r_lstepx = (int)
|
||||
ceil ((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
|
||||
r_lstepy = (int)
|
||||
ceil ((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
|
||||
|
||||
t0 = r_p0[2] - r_p2[2];
|
||||
t1 = r_p1[2] - r_p2[2];
|
||||
r_sstepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
|
||||
xstepdenominv);
|
||||
r_sstepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
|
||||
ystepdenominv);
|
||||
|
||||
t0 = r_p0[3] - r_p2[3];
|
||||
t1 = r_p1[3] - r_p2[3];
|
||||
r_tstepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
|
||||
xstepdenominv);
|
||||
r_tstepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
|
||||
ystepdenominv);
|
||||
|
||||
t0 = r_p0[5] - r_p2[5];
|
||||
t1 = r_p1[5] - r_p2[5];
|
||||
r_zistepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
|
||||
xstepdenominv);
|
||||
r_zistepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
|
||||
ystepdenominv);
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
a_sstepxfrac = r_sstepx << 16;
|
||||
a_tstepxfrac = r_tstepx << 16;
|
||||
#else
|
||||
a_sstepxfrac = r_sstepx & 0xFFFF;
|
||||
a_tstepxfrac = r_tstepx & 0xFFFF;
|
||||
#endif
|
||||
|
||||
a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
byte gelmap[256];
|
||||
|
||||
void
|
||||
InitGel (byte * palette)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
// r = (palette[i*3]>>4);
|
||||
r =
|
||||
(palette[i * 3] + palette[i * 3 + 1] +
|
||||
palette[i * 3 + 2]) / (16 * 3);
|
||||
gelmap[i] = /* 64 */ 0 + r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_PolysetDrawSpans8 (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int lcount;
|
||||
byte *lpdest;
|
||||
byte *lptex;
|
||||
int lsfrac, ltfrac;
|
||||
int llight;
|
||||
int lzi;
|
||||
short *lpz;
|
||||
|
||||
do {
|
||||
lcount = d_aspancount - pspanpackage->count;
|
||||
|
||||
errorterm += erroradjustup;
|
||||
if (errorterm >= 0) {
|
||||
d_aspancount += d_countextrastep;
|
||||
errorterm -= erroradjustdown;
|
||||
} else {
|
||||
d_aspancount += ubasestep;
|
||||
}
|
||||
|
||||
if (lcount) {
|
||||
lpdest = pspanpackage->pdest;
|
||||
lptex = pspanpackage->ptex;
|
||||
lpz = pspanpackage->pz;
|
||||
lsfrac = pspanpackage->sfrac;
|
||||
ltfrac = pspanpackage->tfrac;
|
||||
llight = pspanpackage->light;
|
||||
lzi = pspanpackage->zi;
|
||||
|
||||
do {
|
||||
if ((lzi >> 16) >= *lpz) {
|
||||
*lpdest = ((byte *) acolormap)[*lptex + (llight & 0xFF00)];
|
||||
// gel mapping *lpdest = gelmap[*lpdest];
|
||||
*lpz = lzi >> 16;
|
||||
}
|
||||
lpdest++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
llight += r_lstepx;
|
||||
lptex += a_ststepxwhole;
|
||||
lsfrac += a_sstepxfrac;
|
||||
lptex += lsfrac >> 16;
|
||||
lsfrac &= 0xFFFF;
|
||||
ltfrac += a_tstepxfrac;
|
||||
if (ltfrac & 0x10000) {
|
||||
lptex += r_affinetridesc.skinwidth;
|
||||
ltfrac &= 0xFFFF;
|
||||
}
|
||||
} while (--lcount);
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
} while (pspanpackage->count != -999999);
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
|
||||
void
|
||||
D_PolysetFillSpans8 (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int color;
|
||||
|
||||
// FIXME: do z buffering
|
||||
|
||||
color = d_aflatcolor++;
|
||||
|
||||
while (1) {
|
||||
int lcount;
|
||||
byte *lpdest;
|
||||
|
||||
lcount = pspanpackage->count;
|
||||
|
||||
if (lcount == -1)
|
||||
return;
|
||||
|
||||
if (lcount) {
|
||||
lpdest = pspanpackage->pdest;
|
||||
|
||||
do {
|
||||
*lpdest++ = color;
|
||||
} while (--lcount);
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_RasterizeAliasPolySmooth (void)
|
||||
{
|
||||
int initialleftheight, initialrightheight;
|
||||
int *plefttop, *prighttop, *pleftbottom, *prightbottom;
|
||||
int working_lstepx, originalcount;
|
||||
|
||||
plefttop = pedgetable->pleftedgevert0;
|
||||
prighttop = pedgetable->prightedgevert0;
|
||||
|
||||
pleftbottom = pedgetable->pleftedgevert1;
|
||||
prightbottom = pedgetable->prightedgevert1;
|
||||
|
||||
initialleftheight = pleftbottom[1] - plefttop[1];
|
||||
initialrightheight = prightbottom[1] - prighttop[1];
|
||||
|
||||
// set the s, t, and light gradients, which are consistent across the
|
||||
// triangle, because being a triangle, things are affine
|
||||
D_PolysetCalcGradients (r_affinetridesc.skinwidth);
|
||||
|
||||
// rasterize the polygon
|
||||
|
||||
// scan out the top (and possibly only) part of the left edge
|
||||
D_PolysetSetUpForLineScan (plefttop[0], plefttop[1],
|
||||
pleftbottom[0], pleftbottom[1]);
|
||||
|
||||
d_pedgespanpackage = a_spans;
|
||||
|
||||
ystart = plefttop[1];
|
||||
d_aspancount = plefttop[0] - prighttop[0];
|
||||
|
||||
d_ptex = (byte *) r_affinetridesc.pskin + (plefttop[2] >> 16) +
|
||||
(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_sfrac = (plefttop[2] & 0xFFFF) << 16;
|
||||
d_tfrac = (plefttop[3] & 0xFFFF) << 16;
|
||||
d_pzbasestep = (d_zwidth + ubasestep) << 1;
|
||||
d_pzextrastep = d_pzbasestep + 2;
|
||||
#else
|
||||
d_sfrac = plefttop[2] & 0xFFFF;
|
||||
d_tfrac = plefttop[3] & 0xFFFF;
|
||||
d_pzbasestep = d_zwidth + ubasestep;
|
||||
d_pzextrastep = d_pzbasestep + 1;
|
||||
#endif
|
||||
d_light = plefttop[4];
|
||||
d_zi = plefttop[5];
|
||||
|
||||
d_pdestbasestep = screenwidth + ubasestep;
|
||||
d_pdestextrastep = d_pdestbasestep + 1;
|
||||
d_pdest = (byte *) d_viewbuffer + ystart * screenwidth + plefttop[0];
|
||||
d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
|
||||
|
||||
// TODO: can reuse partial expressions here
|
||||
|
||||
// for negative steps in x along left edge, bias toward overflow rather
|
||||
// than underflow (sort of turning the floor () we did in the gradient
|
||||
// calcs into ceil (), but plus a little bit)
|
||||
if (ubasestep < 0)
|
||||
working_lstepx = r_lstepx - 1;
|
||||
else
|
||||
working_lstepx = r_lstepx;
|
||||
|
||||
d_countextrastep = ubasestep + 1;
|
||||
d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
|
||||
((r_tstepy + r_tstepx * ubasestep) >> 16) * r_affinetridesc.skinwidth;
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
|
||||
#else
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
|
||||
#endif
|
||||
d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
|
||||
d_zibasestep = r_zistepy + r_zistepx * ubasestep;
|
||||
|
||||
d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
|
||||
((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
|
||||
r_affinetridesc.skinwidth;
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) << 16;
|
||||
d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) << 16;
|
||||
#else
|
||||
d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
|
||||
d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
|
||||
#endif
|
||||
d_lightextrastep = d_lightbasestep + working_lstepx;
|
||||
d_ziextrastep = d_zibasestep + r_zistepx;
|
||||
|
||||
D_PolysetScanLeftEdge (initialleftheight);
|
||||
|
||||
// scan out the bottom part of the left edge, if it exists
|
||||
if (pedgetable->numleftedges == 2) {
|
||||
int height;
|
||||
|
||||
plefttop = pleftbottom;
|
||||
pleftbottom = pedgetable->pleftedgevert2;
|
||||
|
||||
D_PolysetSetUpForLineScan (plefttop[0], plefttop[1],
|
||||
pleftbottom[0], pleftbottom[1]);
|
||||
|
||||
height = pleftbottom[1] - plefttop[1];
|
||||
|
||||
// TODO: make this a function; modularize this function in general
|
||||
|
||||
ystart = plefttop[1];
|
||||
d_aspancount = plefttop[0] - prighttop[0];
|
||||
d_ptex = (byte *) r_affinetridesc.pskin + (plefttop[2] >> 16) +
|
||||
(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
|
||||
d_sfrac = 0;
|
||||
d_tfrac = 0;
|
||||
d_light = plefttop[4];
|
||||
d_zi = plefttop[5];
|
||||
|
||||
d_pdestbasestep = screenwidth + ubasestep;
|
||||
d_pdestextrastep = d_pdestbasestep + 1;
|
||||
d_pdest = (byte *) d_viewbuffer + ystart * screenwidth + plefttop[0];
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_pzbasestep = (d_zwidth + ubasestep) << 1;
|
||||
d_pzextrastep = d_pzbasestep + 2;
|
||||
#else
|
||||
d_pzbasestep = d_zwidth + ubasestep;
|
||||
d_pzextrastep = d_pzbasestep + 1;
|
||||
#endif
|
||||
d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
|
||||
|
||||
if (ubasestep < 0)
|
||||
working_lstepx = r_lstepx - 1;
|
||||
else
|
||||
working_lstepx = r_lstepx;
|
||||
|
||||
d_countextrastep = ubasestep + 1;
|
||||
d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
|
||||
((r_tstepy + r_tstepx * ubasestep) >> 16) *
|
||||
r_affinetridesc.skinwidth;
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
|
||||
#else
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
|
||||
#endif
|
||||
d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
|
||||
d_zibasestep = r_zistepy + r_zistepx * ubasestep;
|
||||
|
||||
d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
|
||||
((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
|
||||
r_affinetridesc.skinwidth;
|
||||
#ifdef USE_INTEL_ASM
|
||||
d_sfracextrastep =
|
||||
((r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF) << 16;
|
||||
d_tfracextrastep =
|
||||
((r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF) << 16;
|
||||
#else
|
||||
d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
|
||||
d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
|
||||
#endif
|
||||
d_lightextrastep = d_lightbasestep + working_lstepx;
|
||||
d_ziextrastep = d_zibasestep + r_zistepx;
|
||||
|
||||
D_PolysetScanLeftEdge (height);
|
||||
}
|
||||
// scan out the top (and possibly only) part of the right edge, updating
|
||||
// the count field
|
||||
d_pedgespanpackage = a_spans;
|
||||
|
||||
D_PolysetSetUpForLineScan (prighttop[0], prighttop[1],
|
||||
prightbottom[0], prightbottom[1]);
|
||||
d_aspancount = 0;
|
||||
d_countextrastep = ubasestep + 1;
|
||||
originalcount = a_spans[initialrightheight].count;
|
||||
a_spans[initialrightheight].count = -999999; // mark end of the
|
||||
// spanpackages
|
||||
D_PolysetDrawSpans8 (a_spans);
|
||||
|
||||
// scan out the bottom part of the right edge, if it exists
|
||||
if (pedgetable->numrightedges == 2) {
|
||||
int height;
|
||||
spanpackage_t *pstart;
|
||||
|
||||
pstart = a_spans + initialrightheight;
|
||||
pstart->count = originalcount;
|
||||
|
||||
d_aspancount = prightbottom[0] - prighttop[0];
|
||||
|
||||
prighttop = prightbottom;
|
||||
prightbottom = pedgetable->prightedgevert2;
|
||||
|
||||
height = prightbottom[1] - prighttop[1];
|
||||
|
||||
D_PolysetSetUpForLineScan (prighttop[0], prighttop[1],
|
||||
prightbottom[0], prightbottom[1]);
|
||||
|
||||
d_countextrastep = ubasestep + 1;
|
||||
a_spans[initialrightheight + height].count = -999999;
|
||||
// mark end of the spanpackages
|
||||
D_PolysetDrawSpans8 (pstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_PolysetSetEdgeTable (void)
|
||||
{
|
||||
int edgetableindex;
|
||||
|
||||
edgetableindex = 0; // assume the vertices are already in
|
||||
// top to bottom order
|
||||
|
||||
// determine which edges are right & left, and the order in which
|
||||
// to rasterize them
|
||||
if (r_p0[1] >= r_p1[1]) {
|
||||
if (r_p0[1] == r_p1[1]) {
|
||||
if (r_p0[1] < r_p2[1])
|
||||
pedgetable = &edgetables[2];
|
||||
else
|
||||
pedgetable = &edgetables[5];
|
||||
|
||||
return;
|
||||
} else {
|
||||
edgetableindex = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (r_p0[1] == r_p2[1]) {
|
||||
if (edgetableindex)
|
||||
pedgetable = &edgetables[8];
|
||||
else
|
||||
pedgetable = &edgetables[9];
|
||||
|
||||
return;
|
||||
} else if (r_p1[1] == r_p2[1]) {
|
||||
if (edgetableindex)
|
||||
pedgetable = &edgetables[10];
|
||||
else
|
||||
pedgetable = &edgetables[11];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (r_p0[1] > r_p2[1])
|
||||
edgetableindex += 2;
|
||||
|
||||
if (r_p1[1] > r_p2[1])
|
||||
edgetableindex += 4;
|
||||
|
||||
pedgetable = &edgetables[edgetableindex];
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
void
|
||||
D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
|
||||
{
|
||||
int d;
|
||||
int new[6];
|
||||
int ofs;
|
||||
|
||||
d = lp2[0] - lp1[0];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
d = lp2[1] - lp1[1];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
|
||||
return; // line is completed
|
||||
|
||||
split:
|
||||
// split this edge
|
||||
new[0] = (lp1[0] + lp2[0]) >> 1;
|
||||
new[1] = (lp1[1] + lp2[1]) >> 1;
|
||||
new[5] = (lp1[5] + lp2[5]) >> 1;
|
||||
new[2] = (lp1[2] + lp2[2]) >> 1;
|
||||
new[3] = (lp1[3] + lp2[3]) >> 1;
|
||||
new[4] = (lp1[4] + lp2[4]) >> 1;
|
||||
|
||||
// draw the point
|
||||
ofs = d_scantable[new[1]] + new[0];
|
||||
if (new[5] > d_pzbuffer[ofs]) {
|
||||
int pix;
|
||||
|
||||
d_pzbuffer[ofs] = new[5];
|
||||
pix = skintable[new[3] >> 16][new[2] >> 16];
|
||||
// pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)];
|
||||
d_viewbuffer[ofs] = pix;
|
||||
}
|
||||
// recursively continue
|
||||
D_PolysetRecursiveDrawLine (lp1, new);
|
||||
D_PolysetRecursiveDrawLine (new, lp2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
|
||||
{
|
||||
int d;
|
||||
int new[4];
|
||||
|
||||
d = lp2[0] - lp1[0];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
d = lp2[1] - lp1[1];
|
||||
if (d < -1 || d > 1)
|
||||
goto split;
|
||||
return;
|
||||
|
||||
split:
|
||||
// split this edge
|
||||
new[0] = (lp1[0] + lp2[0]) >> 1;
|
||||
new[1] = (lp1[1] + lp2[1]) >> 1;
|
||||
new[5] = (lp1[5] + lp2[5]) >> 1;
|
||||
new[2] = (lp1[2] + lp2[2]) >> 1;
|
||||
new[3] = (lp1[3] + lp2[3]) >> 1;
|
||||
new[4] = (lp1[4] + lp2[4]) >> 1;
|
||||
|
||||
D_PolysetRecursiveDrawLine (new, lp3);
|
||||
|
||||
// recursively continue
|
||||
D_PolysetRecursiveTriangle (lp1, new, lp3);
|
||||
D_PolysetRecursiveTriangle (new, lp2, lp3);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
d_scana.S
|
||||
|
||||
x86 assembly-language turbulent texture mapping code
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// turbulent texture mapping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawTurbulent8Span)
|
||||
C(D_DrawTurbulent8Span):
|
||||
pushl %ebp // preserve caller's stack frame pointer
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl C(r_turb_s),%esi
|
||||
movl C(r_turb_t),%ecx
|
||||
movl C(r_turb_pdest),%edi
|
||||
movl C(r_turb_spancount),%ebx
|
||||
|
||||
Llp:
|
||||
movl %ecx,%eax
|
||||
movl %esi,%edx
|
||||
sarl $16,%eax
|
||||
movl C(r_turb_turb),%ebp
|
||||
sarl $16,%edx
|
||||
andl $(CYCLE-1),%eax
|
||||
andl $(CYCLE-1),%edx
|
||||
movl (%ebp,%eax,4),%eax
|
||||
movl (%ebp,%edx,4),%edx
|
||||
addl %esi,%eax
|
||||
sarl $16,%eax
|
||||
addl %ecx,%edx
|
||||
sarl $16,%edx
|
||||
andl $(TURB_TEX_SIZE-1),%eax
|
||||
andl $(TURB_TEX_SIZE-1),%edx
|
||||
shll $6,%edx
|
||||
movl C(r_turb_pbase),%ebp
|
||||
addl %eax,%edx
|
||||
incl %edi
|
||||
addl C(r_turb_sstep),%esi
|
||||
addl C(r_turb_tstep),%ecx
|
||||
movb (%ebp,%edx,1),%dl
|
||||
decl %ebx
|
||||
movb %dl,-1(%edi)
|
||||
jnz Llp
|
||||
|
||||
movl %edi,C(r_turb_pdest)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebp // restore caller's stack frame pointer
|
||||
ret
|
||||
|
||||
#endif // USE_INTEL_ASM
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
d_sky.c
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_local.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#define SKY_SPAN_SHIFT 5
|
||||
#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
|
||||
|
||||
|
||||
void
|
||||
D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
||||
{
|
||||
float wu, wv, temp;
|
||||
vec3_t end;
|
||||
|
||||
if (r_refdef.vrect.width >= r_refdef.vrect.height)
|
||||
temp = (float) r_refdef.vrect.width;
|
||||
else
|
||||
temp = (float) r_refdef.vrect.height;
|
||||
|
||||
wu = 8192.0 * (float) (u - ((int) vid.width >> 1)) / temp;
|
||||
wv = 8192.0 * (float) (((int) vid.height >> 1) - v) / temp;
|
||||
|
||||
end[0] = 4096 * vpn[0] + wu * vright[0] + wv * vup[0];
|
||||
end[1] = 4096 * vpn[1] + wu * vright[1] + wv * vup[1];
|
||||
end[2] = 4096 * vpn[2] + wu * vright[2] + wv * vup[2];
|
||||
end[2] *= 3;
|
||||
VectorNormalize (end);
|
||||
|
||||
temp = skytime * skyspeed; // TODO: add D_SetupFrame & set this
|
||||
// there
|
||||
*s = (int) ((temp + 6 * (SKYSIZE / 2 - 1) * end[0]) * 0x10000);
|
||||
*t = (int) ((temp + 6 * (SKYSIZE / 2 - 1) * end[1]) * 0x10000);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DrawSkyScans8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned char *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (unsigned char *) ((byte *) d_viewbuffer +
|
||||
(screenwidth * pspan->v) + pspan->u);
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
// calculate the initial s & t
|
||||
u = pspan->u;
|
||||
v = pspan->v;
|
||||
D_Sky_uv_To_st (u, v, &s, &t);
|
||||
|
||||
do {
|
||||
if (count >= SKY_SPAN_MAX)
|
||||
spancount = SKY_SPAN_MAX;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count) {
|
||||
u += spancount;
|
||||
|
||||
// calculate s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) >> SKY_SPAN_SHIFT;
|
||||
tstep = (tnext - t) >> SKY_SPAN_SHIFT;
|
||||
} else {
|
||||
// calculate s and t at last pixel in span,
|
||||
// calculate s and t steps across span by division
|
||||
spancountminus1 = (float) (spancount - 1);
|
||||
|
||||
if (spancountminus1 > 0) {
|
||||
u += spancountminus1;
|
||||
D_Sky_uv_To_st (u, v, &snext, &tnext);
|
||||
|
||||
sstep = (snext - s) / spancountminus1;
|
||||
tstep = (tnext - t) / spancountminus1;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
*pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) +
|
||||
((s & R_SKY_SMASK) >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
|
@ -1,907 +0,0 @@
|
|||
/*
|
||||
d_spr8.S
|
||||
|
||||
x86 assembly-language horizontal 8-bpp transparent span-drawing code.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with transparency.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $2048,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $2048,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $2048,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $2048,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_SpriteDrawSpans)
|
||||
C(D_SpriteDrawSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock
|
||||
// and span list pointers, and 1/z step in 0.32 fixed-point
|
||||
//
|
||||
// FIXME: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_8
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_8
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_8
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(3)
|
||||
fstps sdivz8stepu
|
||||
fstps zi8stepu
|
||||
fstps tdivz8stepu
|
||||
fistpl izistep
|
||||
movl izistep,%eax
|
||||
rorl $16,%eax // put upper 16 bits in low word
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
movl %eax,izistep
|
||||
|
||||
cmpl $0,%ecx
|
||||
jle LNextSpan
|
||||
|
||||
LSpanLoop:
|
||||
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl sspan_t_v(%ebx)
|
||||
fildl sspan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
|
||||
fld %st(0) // FIXME: get rid of stall on FMUL?
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(1)
|
||||
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z
|
||||
fxch %st(1)
|
||||
|
||||
fistpl izi // 0.32 fixed-point 1/z
|
||||
movl izi,%ebp
|
||||
|
||||
//
|
||||
// set pz to point to the first z-buffer pixel in the span
|
||||
//
|
||||
rorl $16,%ebp // put upper 16 bits in low word
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
movl %ebp,izi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
imull C(d_zrowbytes)
|
||||
shll $1,%ebp // a word per pixel
|
||||
addl C(d_pzbuffer),%eax
|
||||
addl %ebp,%eax
|
||||
movl %eax,pz
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ebp
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
pushl %ebx // preserve spans pointer
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ebp,%edi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
addl %ebp,%edi // pdest = &pdestspan[scans->u];
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1
|
||||
flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1
|
||||
fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1
|
||||
fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
addl %ebx,%esi
|
||||
imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 8-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
subl $8,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
pushl %ecx // remember count of remaining pixels
|
||||
movl C(tadjust),%ecx
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $2048,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $19,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $19,%eax // tstep >>= 16;
|
||||
jz LIsZero
|
||||
imull %ebx,%eax // (tstep >> 16) * cachewidth;
|
||||
LIsZero:
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $13,%ebp // left-justify sstep fractional part
|
||||
movl %ebp,sstep
|
||||
movl sfracf,%ebx
|
||||
shll $13,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
movl %ecx,tstep
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp1
|
||||
movb (%esi),%al // get first source texel
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp1
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi) // store first dest pixel
|
||||
Lp1:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %eax,%eax // turn tstep carry into -1 (0 if none)
|
||||
addl sstep,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%eax,4),%esi // point to next source texel
|
||||
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp2
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp2
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp2:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp3
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp3
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp3:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp4
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp4
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp4:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp5
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp5
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp5:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
popl %eax
|
||||
cmpl $8,%eax // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %eax
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %eax,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // _d_zistepu | spancountminus1
|
||||
fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1
|
||||
faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1
|
||||
fxch %st(1) // scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
flds fp_64k // 64k | _d_sdivzstepu*scm1
|
||||
fxch %st(1) // _d_sdivzstepu*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
pushl %eax
|
||||
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp6
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp6
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp6:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp7
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp7
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp7:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp8
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp8
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp8:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
addl $8,%edi
|
||||
addl $16,%ecx
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl %ecx,pz
|
||||
movl %ebp,izi
|
||||
|
||||
popl %ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx // are there multiple segments remaining?
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movl C(tadjust),%ebx
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $2048,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1)
|
||||
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl spr8entryvec_table(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
pushl %ebx // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
jz LIsZeroLast
|
||||
imull %ebx,%edx // (tstep >> 16) * cachewidth;
|
||||
LIsZeroLast:
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ebp,sstep
|
||||
movl %ecx,%edx
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
ret // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movl pz,%ecx
|
||||
subl $7,%edi // adjust for hardwired offset
|
||||
subl $14,%ecx
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry2_8
|
||||
Spr8Entry2_8:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
subl $12,%ecx
|
||||
movb (%esi),%al
|
||||
jmp LLEntry2_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry3_8
|
||||
Spr8Entry3_8:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
subl $10,%ecx
|
||||
jmp LLEntry3_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry4_8
|
||||
Spr8Entry4_8:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
subl $8,%ecx
|
||||
jmp LLEntry4_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry5_8
|
||||
Spr8Entry5_8:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
subl $6,%ecx
|
||||
jmp LLEntry5_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry6_8
|
||||
Spr8Entry6_8:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
subl $4,%ecx
|
||||
jmp LLEntry6_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry7_8
|
||||
Spr8Entry7_8:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
subl $2,%ecx
|
||||
jmp LLEntry7_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry8_8
|
||||
Spr8Entry8_8:
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp9
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp9
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi)
|
||||
Lp9:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry7_8:
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp10
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp10
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp10:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry6_8:
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp11
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp11
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp11:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry5_8:
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp12
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp12
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp12:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry4_8:
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp13
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp13
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp13:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry3_8:
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp14
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp14
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp14:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry2_8:
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp15
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp15
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp15:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
LEndSpan:
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp16
|
||||
movb (%esi),%al // load first texel in segment
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp16
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp16:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
popl %ebx // restore spans pointer
|
||||
LNextSpan:
|
||||
addl $(sspan_t_size),%ebx // point to next span
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
cmpl $0,%ecx // any more spans?
|
||||
jg LSpanLoop // yes
|
||||
jz LNextSpan // yes, but this one's empty
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // USE_INTEL_ASM
|
|
@ -1,416 +0,0 @@
|
|||
/*
|
||||
d_sprite.c
|
||||
|
||||
software top-level rasterization driver module for drawing sprites
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_local.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
static int sprite_height;
|
||||
static int minindex, maxindex;
|
||||
static sspan_t *sprite_spans;
|
||||
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
|
||||
void
|
||||
D_SpriteDrawSpans (sspan_t *pspan)
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase, *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
byte btemp;
|
||||
short *pz;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
pbase = cacheblock;
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (byte *) d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
|
||||
pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = d_sdivzorigin + dv * d_sdivzstepv + du * d_sdivzstepu;
|
||||
tdivz = d_tdivzorigin + dv * d_tdivzstepv + du * d_tdivzstepu;
|
||||
zi = d_ziorigin + dv * d_zistepv + du * d_zistepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izi = (int) (zi * 0x8000 * 0x10000);
|
||||
|
||||
s = (int) (sdivz * z) + sadjust;
|
||||
if (s > bbextents)
|
||||
s = bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int) (tdivz * z) + tadjust;
|
||||
if (t > bbextentt)
|
||||
t = bbextentt;
|
||||
else if (t < 0)
|
||||
t = 0;
|
||||
|
||||
do {
|
||||
// calculate s and t at the far end of the span
|
||||
if (count >= 8)
|
||||
spancount = 8;
|
||||
else
|
||||
spancount = count;
|
||||
|
||||
count -= spancount;
|
||||
|
||||
if (count) {
|
||||
// calculate s/z, t/z, zi->fixed s and t at far end of span,
|
||||
// calculate s and t steps across span by shifting
|
||||
sdivz += sdivz8stepu;
|
||||
tdivz += tdivz8stepu;
|
||||
zi += zi8stepu;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from
|
||||
// from causing overstepping & running off the
|
||||
// edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
} else {
|
||||
// calculate s/z, t/z, zi->fixed s and t at last pixel in
|
||||
// span (so can't step off polygon), clamp, calculate s and t
|
||||
// steps across span by division, biasing steps low so we
|
||||
// don't run off the texture
|
||||
spancountminus1 = (float) (spancount - 1);
|
||||
sdivz += d_sdivzstepu * spancountminus1;
|
||||
tdivz += d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * spancountminus1;
|
||||
z = (float) 0x10000 / zi; // prescale to 16.16 fixed-point
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0 steps
|
||||
// from from causing overstepping &
|
||||
// running off the edge of the texture
|
||||
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
if (tnext > bbextentt)
|
||||
tnext = bbextentt;
|
||||
else if (tnext < 8)
|
||||
tnext = 8; // guard against round-off error on
|
||||
// <0 steps
|
||||
|
||||
if (spancount > 1) {
|
||||
sstep = (snext - s) / (spancount - 1);
|
||||
tstep = (tnext - t) / (spancount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
|
||||
if (btemp != 255) {
|
||||
if (*pz <= (izi >> 16)) {
|
||||
*pz = izi >> 16;
|
||||
*pdest = btemp;
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
D_SpriteScanLeftEdge (void)
|
||||
{
|
||||
int i, v, itop, ibottom, lmaxindex;
|
||||
emitpoint_t *pvert, *pnext;
|
||||
sspan_t *pspan;
|
||||
float du, dv, vtop, vbottom, slope;
|
||||
fixed16_t u, u_step;
|
||||
|
||||
pspan = sprite_spans;
|
||||
i = minindex;
|
||||
if (i == 0)
|
||||
i = r_spritedesc.nump;
|
||||
|
||||
lmaxindex = maxindex;
|
||||
if (lmaxindex == 0)
|
||||
lmaxindex = r_spritedesc.nump;
|
||||
|
||||
vtop = ceil (r_spritedesc.pverts[i].v);
|
||||
|
||||
do {
|
||||
pvert = &r_spritedesc.pverts[i];
|
||||
pnext = pvert - 1;
|
||||
|
||||
vbottom = ceil (pnext->v);
|
||||
|
||||
if (vtop < vbottom) {
|
||||
du = pnext->u - pvert->u;
|
||||
dv = pnext->v - pvert->v;
|
||||
slope = du / dv;
|
||||
u_step = (int) (slope * 0x10000);
|
||||
// adjust u to ceil the integer portion
|
||||
u = (int) ((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) +
|
||||
(0x10000 - 1);
|
||||
itop = (int) vtop;
|
||||
ibottom = (int) vbottom;
|
||||
|
||||
for (v = itop; v < ibottom; v++) {
|
||||
pspan->u = u >> 16;
|
||||
pspan->v = v;
|
||||
u += u_step;
|
||||
pspan++;
|
||||
}
|
||||
}
|
||||
|
||||
vtop = vbottom;
|
||||
|
||||
i--;
|
||||
if (i == 0)
|
||||
i = r_spritedesc.nump;
|
||||
|
||||
} while (i != lmaxindex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_SpriteScanRightEdge (void)
|
||||
{
|
||||
int i, v, itop, ibottom;
|
||||
emitpoint_t *pvert, *pnext;
|
||||
sspan_t *pspan;
|
||||
float du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext;
|
||||
fixed16_t u, u_step;
|
||||
|
||||
pspan = sprite_spans;
|
||||
i = minindex;
|
||||
|
||||
vvert = r_spritedesc.pverts[i].v;
|
||||
if (vvert < r_refdef.fvrecty_adj)
|
||||
vvert = r_refdef.fvrecty_adj;
|
||||
if (vvert > r_refdef.fvrectbottom_adj)
|
||||
vvert = r_refdef.fvrectbottom_adj;
|
||||
|
||||
vtop = ceil (vvert);
|
||||
|
||||
do {
|
||||
pvert = &r_spritedesc.pverts[i];
|
||||
pnext = pvert + 1;
|
||||
|
||||
vnext = pnext->v;
|
||||
if (vnext < r_refdef.fvrecty_adj)
|
||||
vnext = r_refdef.fvrecty_adj;
|
||||
if (vnext > r_refdef.fvrectbottom_adj)
|
||||
vnext = r_refdef.fvrectbottom_adj;
|
||||
|
||||
vbottom = ceil (vnext);
|
||||
|
||||
if (vtop < vbottom) {
|
||||
uvert = pvert->u;
|
||||
if (uvert < r_refdef.fvrectx_adj)
|
||||
uvert = r_refdef.fvrectx_adj;
|
||||
if (uvert > r_refdef.fvrectright_adj)
|
||||
uvert = r_refdef.fvrectright_adj;
|
||||
|
||||
unext = pnext->u;
|
||||
if (unext < r_refdef.fvrectx_adj)
|
||||
unext = r_refdef.fvrectx_adj;
|
||||
if (unext > r_refdef.fvrectright_adj)
|
||||
unext = r_refdef.fvrectright_adj;
|
||||
|
||||
du = unext - uvert;
|
||||
dv = vnext - vvert;
|
||||
slope = du / dv;
|
||||
u_step = (int) (slope * 0x10000);
|
||||
// adjust u to ceil the integer portion
|
||||
u = (int) ((uvert + (slope * (vtop - vvert))) * 0x10000) +
|
||||
(0x10000 - 1);
|
||||
itop = (int) vtop;
|
||||
ibottom = (int) vbottom;
|
||||
|
||||
for (v = itop; v < ibottom; v++) {
|
||||
pspan->count = (u >> 16) - pspan->u;
|
||||
u += u_step;
|
||||
pspan++;
|
||||
}
|
||||
}
|
||||
|
||||
vtop = vbottom;
|
||||
vvert = vnext;
|
||||
|
||||
i++;
|
||||
if (i == r_spritedesc.nump)
|
||||
i = 0;
|
||||
|
||||
} while (i != maxindex);
|
||||
|
||||
pspan->count = DS_SPAN_LIST_END; // mark the end of the span list
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_SpriteCalculateGradients (void)
|
||||
{
|
||||
vec3_t p_normal, p_saxis, p_taxis, p_temp1;
|
||||
float distinv;
|
||||
|
||||
TransformVector (r_spritedesc.vpn, p_normal);
|
||||
TransformVector (r_spritedesc.vright, p_saxis);
|
||||
TransformVector (r_spritedesc.vup, p_taxis);
|
||||
VectorInverse (p_taxis);
|
||||
|
||||
distinv = 1.0 / (-DotProduct (modelorg, r_spritedesc.vpn));
|
||||
|
||||
d_sdivzstepu = p_saxis[0] * xscaleinv;
|
||||
d_tdivzstepu = p_taxis[0] * xscaleinv;
|
||||
|
||||
d_sdivzstepv = -p_saxis[1] * yscaleinv;
|
||||
d_tdivzstepv = -p_taxis[1] * yscaleinv;
|
||||
|
||||
d_zistepu = p_normal[0] * xscaleinv * distinv;
|
||||
d_zistepv = -p_normal[1] * yscaleinv * distinv;
|
||||
|
||||
d_sdivzorigin = p_saxis[2] - xcenter * d_sdivzstepu -
|
||||
ycenter * d_sdivzstepv;
|
||||
d_tdivzorigin = p_taxis[2] - xcenter * d_tdivzstepu -
|
||||
ycenter * d_tdivzstepv;
|
||||
d_ziorigin = p_normal[2] * distinv - xcenter * d_zistepu -
|
||||
ycenter * d_zistepv;
|
||||
|
||||
TransformVector (modelorg, p_temp1);
|
||||
|
||||
sadjust = ((fixed16_t) (DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
(-(cachewidth >> 1) << 16);
|
||||
tadjust = ((fixed16_t) (DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
|
||||
(-(sprite_height >> 1) << 16);
|
||||
|
||||
// -1 (-epsilon) so we never wander off the edge of the texture
|
||||
bbextents = (cachewidth << 16) - 1;
|
||||
bbextentt = (sprite_height << 16) - 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_DrawSprite (void)
|
||||
{
|
||||
int i, nump;
|
||||
float ymin, ymax;
|
||||
emitpoint_t *pverts;
|
||||
sspan_t spans[MAXHEIGHT + 1];
|
||||
|
||||
sprite_spans = spans;
|
||||
|
||||
// find the top and bottom vertices, and make sure there's at least one
|
||||
// scan to draw
|
||||
ymin = 999999.9;
|
||||
ymax = -999999.9;
|
||||
pverts = r_spritedesc.pverts;
|
||||
|
||||
for (i = 0; i < r_spritedesc.nump; i++) {
|
||||
if (pverts->v < ymin) {
|
||||
ymin = pverts->v;
|
||||
minindex = i;
|
||||
}
|
||||
|
||||
if (pverts->v > ymax) {
|
||||
ymax = pverts->v;
|
||||
maxindex = i;
|
||||
}
|
||||
|
||||
pverts++;
|
||||
}
|
||||
|
||||
ymin = ceil (ymin);
|
||||
ymax = ceil (ymax);
|
||||
|
||||
if (ymin >= ymax)
|
||||
return; // doesn't cross any scans at all
|
||||
|
||||
cachewidth = r_spritedesc.pspriteframe->width;
|
||||
sprite_height = r_spritedesc.pspriteframe->height;
|
||||
cacheblock = (byte *) & r_spritedesc.pspriteframe->pixels[0];
|
||||
|
||||
// copy the first vertex to the last vertex, so we don't have to deal with
|
||||
// wrapping
|
||||
nump = r_spritedesc.nump;
|
||||
pverts = r_spritedesc.pverts;
|
||||
pverts[nump] = pverts[0];
|
||||
|
||||
D_SpriteCalculateGradients ();
|
||||
D_SpriteScanLeftEdge ();
|
||||
D_SpriteScanRightEdge ();
|
||||
D_SpriteDrawSpans (sprite_spans);
|
||||
}
|
|
@ -1,325 +0,0 @@
|
|||
/*
|
||||
d_surf.c
|
||||
|
||||
rasterization driver surface heap manager
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "d_local.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "r_local.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
float surfscale;
|
||||
qboolean r_cache_thrash; // set if surface cache is thrashing
|
||||
|
||||
int sc_size;
|
||||
surfcache_t *sc_rover, *sc_base;
|
||||
|
||||
#define GUARDSIZE 4
|
||||
|
||||
|
||||
void *
|
||||
D_SurfaceCacheAddress (void)
|
||||
{
|
||||
return sc_base;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
D_SurfaceCacheForRes (int width, int height)
|
||||
{
|
||||
int size, pix;
|
||||
|
||||
if (COM_CheckParm ("-surfcachesize")) {
|
||||
size = atoi (com_argv[COM_CheckParm ("-surfcachesize") + 1]) * 1024;
|
||||
return size;
|
||||
}
|
||||
|
||||
size = SURFCACHE_SIZE_AT_320X200;
|
||||
|
||||
pix = width * height;
|
||||
if (pix > 64000)
|
||||
size += (pix - 64000) * 3;
|
||||
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_CheckCacheGuard (void)
|
||||
{
|
||||
byte *s;
|
||||
int i;
|
||||
|
||||
s = (byte *) sc_base + sc_size;
|
||||
for (i = 0; i < GUARDSIZE; i++)
|
||||
if (s[i] != (byte) i)
|
||||
Sys_Error ("D_CheckCacheGuard: failed");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_ClearCacheGuard (void)
|
||||
{
|
||||
byte *s;
|
||||
int i;
|
||||
|
||||
s = (byte *) sc_base + sc_size;
|
||||
for (i = 0; i < GUARDSIZE; i++)
|
||||
s[i] = (byte) i;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_InitCaches (void *buffer, int size)
|
||||
{
|
||||
// if (!msg_suppress_1)
|
||||
// Con_Printf ("%ik surface cache\n", size/1024);
|
||||
|
||||
sc_size = size - GUARDSIZE;
|
||||
sc_base = (surfcache_t *) buffer;
|
||||
sc_rover = sc_base;
|
||||
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
|
||||
d_pzbuffer = vid.zbuffer;
|
||||
|
||||
D_ClearCacheGuard ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_FlushCaches (void)
|
||||
{
|
||||
surfcache_t *c;
|
||||
|
||||
if (!sc_base)
|
||||
return;
|
||||
|
||||
for (c = sc_base; c; c = c->next) {
|
||||
if (c->owner)
|
||||
*c->owner = NULL;
|
||||
}
|
||||
|
||||
sc_rover = sc_base;
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
}
|
||||
|
||||
|
||||
surfcache_t *
|
||||
D_SCAlloc (int width, int size)
|
||||
{
|
||||
surfcache_t *new;
|
||||
qboolean wrapped_this_time;
|
||||
|
||||
if ((width < 0) || (width > 256))
|
||||
Sys_Error ("D_SCAlloc: bad cache width %d\n", width);
|
||||
|
||||
if ((size <= 0) || (size > 0x10000))
|
||||
Sys_Error ("D_SCAlloc: bad cache size %d\n", size);
|
||||
|
||||
/* This adds the offset of data[0] in the surfcache_t struct. */
|
||||
size += (int) ((surfcache_t *) 0)->data;
|
||||
|
||||
#define SIZE_ALIGN (sizeof(surfcache_t*)-1)
|
||||
size = (size + SIZE_ALIGN) & ~SIZE_ALIGN;
|
||||
#undef SIZE_ALIGN
|
||||
size = (size + 3) & ~3;
|
||||
if (size > sc_size)
|
||||
Sys_Error ("D_SCAlloc: %i > cache size", size);
|
||||
|
||||
// if there is not size bytes after the rover, reset to the start
|
||||
wrapped_this_time = false;
|
||||
|
||||
if (!sc_rover || (byte *) sc_rover - (byte *) sc_base > sc_size - size) {
|
||||
if (sc_rover) {
|
||||
wrapped_this_time = true;
|
||||
}
|
||||
sc_rover = sc_base;
|
||||
}
|
||||
// colect and free surfcache_t blocks until the rover block is large enough
|
||||
new = sc_rover;
|
||||
if (sc_rover->owner)
|
||||
*sc_rover->owner = NULL;
|
||||
|
||||
while (new->size < size) {
|
||||
// free another
|
||||
sc_rover = sc_rover->next;
|
||||
if (!sc_rover)
|
||||
Sys_Error ("D_SCAlloc: hit the end of memory");
|
||||
if (sc_rover->owner)
|
||||
*sc_rover->owner = NULL;
|
||||
|
||||
new->size += sc_rover->size;
|
||||
new->next = sc_rover->next;
|
||||
}
|
||||
|
||||
// create a fragment out of any leftovers
|
||||
if (new->size - size > 256) {
|
||||
sc_rover = (surfcache_t *) ((byte *) new + size);
|
||||
sc_rover->size = new->size - size;
|
||||
sc_rover->next = new->next;
|
||||
sc_rover->width = 0;
|
||||
sc_rover->owner = NULL;
|
||||
new->next = sc_rover;
|
||||
new->size = size;
|
||||
} else
|
||||
sc_rover = new->next;
|
||||
|
||||
new->width = width;
|
||||
// DEBUG
|
||||
if (width > 0)
|
||||
new->height = (size - sizeof (*new) + sizeof (new->data)) / width;
|
||||
|
||||
new->owner = NULL; // should be set properly after return
|
||||
|
||||
if (d_roverwrapped) {
|
||||
if (wrapped_this_time || (sc_rover >= d_initial_rover))
|
||||
r_cache_thrash = true;
|
||||
} else if (wrapped_this_time) {
|
||||
d_roverwrapped = true;
|
||||
}
|
||||
|
||||
D_CheckCacheGuard (); // DEBUG
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D_SCDump (void)
|
||||
{
|
||||
surfcache_t *test;
|
||||
|
||||
for (test = sc_base; test; test = test->next) {
|
||||
if (test == sc_rover)
|
||||
Sys_Printf ("ROVER:\n");
|
||||
Sys_Printf ("%p : %i bytes %i width\n", test, test->size,
|
||||
test->width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if the num is not a power of 2, assume it will not repeat
|
||||
int
|
||||
MaskForNum (int num)
|
||||
{
|
||||
if (num == 128)
|
||||
return 127;
|
||||
if (num == 64)
|
||||
return 63;
|
||||
if (num == 32)
|
||||
return 31;
|
||||
if (num == 16)
|
||||
return 15;
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
D_log2 (int num)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = 0;
|
||||
|
||||
while (num >>= 1)
|
||||
c++;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
surfcache_t *
|
||||
D_CacheSurface (msurface_t *surface, int miplevel)
|
||||
{
|
||||
surfcache_t *cache;
|
||||
|
||||
// if the surface is animating or flashing, flush the cache
|
||||
r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture);
|
||||
r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
|
||||
r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
|
||||
r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
|
||||
r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]];
|
||||
|
||||
// see if the cache holds apropriate data
|
||||
cache = surface->cachespots[miplevel];
|
||||
|
||||
if (cache && !cache->dlight && surface->dlightframe != r_framecount
|
||||
&& cache->texture == r_drawsurf.texture
|
||||
&& cache->lightadj[0] == r_drawsurf.lightadj[0]
|
||||
&& cache->lightadj[1] == r_drawsurf.lightadj[1]
|
||||
&& cache->lightadj[2] == r_drawsurf.lightadj[2]
|
||||
&& cache->lightadj[3] == r_drawsurf.lightadj[3])
|
||||
return cache;
|
||||
|
||||
// determine shape of surface
|
||||
surfscale = 1.0 / (1 << miplevel);
|
||||
r_drawsurf.surfmip = miplevel;
|
||||
r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
|
||||
r_drawsurf.rowbytes = r_drawsurf.surfwidth;
|
||||
r_drawsurf.surfheight = surface->extents[1] >> miplevel;
|
||||
|
||||
// allocate memory if needed
|
||||
if (!cache) // if a texture just animated, don't
|
||||
// reallocate it
|
||||
{
|
||||
cache = D_SCAlloc (r_drawsurf.surfwidth,
|
||||
r_drawsurf.surfwidth * r_drawsurf.surfheight);
|
||||
surface->cachespots[miplevel] = cache;
|
||||
cache->owner = &surface->cachespots[miplevel];
|
||||
cache->mipscale = surfscale;
|
||||
}
|
||||
|
||||
if (surface->dlightframe == r_framecount)
|
||||
cache->dlight = 1;
|
||||
else
|
||||
cache->dlight = 0;
|
||||
|
||||
r_drawsurf.surfdat = (pixel_t *) cache->data;
|
||||
|
||||
cache->texture = r_drawsurf.texture;
|
||||
cache->lightadj[0] = r_drawsurf.lightadj[0];
|
||||
cache->lightadj[1] = r_drawsurf.lightadj[1];
|
||||
cache->lightadj[2] = r_drawsurf.lightadj[2];
|
||||
cache->lightadj[3] = r_drawsurf.lightadj[3];
|
||||
|
||||
// draw and light the surface texture
|
||||
r_drawsurf.surf = surface;
|
||||
|
||||
c_surf++;
|
||||
R_DrawSurface ();
|
||||
|
||||
return surface->cachespots[miplevel];
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
/*
|
||||
d_varsa.S
|
||||
|
||||
(description)
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "QF/asm_i386.h"
|
||||
#include "quakeasm.h"
|
||||
#include "asm_draw.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#ifdef USE_INTEL_ASM
|
||||
|
||||
.data
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: put all refresh variables into one contiguous block. Make into one
|
||||
// big structure, like cl or sv?
|
||||
|
||||
.align 4
|
||||
.globl C(d_sdivzstepu)
|
||||
.globl C(d_tdivzstepu)
|
||||
.globl C(d_zistepu)
|
||||
.globl C(d_sdivzstepv)
|
||||
.globl C(d_tdivzstepv)
|
||||
.globl C(d_zistepv)
|
||||
.globl C(d_sdivzorigin)
|
||||
.globl C(d_tdivzorigin)
|
||||
.globl C(d_ziorigin)
|
||||
C(d_sdivzstepu): .single 0
|
||||
C(d_tdivzstepu): .single 0
|
||||
C(d_zistepu): .single 0
|
||||
C(d_sdivzstepv): .single 0
|
||||
C(d_tdivzstepv): .single 0
|
||||
C(d_zistepv): .single 0
|
||||
C(d_sdivzorigin): .single 0
|
||||
C(d_tdivzorigin): .single 0
|
||||
C(d_ziorigin): .single 0
|
||||
|
||||
.globl C(sadjust)
|
||||
.globl C(tadjust)
|
||||
.globl C(bbextents)
|
||||
.globl C(bbextentt)
|
||||
C(sadjust): .long 0
|
||||
C(tadjust): .long 0
|
||||
C(bbextents): .long 0
|
||||
C(bbextentt): .long 0
|
||||
|
||||
.globl C(cacheblock)
|
||||
.globl C(d_viewbuffer)
|
||||
.globl C(cachewidth)
|
||||
.globl C(d_pzbuffer)
|
||||
.globl C(d_zrowbytes)
|
||||
.globl C(d_zwidth)
|
||||
C(cacheblock): .long 0
|
||||
C(cachewidth): .long 0
|
||||
C(d_viewbuffer): .long 0
|
||||
C(d_pzbuffer): .long 0
|
||||
C(d_zrowbytes): .long 0
|
||||
C(d_zwidth): .long 0
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl izi
|
||||
izi: .long 0
|
||||
|
||||
.globl pbase, s, t, sfracf, tfracf, snext, tnext
|
||||
.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu
|
||||
.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz
|
||||
s: .long 0
|
||||
t: .long 0
|
||||
snext: .long 0
|
||||
tnext: .long 0
|
||||
sfracf: .long 0
|
||||
tfracf: .long 0
|
||||
pbase: .long 0
|
||||
zi8stepu: .long 0
|
||||
sdivz8stepu: .long 0
|
||||
tdivz8stepu: .long 0
|
||||
zi16stepu: .long 0
|
||||
sdivz16stepu: .long 0
|
||||
tdivz16stepu: .long 0
|
||||
spancountminus1: .long 0
|
||||
pz: .long 0
|
||||
|
||||
.globl izistep
|
||||
izistep: .long 0
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_draw16.s
|
||||
//-------------------------------------------------------
|
||||
|
||||
.globl reciprocal_table_16, entryvec_table_16
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13,
|
||||
// 1/14, and 1/15 in 0.32 form
|
||||
reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
.long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba
|
||||
.long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_16
|
||||
.extern Entry3_16
|
||||
.extern Entry4_16
|
||||
.extern Entry5_16
|
||||
.extern Entry6_16
|
||||
.extern Entry7_16
|
||||
.extern Entry8_16
|
||||
.extern Entry9_16
|
||||
.extern Entry10_16
|
||||
.extern Entry11_16
|
||||
.extern Entry12_16
|
||||
.extern Entry13_16
|
||||
.extern Entry14_16
|
||||
.extern Entry15_16
|
||||
.extern Entry16_16
|
||||
#endif
|
||||
|
||||
entryvec_table_16: .long 0, Entry2_16, Entry3_16, Entry4_16
|
||||
.long Entry5_16, Entry6_16, Entry7_16, Entry8_16
|
||||
.long Entry9_16, Entry10_16, Entry11_16, Entry12_16
|
||||
.long Entry13_16, Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_parta.s
|
||||
//-------------------------------------------------------
|
||||
.globl DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable
|
||||
DP_Count: .long 0
|
||||
DP_u: .long 0
|
||||
DP_v: .long 0
|
||||
DP_32768: .single 32768.0
|
||||
DP_Color: .long 0
|
||||
DP_Pix: .long 0
|
||||
|
||||
|
||||
#ifndef NeXT
|
||||
.extern DP_1x1
|
||||
.extern DP_2x2
|
||||
.extern DP_3x3
|
||||
.extern DP_4x4
|
||||
#endif
|
||||
|
||||
DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4
|
||||
|
||||
//
|
||||
// advancetable is 8 bytes, but points to the middle of that range so negative
|
||||
// offsets will work
|
||||
//
|
||||
.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp
|
||||
advancetable: .long 0, 0
|
||||
sstep: .long 0
|
||||
tstep: .long 0
|
||||
|
||||
pspantemp: .long 0
|
||||
counttemp: .long 0
|
||||
jumptemp: .long 0
|
||||
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form
|
||||
.globl reciprocal_table, entryvec_table
|
||||
reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_8
|
||||
.extern Entry3_8
|
||||
.extern Entry4_8
|
||||
.extern Entry5_8
|
||||
.extern Entry6_8
|
||||
.extern Entry7_8
|
||||
.extern Entry8_8
|
||||
#endif
|
||||
|
||||
entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8
|
||||
.long Entry5_8, Entry6_8, Entry7_8, Entry8_8
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Spr8Entry2_8
|
||||
.extern Spr8Entry3_8
|
||||
.extern Spr8Entry4_8
|
||||
.extern Spr8Entry5_8
|
||||
.extern Spr8Entry6_8
|
||||
.extern Spr8Entry7_8
|
||||
.extern Spr8Entry8_8
|
||||
#endif
|
||||
|
||||
.globl spr8entryvec_table
|
||||
spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8
|
||||
.long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8
|
||||
|
||||
#endif // USE_INTEL_ASM
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
d_zpoint.c
|
||||
|
||||
software driver module for drawing z-buffered points
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "d_local.h"
|
||||
|
||||
|
||||
void
|
||||
D_DrawZPoint (void)
|
||||
{
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u;
|
||||
pdest = d_viewbuffer + d_scantable[r_zpointdesc.v] + r_zpointdesc.u;
|
||||
izi = (int) (r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi) {
|
||||
*pz = izi;
|
||||
*pdest = r_zpointdesc.color;
|
||||
}
|
||||
}
|
|
@ -1,735 +0,0 @@
|
|||
/*
|
||||
gl_draw.c
|
||||
|
||||
Draw functions for chars, textures, etc
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/console.h"
|
||||
#include "QF/draw.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/screen.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/vid.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "r_cvar.h"
|
||||
#include "sbar.h"
|
||||
|
||||
extern byte *vid_basepal;
|
||||
extern cvar_t *crosshair, *cl_crossx, *cl_crossy, *crosshaircolor,
|
||||
*gl_lightmap_components;
|
||||
|
||||
byte *draw_chars; // 8*8 graphic characters
|
||||
qpic_t *draw_disc;
|
||||
qpic_t *draw_backtile;
|
||||
|
||||
static int translate_texture;
|
||||
static int char_texture;
|
||||
static int cs_texture; // crosshair texturea
|
||||
|
||||
static byte cs_data[64] = {
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int texnum;
|
||||
int bytesperpixel;
|
||||
float sl, tl, sh, th;
|
||||
} glpic_t;
|
||||
|
||||
extern int gl_filter_min, gl_filter_max;
|
||||
|
||||
typedef struct cachepic_s {
|
||||
char name[MAX_QPATH];
|
||||
qboolean dirty;
|
||||
qpic_t pic;
|
||||
byte padding[32]; // for appended glpic
|
||||
} cachepic_t;
|
||||
|
||||
#define MAX_CACHED_PICS 128
|
||||
static cachepic_t cachepics[MAX_CACHED_PICS];
|
||||
static int numcachepics;
|
||||
|
||||
static byte menuplyr_pixels[4096];
|
||||
|
||||
|
||||
qpic_t *
|
||||
Draw_PicFromWad (char *name)
|
||||
{
|
||||
qpic_t *p;
|
||||
glpic_t *gl;
|
||||
|
||||
p = W_GetLumpName (name);
|
||||
gl = (glpic_t *) p->data;
|
||||
|
||||
gl->texnum = GL_LoadTexture ("", p->width, p->height, p->data, false, true, 1);
|
||||
gl->sl = 0;
|
||||
gl->sh = 1;
|
||||
gl->tl = 0;
|
||||
gl->th = 1;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_ClearCache (void)
|
||||
{
|
||||
cachepic_t *pic;
|
||||
int i;
|
||||
|
||||
for (pic = cachepics, i = 0; i < numcachepics; pic++, i++)
|
||||
pic->dirty = true;
|
||||
}
|
||||
|
||||
|
||||
qpic_t *
|
||||
Draw_CachePic (char *path, qboolean alpha)
|
||||
{
|
||||
cachepic_t *pic;
|
||||
int i;
|
||||
qpic_t *dat;
|
||||
glpic_t *gl;
|
||||
|
||||
// First, check if its cached..
|
||||
for (pic = cachepics, i = 0; i < numcachepics; pic++, i++)
|
||||
if ((!strcmp (path, pic->name)) && !pic->dirty)
|
||||
return &pic->pic;
|
||||
|
||||
// Its not cached, lets make sure we have space in the cache..
|
||||
if (numcachepics == MAX_CACHED_PICS)
|
||||
Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
|
||||
|
||||
// Load the picture..
|
||||
dat = (qpic_t *) COM_LoadTempFile (path);
|
||||
if (!dat)
|
||||
Sys_Error ("Draw_CachePic: failed to load %s", path);
|
||||
|
||||
// Adjust for endian..
|
||||
SwapPic (dat);
|
||||
|
||||
// Ok, the image is here, lets load it up into the cache..
|
||||
|
||||
// First the image name..
|
||||
strncpy (pic->name, path, sizeof (pic->name));
|
||||
|
||||
// Now the width and height.
|
||||
pic->pic.width = dat->width;
|
||||
pic->pic.height = dat->height;
|
||||
|
||||
// Now feed it to the GL stuff and get a texture number..
|
||||
gl = (glpic_t *) pic->pic.data;
|
||||
gl->texnum = GL_LoadTexture ("", dat->width, dat->height, dat->data, false, alpha, 1);
|
||||
|
||||
// Alignment stuff..
|
||||
gl->sl = 0;
|
||||
gl->sh = 1;
|
||||
gl->tl = 0;
|
||||
gl->th = 1;
|
||||
|
||||
// Now lets mark this cache entry as used..
|
||||
pic->dirty = false;
|
||||
numcachepics++;
|
||||
|
||||
// FIXME:
|
||||
// A really ugly kluge, keep a specific image in memory
|
||||
// for the menu system.
|
||||
// Some days I really dislike legacy support..
|
||||
|
||||
if (!strcmp (path, "gfx/menuplyr.lmp"))
|
||||
memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
|
||||
|
||||
// And now we are done, return what was asked for..
|
||||
return &pic->pic;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
extern void glrmain_init (void);
|
||||
extern void glrsurf_init (void);
|
||||
extern void GL_TextureMode_f (void);
|
||||
|
||||
|
||||
void
|
||||
Draw_Init (void)
|
||||
{
|
||||
int i;
|
||||
GLint texSize;
|
||||
|
||||
// Some cards have a texture size limit.
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
|
||||
Cvar_Set (gl_max_size, va("%d", texSize));
|
||||
|
||||
// LordHavoc: 3DFX's dithering has terrible artifacts with lightmode 1
|
||||
if (strstr (gl_renderer, "3dfx") || strstr (gl_renderer, "Mesa Glide"))
|
||||
{
|
||||
Cvar_Set (gl_lightmode, "0");
|
||||
}
|
||||
|
||||
Cmd_AddCommand ("gl_texturemode", &GL_TextureMode_f, "Texture mipmap quality.");
|
||||
|
||||
// load the console background and the charset
|
||||
// by hand, because we need to write the version
|
||||
// string into the background before turning
|
||||
// it into a texture
|
||||
draw_chars = W_GetLumpName ("conchars");
|
||||
for (i = 0; i < 256 * 64; i++)
|
||||
if (draw_chars[i] == 0)
|
||||
draw_chars[i] = 255; // proper transparent color
|
||||
|
||||
// now turn them into textures
|
||||
char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1); // 1999-12-27 Conwidth/height charset fix by TcT
|
||||
cs_texture = GL_LoadTexture ("crosshair", 8, 8, cs_data, false, true, 1);
|
||||
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// save a texture slot for translated picture
|
||||
translate_texture = texture_extension_number++;
|
||||
|
||||
// get the other pics we need
|
||||
draw_disc = Draw_PicFromWad ("disc");
|
||||
draw_backtile = Draw_PicFromWad ("backtile");
|
||||
|
||||
// LordHavoc: call init code for other GL renderer modules;
|
||||
glrmain_init ();
|
||||
glrsurf_init ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
int row, col;
|
||||
float frow, fcol, size;
|
||||
|
||||
if (num == 32)
|
||||
return; // space
|
||||
|
||||
num &= 255;
|
||||
|
||||
if (y <= -8)
|
||||
return; // totally off screen
|
||||
|
||||
row = num >> 4;
|
||||
col = num & 15;
|
||||
|
||||
frow = row * 0.0625;
|
||||
fcol = col * 0.0625;
|
||||
size = 0.0625;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, char_texture);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (fcol, frow);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (fcol + size, frow);
|
||||
glVertex2f (x + 8, y);
|
||||
glTexCoord2f (fcol + size, frow + size);
|
||||
glVertex2f (x + 8, y + 8);
|
||||
glTexCoord2f (fcol, frow + size);
|
||||
glVertex2f (x, y + 8);
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_String8 (int x, int y, char *str)
|
||||
{
|
||||
while (*str) {
|
||||
Draw_Character8 (x, y, *str);
|
||||
str++;
|
||||
x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_AltString8 (int x, int y, char *str)
|
||||
{
|
||||
while (*str) {
|
||||
Draw_Character8 (x, y, (*str) | 0x80);
|
||||
str++;
|
||||
x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Crosshair (int swap)
|
||||
{
|
||||
int x, y;
|
||||
extern vrect_t scr_vrect;
|
||||
unsigned char *pColor;
|
||||
|
||||
switch (crosshair->int_val) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
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, '+');
|
||||
break;
|
||||
case 2:
|
||||
x = scr_vrect.x + scr_vrect.width / 2 - 3 + cl_crossx->int_val;
|
||||
y = scr_vrect.y + scr_vrect.height / 2 - 3 + cl_crossy->int_val;
|
||||
|
||||
pColor = (unsigned char *) &d_8to24table[crosshaircolor->int_val];
|
||||
if (lighthalf)
|
||||
glColor4ub ((byte) ((int) pColor[0] >> 1),
|
||||
(byte) ((int) pColor[1] >> 1),
|
||||
(byte) ((int) pColor[2] >> 1), pColor[3]);
|
||||
else
|
||||
glColor4ubv (pColor);
|
||||
glBindTexture (GL_TEXTURE_2D, cs_texture);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (x - 4, y - 4);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex2f (x + 12, y - 4);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex2f (x + 12, y + 12);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex2f (x - 4, y + 12);
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_Pic (int x, int y, qpic_t *pic)
|
||||
{
|
||||
glpic_t *gl;
|
||||
|
||||
gl = (glpic_t *) pic->data;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (gl->sl, gl->tl);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (gl->sh, gl->tl);
|
||||
glVertex2f (x + pic->width, y);
|
||||
glTexCoord2f (gl->sh, gl->th);
|
||||
glVertex2f (x + pic->width, y + pic->height);
|
||||
glTexCoord2f (gl->sl, gl->th);
|
||||
glVertex2f (x, y + pic->height);
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
|
||||
int height)
|
||||
{
|
||||
glpic_t *gl;
|
||||
float newsl, newtl, newsh, newth;
|
||||
float oldglwidth, oldglheight;
|
||||
|
||||
gl = (glpic_t *) pic->data;
|
||||
|
||||
oldglwidth = gl->sh - gl->sl;
|
||||
oldglheight = gl->th - gl->tl;
|
||||
|
||||
newsl = gl->sl + (srcx * oldglwidth) / pic->width;
|
||||
newsh = newsl + (width * oldglwidth) / pic->width;
|
||||
|
||||
newtl = gl->tl + (srcy * oldglheight) / pic->height;
|
||||
newth = newtl + (height * oldglheight) / pic->height;
|
||||
|
||||
if (lighthalf)
|
||||
glColor3f (0.4, 0.4, 0.4);
|
||||
else
|
||||
glColor3f (0.8, 0.8, 0.8);
|
||||
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (newsl, newtl);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (newsh, newtl);
|
||||
glVertex2f (x + width, y);
|
||||
glTexCoord2f (newsh, newth);
|
||||
glVertex2f (x + width, y + height);
|
||||
glTexCoord2f (newsl, newth);
|
||||
glVertex2f (x, y + height);
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_TransPicTranslate
|
||||
|
||||
Only used for the player color selection menu
|
||||
*/
|
||||
void
|
||||
Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte * translation)
|
||||
{
|
||||
int v, u, c;
|
||||
unsigned int trans[64 * 64], *dest;
|
||||
byte *src;
|
||||
int p;
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, translate_texture);
|
||||
|
||||
c = pic->width * pic->height;
|
||||
|
||||
dest = trans;
|
||||
for (v = 0; v < 64; v++, dest += 64) {
|
||||
src = &menuplyr_pixels[((v * pic->height) >> 6) * pic->width];
|
||||
for (u = 0; u < 64; u++) {
|
||||
p = src[(u * pic->width) >> 6];
|
||||
if (p == 255)
|
||||
dest[u] = p;
|
||||
else
|
||||
dest[u] = d_8to24table[translation[p]];
|
||||
}
|
||||
}
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, trans);
|
||||
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
||||
|
||||
if (lighthalf)
|
||||
glColor3f (0.4, 0.4, 0.4);
|
||||
else
|
||||
glColor3f (0.8, 0.8, 0.8);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex2f (x + pic->width, y);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex2f (x + pic->width, y + pic->height);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex2f (x, y + pic->height);
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_ConsoleBackground
|
||||
|
||||
Draws console background (obviously!) Completely rewritten to use
|
||||
several simple yet very cool GL effects. --KB
|
||||
*/
|
||||
void
|
||||
Draw_ConsoleBackground (int lines)
|
||||
{
|
||||
int y;
|
||||
qpic_t *conback;
|
||||
glpic_t *gl;
|
||||
float ofs;
|
||||
float alpha;
|
||||
|
||||
// This can be a CachePic now, just like in software
|
||||
conback = Draw_CachePic ("gfx/conback.lmp", false);
|
||||
gl = (glpic_t *) conback->data;
|
||||
|
||||
// spin the console? - effect described in a QER tutorial
|
||||
if (gl_conspin->value) {
|
||||
static float xangle = 0;
|
||||
static float xfactor = .3f;
|
||||
static float xstep = .005f;
|
||||
|
||||
glPushMatrix ();
|
||||
glMatrixMode (GL_TEXTURE);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity ();
|
||||
xangle += gl_conspin->value;
|
||||
xfactor += xstep;
|
||||
if (xfactor > 8 || xfactor < .3f)
|
||||
xstep = -xstep;
|
||||
glRotatef (xangle, 0, 0, 1);
|
||||
glScalef (xfactor, xfactor, xfactor);
|
||||
}
|
||||
// slide console up/down or stretch it?
|
||||
if (gl_constretch->int_val)
|
||||
ofs = 0;
|
||||
else
|
||||
ofs = (vid.conheight - lines) / (float) vid.conheight;
|
||||
|
||||
y = vid.height * scr_consize->value;
|
||||
if (!r_active || lines > y) {
|
||||
alpha = 1.0;
|
||||
} else {
|
||||
// set up to draw alpha console
|
||||
alpha = (float) (gl_conalpha->value * lines) / y;
|
||||
}
|
||||
|
||||
if (lighthalf)
|
||||
glColor4f (0.4, 0.4, 0.4, alpha);
|
||||
else
|
||||
glColor4f (0.8, 0.8, 0.8, alpha);
|
||||
|
||||
// draw the console texture
|
||||
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (gl->sl, gl->tl + ofs);
|
||||
glVertex2f (0, 0);
|
||||
glTexCoord2f (gl->sh, gl->tl + ofs);
|
||||
glVertex2f (vid.conwidth, 0);
|
||||
glTexCoord2f (gl->sh, gl->th);
|
||||
glVertex2f (vid.conwidth, lines);
|
||||
glTexCoord2f (gl->sl, gl->th);
|
||||
glVertex2f (0, lines);
|
||||
glEnd ();
|
||||
|
||||
// turn off alpha blending
|
||||
if (alpha < 1.0) {
|
||||
if (lighthalf)
|
||||
glColor3f (0.4, 0.4, 0.4);
|
||||
else
|
||||
glColor3f (0.8, 0.8, 0.8);
|
||||
}
|
||||
|
||||
if (gl_conspin->value) {
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix ();
|
||||
}
|
||||
|
||||
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string) * 8 - 11,
|
||||
lines - 14, cl_verstring->string);
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_TileClear
|
||||
|
||||
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)
|
||||
{
|
||||
if (lighthalf)
|
||||
glColor3f (0.4, 0.4, 0.4);
|
||||
else
|
||||
glColor3f (0.8, 0.8, 0.8);
|
||||
glBindTexture (GL_TEXTURE_2D, *(int *) draw_backtile->data);
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (x / 64.0, y / 64.0);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f ((x + w) / 64.0, y / 64.0);
|
||||
glVertex2f (x + w, y);
|
||||
glTexCoord2f ((x + w) / 64.0, (y + h) / 64.0);
|
||||
glVertex2f (x + w, y + h);
|
||||
glTexCoord2f (x / 64.0, (y + h) / 64.0);
|
||||
glVertex2f (x, y + h);
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_Fill
|
||||
|
||||
Fills a box of pixels with a single color
|
||||
*/
|
||||
void
|
||||
Draw_Fill (int x, int y, int w, int h, int c)
|
||||
{
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
if (lighthalf)
|
||||
glColor3f (vid_basepal[c * 3] / 510.0, vid_basepal[c * 3 + 1] / 510.0,
|
||||
vid_basepal[c * 3 + 2] / 510.0);
|
||||
else
|
||||
glColor3f (vid_basepal[c * 3] / 255.0, vid_basepal[c * 3 + 1] / 255.0,
|
||||
vid_basepal[c * 3 + 2] / 255.0);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glVertex2f (x, y);
|
||||
glVertex2f (x + w, y);
|
||||
glVertex2f (x + w, y + h);
|
||||
glVertex2f (x, y + h);
|
||||
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
void
|
||||
Draw_FadeScreen (void)
|
||||
{
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glColor4f (0, 0, 0, 0.7);
|
||||
glBegin (GL_QUADS);
|
||||
|
||||
glVertex2f (0, 0);
|
||||
glVertex2f (vid.width, 0);
|
||||
glVertex2f (vid.width, vid.height);
|
||||
glVertex2f (0, vid.height);
|
||||
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
||||
Sbar_Changed ();
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/*
|
||||
Draw_BeginDisc
|
||||
|
||||
Draws the little blue disc in the corner of the screen.
|
||||
Call before beginning any disc IO.
|
||||
*/
|
||||
void
|
||||
Draw_BeginDisc (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Draw_EndDisc
|
||||
|
||||
Erases the disc icon.
|
||||
Call after completing any disc IO
|
||||
*/
|
||||
void
|
||||
Draw_EndDisc (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GL_Set2D
|
||||
|
||||
Setup as if the screen was 320*200
|
||||
*/
|
||||
void
|
||||
GL_Set2D (void)
|
||||
{
|
||||
glViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_CULL_FACE);
|
||||
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
gl_dyn_fires.c
|
||||
|
||||
dynamic fires
|
||||
|
||||
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/cmd.h"
|
||||
#include "QF/console.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "r_shared.h"
|
||||
|
||||
#define MAX_FIRES 128 // rocket flames
|
||||
|
||||
static fire_t r_fires[MAX_FIRES];
|
||||
extern cvar_t *gl_fires;
|
||||
extern cvar_t *r_firecolor;
|
||||
|
||||
|
||||
/*
|
||||
R_AddFire
|
||||
|
||||
Nifty ball of fire GL effect. Kinda a meshing of the dlight and
|
||||
particle engine code.
|
||||
*/
|
||||
void
|
||||
R_AddFire (vec3_t start, vec3_t end, entity_t *ent)
|
||||
{
|
||||
float len;
|
||||
fire_t *f;
|
||||
vec3_t vec;
|
||||
int key;
|
||||
|
||||
if (!gl_fires->int_val)
|
||||
return;
|
||||
|
||||
VectorSubtract (end, start, vec);
|
||||
len = VectorNormalize (vec);
|
||||
key = ent->keynum;
|
||||
|
||||
if (len) {
|
||||
f = R_AllocFire (key);
|
||||
VectorCopy (end, f->origin);
|
||||
VectorCopy (start, f->owner);
|
||||
f->size = 10;
|
||||
f->die = r_realtime + 0.5;
|
||||
f->decay = 1;
|
||||
VectorCopy (r_firecolor->vec, f->color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_AllocFire
|
||||
|
||||
Clears out and returns a new fireball
|
||||
*/
|
||||
fire_t *
|
||||
R_AllocFire (int key)
|
||||
{
|
||||
int i;
|
||||
fire_t *f;
|
||||
|
||||
if (key) // first try to find/reuse a keyed
|
||||
// spot
|
||||
{
|
||||
f = r_fires;
|
||||
for (i = 0; i < MAX_FIRES; i++, f++)
|
||||
if (f->key == key) {
|
||||
memset (f, 0, sizeof (*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
f = r_fires; // no match, look for a free spot
|
||||
for (i = 0; i < MAX_FIRES; i++, f++) {
|
||||
if (f->die < r_realtime) {
|
||||
memset (f, 0, sizeof (*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
f = &r_fires[0];
|
||||
memset (f, 0, sizeof (*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_DrawFire
|
||||
|
||||
draws one fireball - probably never need to call this directly
|
||||
*/
|
||||
void
|
||||
R_DrawFire (fire_t *f)
|
||||
{
|
||||
int i, j;
|
||||
vec3_t vec, vec2;
|
||||
float radius;
|
||||
float *b_sin, *b_cos;
|
||||
|
||||
b_sin = bubble_sintable;
|
||||
b_cos = bubble_costable;
|
||||
|
||||
radius = f->size - 0.5;
|
||||
|
||||
// figure out if we're inside the area of effect
|
||||
VectorSubtract (f->origin, r_origin, vec);
|
||||
if (Length (vec) < radius) {
|
||||
AddLightBlend (f->color[0], f->color[1], f->color[2], f->size * 0.0003); // we are
|
||||
return;
|
||||
}
|
||||
// we're not - draw it
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
if (lighthalf)
|
||||
glColor3f (f->color[0] * 0.5, f->color[1] * 0.5, f->color[2] * 0.5);
|
||||
else
|
||||
glColor3fv (f->color);
|
||||
for (i = 0; i < 3; i++)
|
||||
vec[i] = f->origin[i] - vpn[i] * radius;
|
||||
glVertex3fv (vec);
|
||||
glColor3f (0.0, 0.0, 0.0);
|
||||
|
||||
// don't panic, this just draws a bubble...
|
||||
for (i = 16; i >= 0; i--) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
vec[j] = f->origin[j] + (*b_cos * vright[j]
|
||||
+ vup[j] * (*b_sin)) * radius;
|
||||
vec2[j] = f->owner[j] + (*b_cos * vright[j]
|
||||
+ vup[j] * (*b_sin)) * radius;
|
||||
}
|
||||
glVertex3fv (vec);
|
||||
glVertex3fv (vec2);
|
||||
|
||||
b_sin += 2;
|
||||
b_cos += 2;
|
||||
}
|
||||
glEnd ();
|
||||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_UpdateFires
|
||||
|
||||
Draws each fireball in sequence
|
||||
*/
|
||||
void
|
||||
R_UpdateFires (void)
|
||||
{
|
||||
int i;
|
||||
fire_t *f;
|
||||
|
||||
if (!gl_fires->int_val)
|
||||
return;
|
||||
|
||||
glDepthMask (GL_FALSE);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
|
||||
f = r_fires;
|
||||
for (i = 0; i < MAX_FIRES; i++, f++) {
|
||||
if (f->die < r_realtime || !f->size)
|
||||
continue;
|
||||
f->size += f->decay;
|
||||
R_DrawFire (f);
|
||||
}
|
||||
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask (GL_TRUE);
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
gl_dyn_textures.c
|
||||
|
||||
Dynamic texture generation.
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glquake.h"
|
||||
|
||||
extern void noise_diamondsquare(unsigned char *noise, int size);
|
||||
extern void noise_plasma(unsigned char *noise, int size);
|
||||
|
||||
static void GDT_InitDotParticleTexture (void);
|
||||
static void GDT_InitSparkParticleTexture (void);
|
||||
static void GDT_InitSmokeParticleTexture (void);
|
||||
static void GDT_InitSmokeRingParticleTexture (void);
|
||||
|
||||
int part_tex_dot;
|
||||
int part_tex_spark;
|
||||
int part_tex_smoke[8];
|
||||
int part_tex_smoke_ring[8];
|
||||
|
||||
|
||||
void
|
||||
GDT_Init (void)
|
||||
{
|
||||
GDT_InitDotParticleTexture ();
|
||||
GDT_InitSparkParticleTexture ();
|
||||
GDT_InitSmokeParticleTexture ();
|
||||
GDT_InitSmokeRingParticleTexture ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GDT_InitDotParticleTexture (void)
|
||||
{
|
||||
int x, y, dx2, dy, d;
|
||||
byte data[16][16][2];
|
||||
|
||||
for (x = 0; x < 16; x++) {
|
||||
dx2 = x - 8;
|
||||
dx2 *= dx2;
|
||||
for (y = 0; y < 16; y++) {
|
||||
dy = y - 8;
|
||||
d = 255 - 4 * (dx2 + (dy * dy));
|
||||
if (d<=0) {
|
||||
d = 0;
|
||||
data[y][x][0] = 0;
|
||||
} else
|
||||
data[y][x][0] = 255;
|
||||
|
||||
data[y][x][1] = (byte) d;
|
||||
}
|
||||
}
|
||||
part_tex_dot = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, part_tex_dot);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, 2, 16, 16, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GDT_InitSparkParticleTexture (void)
|
||||
{
|
||||
int x, y, dx2, dy, d;
|
||||
byte data[16][16][2];
|
||||
|
||||
for (x = 0; x < 16; x++) {
|
||||
dx2 = 8 - abs(x - 8);
|
||||
dx2 *= dx2;
|
||||
for (y = 0; y < 16; y++) {
|
||||
dy = 8 - abs(y - 8);
|
||||
d = 3 * (dx2 + dy * dy) - 100;
|
||||
if (d>255)
|
||||
d = 255;
|
||||
if (d<1) {
|
||||
d = 0;
|
||||
data[y][x][0] = 0;
|
||||
} else
|
||||
data[y][x][0] = 255;
|
||||
|
||||
data[y][x][1] = (byte) d;
|
||||
}
|
||||
}
|
||||
part_tex_spark = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, part_tex_spark);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, 2, 16, 16, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GDT_InitSmokeParticleTexture (void)
|
||||
{
|
||||
int i, x, y, c;
|
||||
float dx, dy2;
|
||||
byte d, data[32][32][2], noise1[32][32], noise2[32][32];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
noise_plasma (&noise1[0][0], 32);
|
||||
noise_diamondsquare (&noise2[0][0], 32);
|
||||
for (y = 0; y < 32; y++)
|
||||
{
|
||||
dy2 = y - 16;
|
||||
dy2 *= dy2;
|
||||
for (x = 0; x < 32; x++) {
|
||||
dx = x - 16;
|
||||
c = 255 - (dx*dx + dy2);
|
||||
if (c < 1)
|
||||
c = 0;
|
||||
d = (noise1[y][x] + noise2[y][x]) / 2;
|
||||
if (d > 0) {
|
||||
data[y][x][0] = 255;
|
||||
data[y][x][1] = (d * c)/255;
|
||||
} else {
|
||||
data[y][x][0] = 255;
|
||||
data[y][x][1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
part_tex_smoke[i] = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, part_tex_smoke[i]);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, 2, 32, 32, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GDT_InitSmokeRingParticleTexture (void)
|
||||
{
|
||||
int i, x, y, b;
|
||||
float dx, dy, c, c2;
|
||||
byte d, data[32][32][2], noise1[32][32], noise2[32][32];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
noise_diamondsquare (&noise1[0][0], 32);
|
||||
noise_plasma (&noise2[0][0], 32);
|
||||
for (y = 0; y < 32; y++)
|
||||
{
|
||||
dy = y - 16;
|
||||
dy *= dy;
|
||||
for (x = 0; x < 32; x++) {
|
||||
dx = x - 16;
|
||||
dx *= dx;
|
||||
c = 255 - (dx + dy);
|
||||
c2 = (dx + dy);
|
||||
if (c < 1) c = 0;
|
||||
if (c2 < 1) c2 = 0;
|
||||
//b = ((c / 255) * (c2 / 255)) * 512;
|
||||
b = (c * c2) * 512 / (255*255);
|
||||
if (b < 1) b = 0;
|
||||
d = (noise1[y][x] + noise2[y][x]) / 2;
|
||||
if (d > 0) {
|
||||
data[y][x][0] = 255;
|
||||
data[y][x][1] = (d * b)/255;
|
||||
} else {
|
||||
data[y][x][0] = 255;
|
||||
data[y][x][1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
part_tex_smoke_ring[i] = texture_extension_number++;
|
||||
glBindTexture (GL_TEXTURE_2D, part_tex_smoke_ring[i]);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, 2, 32, 32, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
gl_ngraph.c
|
||||
|
||||
(description)
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/draw.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "r_cvar.h"
|
||||
|
||||
extern byte *draw_chars; // 8*8 graphic characters
|
||||
extern qboolean lighthalf;
|
||||
|
||||
extern cvar_t *r_netgraph;
|
||||
extern cvar_t *r_netgraph_alpha;
|
||||
extern cvar_t *r_netgraph_box;
|
||||
|
||||
static int graph_index;
|
||||
static int graph_size[NUM_GRAPH_TEXTURES];
|
||||
static int graph_width[NUM_GRAPH_TEXTURES];
|
||||
static byte *graph_texels[NUM_GRAPH_TEXTURES];
|
||||
int graph_texture[NUM_GRAPH_TEXTURES];
|
||||
|
||||
int
|
||||
R_InitGraphTextures (int base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GRAPH_TEXTURES; i++)
|
||||
graph_texture[i] = base++;
|
||||
return base;
|
||||
}
|
||||
|
||||
void
|
||||
R_LineGraph (int x, int y, int *h_vals, int count)
|
||||
{
|
||||
int i, j;
|
||||
int h;
|
||||
int s;
|
||||
byte color;
|
||||
int size;
|
||||
byte *dest;
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
s = r_graphheight->int_val;
|
||||
|
||||
size = s * count;
|
||||
if (size > graph_size[graph_index]) {
|
||||
graph_size[graph_index] = size;
|
||||
graph_texels[graph_index] = realloc (graph_texels[graph_index], size);
|
||||
}
|
||||
graph_width[graph_index] = count;
|
||||
|
||||
if (!graph_texels[graph_index])
|
||||
Sys_Error ("R_LineGraph: failed to allocate texture buffer\n");
|
||||
|
||||
i = 0;
|
||||
while (count--) {
|
||||
dest = graph_texels[graph_index] + i++;
|
||||
|
||||
h = *h_vals++;
|
||||
|
||||
if (h == 10000)
|
||||
color = 0x6f; // yellow
|
||||
else if (h == 9999)
|
||||
color = 0x4f; // red
|
||||
else if (h == 9998)
|
||||
color = 0xd0; // blue
|
||||
else
|
||||
color = 0xfe; // white
|
||||
|
||||
if (h > s)
|
||||
h = s;
|
||||
|
||||
for (j = 0; j < h; j++, dest += graph_width[graph_index])
|
||||
dest[0] = color;
|
||||
|
||||
for (; j < s; j++, dest += graph_width[graph_index])
|
||||
dest[0] = 0xff;
|
||||
}
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, graph_texture[graph_index]);
|
||||
|
||||
GL_Upload8 (graph_texels[graph_index], graph_width[graph_index], s, 0, 1);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (x, y);
|
||||
glTexCoord2f (1, 0);
|
||||
glVertex2f (x + graph_width[graph_index], y);
|
||||
glTexCoord2f (1, 1);
|
||||
glVertex2f (x + graph_width[graph_index], y - s);
|
||||
glTexCoord2f (0, 1);
|
||||
glVertex2f (x, y - s);
|
||||
glEnd ();
|
||||
|
||||
glColor3ubv (lighthalf_v);
|
||||
|
||||
graph_index = (graph_index + 1) % NUM_GRAPH_TEXTURES;
|
||||
}
|
|
@ -1,429 +0,0 @@
|
|||
/*
|
||||
gl_rlight.c
|
||||
|
||||
@description@
|
||||
|
||||
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 <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "glquake.h"
|
||||
#include "r_shared.h"
|
||||
|
||||
|
||||
void
|
||||
R_AnimateLight (void)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
// light animations
|
||||
// 'm' is normal light, 'a' is no light, 'z' is double bright
|
||||
i = (int) (r_realtime * 10);
|
||||
for (j = 0; j < MAX_LIGHTSTYLES; j++) {
|
||||
if (!r_lightstyle[j].length) {
|
||||
d_lightstylevalue[j] = 256;
|
||||
continue;
|
||||
}
|
||||
k = i % r_lightstyle[j].length;
|
||||
k = r_lightstyle[j].map[k] - 'a';
|
||||
k = k * 22;
|
||||
d_lightstylevalue[j] = k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
DYNAMIC LIGHTS BLEND RENDERING
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
AddLightBlend (float r, float g, float b, float a2)
|
||||
{
|
||||
float a;
|
||||
|
||||
v_blend[3] = a = v_blend[3] + a2 * (1 - v_blend[3]);
|
||||
|
||||
a2 = a2 / a;
|
||||
|
||||
v_blend[0] = v_blend[0] * (1 - a2) + r * a2;
|
||||
v_blend[1] = v_blend[1] * (1 - a2) + g * a2;
|
||||
v_blend[2] = v_blend[2] * (1 - a2) + b * a2;
|
||||
//Con_Printf("AddLightBlend(): %4.2f %4.2f %4.2f %4.6f\n", v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
|
||||
}
|
||||
|
||||
|
||||
float bubble_sintable[33], bubble_costable[33];
|
||||
|
||||
void
|
||||
R_InitBubble ()
|
||||
{
|
||||
int i;
|
||||
float a;
|
||||
float *bub_sin, *bub_cos;
|
||||
|
||||
bub_sin = bubble_sintable;
|
||||
bub_cos = bubble_costable;
|
||||
|
||||
for (i = 32; i >= 0; i--) {
|
||||
a = i / 32.0 * M_PI * 2;
|
||||
*bub_sin++ = sin (a);
|
||||
*bub_cos++ = cos (a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_RenderDlight (dlight_t *light)
|
||||
{
|
||||
int i, j;
|
||||
vec3_t v;
|
||||
float rad;
|
||||
float *bub_sin, *bub_cos;
|
||||
|
||||
bub_sin = bubble_sintable;
|
||||
bub_cos = bubble_costable;
|
||||
rad = light->radius * 0.35;
|
||||
|
||||
VectorSubtract (light->origin, r_origin, v);
|
||||
if (Length (v) < rad) { // view is inside the dlight
|
||||
return;
|
||||
}
|
||||
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
|
||||
if (lighthalf)
|
||||
glColor3f (light->color[0] * 0.5, light->color[1] * 0.5,
|
||||
light->color[2] * 0.5);
|
||||
else
|
||||
glColor3fv (light->color);
|
||||
|
||||
VectorSubtract (r_origin, light->origin, v);
|
||||
VectorNormalize (v);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
v[i] = light->origin[i] + v[i] * rad;
|
||||
|
||||
glVertex3fv (v);
|
||||
glColor3f (0, 0, 0);
|
||||
|
||||
for (i = 16; i >= 0; i--) {
|
||||
for (j = 0; j < 3; j++)
|
||||
v[j] = light->origin[j] + (vright[j] * (*bub_cos) +
|
||||
vup[j] * (*bub_sin)) * rad;
|
||||
bub_sin += 2;
|
||||
bub_cos += 2;
|
||||
glVertex3fv (v);
|
||||
}
|
||||
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_RenderDlights (void)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
|
||||
if (!gl_dlight_polyblend->int_val)
|
||||
return;
|
||||
|
||||
glDepthMask (GL_FALSE);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
|
||||
l = r_dlights;
|
||||
for (i = 0; i < MAX_DLIGHTS; i++, l++) {
|
||||
if (l->die < r_realtime || !l->radius)
|
||||
continue;
|
||||
R_RenderDlight (l);
|
||||
}
|
||||
|
||||
if (!gl_dlight_smooth->int_val)
|
||||
glShadeModel (GL_FLAT);
|
||||
glColor3ubv (lighthalf_v);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask (GL_TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
DYNAMIC LIGHTS
|
||||
*/
|
||||
|
||||
|
||||
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
|
||||
// and support bmodel lighting better
|
||||
void
|
||||
R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float ndist, maxdist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
maxdist = light->radius * light->radius;
|
||||
|
||||
loc0:
|
||||
if (node->contents < 0)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (ndist > light->radius) {
|
||||
// Save time by not pushing another stack frame.
|
||||
if (node->children[0]->contents >= 0) {
|
||||
node = node->children[0];
|
||||
goto loc0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ndist < -light->radius) {
|
||||
// Save time by not pushing another stack frame.
|
||||
if (node->children[1]->contents >= 0) {
|
||||
node = node->children[1];
|
||||
goto loc0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = r_worldentity.model->surfaces + node->firstsurface;
|
||||
for (i = 0; i < node->numsurfaces; i++, surf++) {
|
||||
int s, t;
|
||||
float l, dist, dist2;
|
||||
vec3_t impact;
|
||||
|
||||
dist = ndist;
|
||||
|
||||
dist2 = dist * dist;
|
||||
if (dist2 >= maxdist)
|
||||
continue;
|
||||
|
||||
impact[0] = light->origin[0] - surf->plane->normal[0] * dist;
|
||||
impact[1] = light->origin[1] - surf->plane->normal[1] * dist;
|
||||
impact[2] = light->origin[2] - surf->plane->normal[2] * dist;
|
||||
|
||||
l = DotProduct (impact, surf->texinfo->vecs[0]) +
|
||||
surf->texinfo->vecs[0][3] - surf->texturemins[0];
|
||||
s = l + 0.5;
|
||||
if (s < 0)
|
||||
s = 0;
|
||||
else if (s > surf->extents[0])
|
||||
s = surf->extents[0];
|
||||
s = l - s;
|
||||
l = DotProduct (impact, surf->texinfo->vecs[1]) +
|
||||
surf->texinfo->vecs[1][3] - surf->texturemins[1];
|
||||
t = l + 0.5;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
else if (t > surf->extents[1])
|
||||
t = surf->extents[1];
|
||||
t = l - t;
|
||||
|
||||
if ((s * s + t * t + dist * dist) < maxdist) {
|
||||
if (surf->dlightframe != r_framecount) {
|
||||
surf->dlightframe = r_framecount;
|
||||
surf->dlightbits = bit;
|
||||
} else {
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node->children[0]->contents >= 0) {
|
||||
if (node->children[1]->contents >= 0)
|
||||
R_MarkLights (lightorigin, light, bit, node->children[1]);
|
||||
|
||||
node = node->children[0];
|
||||
goto loc0;
|
||||
} else if (node->children[1]->contents >= 0) {
|
||||
node = node->children[1];
|
||||
goto loc0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_PushDlights (vec3_t entorigin)
|
||||
{
|
||||
int i;
|
||||
dlight_t *l;
|
||||
vec3_t lightorigin;
|
||||
|
||||
if (!gl_dlight_lightmap->int_val)
|
||||
return;
|
||||
|
||||
l = r_dlights;
|
||||
|
||||
for (i = 0; i < MAX_DLIGHTS; i++, l++) {
|
||||
if (l->die < r_realtime || !l->radius)
|
||||
continue;
|
||||
VectorSubtract (l->origin, entorigin, lightorigin);
|
||||
R_MarkLights (lightorigin, l, 1 << i, r_worldentity.model->nodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
LIGHT SAMPLING
|
||||
*/
|
||||
|
||||
mplane_t *lightplane;
|
||||
vec3_t lightspot;
|
||||
|
||||
int
|
||||
RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
||||
{
|
||||
int r;
|
||||
float front, back, frac;
|
||||
int side;
|
||||
mplane_t *plane;
|
||||
vec3_t mid;
|
||||
msurface_t *surf;
|
||||
int s, t, ds, dt;
|
||||
int i;
|
||||
mtexinfo_t *tex;
|
||||
byte *lightmap;
|
||||
unsigned int scale;
|
||||
int maps;
|
||||
|
||||
if (node->contents < 0)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// calculate mid point
|
||||
|
||||
// FIXME: optimize for axial
|
||||
plane = node->plane;
|
||||
front = DotProduct (start, plane->normal) - plane->dist;
|
||||
back = DotProduct (end, plane->normal) - plane->dist;
|
||||
side = front < 0;
|
||||
|
||||
if ((back < 0) == side)
|
||||
return RecursiveLightPoint (node->children[side], start, end);
|
||||
|
||||
frac = front / (front - back);
|
||||
mid[0] = start[0] + (end[0] - start[0]) * frac;
|
||||
mid[1] = start[1] + (end[1] - start[1]) * frac;
|
||||
mid[2] = start[2] + (end[2] - start[2]) * frac;
|
||||
|
||||
// go down front side
|
||||
r = RecursiveLightPoint (node->children[side], start, mid);
|
||||
if (r >= 0)
|
||||
return r; // hit something
|
||||
|
||||
if ((back < 0) == side)
|
||||
return -1; // didn't hit anything
|
||||
|
||||
// check for impact on this node
|
||||
VectorCopy (mid, lightspot);
|
||||
lightplane = plane;
|
||||
|
||||
surf = r_worldentity.model->surfaces + node->firstsurface;
|
||||
for (i = 0; i < node->numsurfaces; i++, surf++) {
|
||||
if (surf->flags & SURF_DRAWTILED)
|
||||
continue; // no lightmaps
|
||||
|
||||
tex = surf->texinfo;
|
||||
|
||||
s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
|
||||
t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];;
|
||||
|
||||
if (s < surf->texturemins[0] || t < surf->texturemins[1])
|
||||
continue;
|
||||
|
||||
ds = s - surf->texturemins[0];
|
||||
dt = t - surf->texturemins[1];
|
||||
|
||||
if (ds > surf->extents[0] || dt > surf->extents[1])
|
||||
continue;
|
||||
|
||||
if (!surf->samples)
|
||||
return 0;
|
||||
|
||||
ds >>= 4;
|
||||
dt >>= 4;
|
||||
|
||||
lightmap = surf->samples;
|
||||
r = 0;
|
||||
if (lightmap) {
|
||||
|
||||
lightmap += dt * ((surf->extents[0] >> 4) + 1) + ds;
|
||||
|
||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255;
|
||||
maps++) {
|
||||
scale = d_lightstylevalue[surf->styles[maps]];
|
||||
r += *lightmap * scale;
|
||||
lightmap += ((surf->extents[0] >> 4) + 1) *
|
||||
((surf->extents[1] >> 4) + 1);
|
||||
}
|
||||
|
||||
r >>= 8;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// go down back side
|
||||
return RecursiveLightPoint (node->children[!side], mid, end);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
R_LightPoint (vec3_t p)
|
||||
{
|
||||
vec3_t end;
|
||||
int r;
|
||||
|
||||
if (!r_worldentity.model->lightdata)
|
||||
return 255;
|
||||
|
||||
end[0] = p[0];
|
||||
end[1] = p[1];
|
||||
end[2] = p[2] - 2048;
|
||||
|
||||
r = RecursiveLightPoint (r_worldentity.model->nodes, p, end);
|
||||
|
||||
if (r == -1)
|
||||
r = 0;
|
||||
|
||||
return r;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue