mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[renderer] Merge the two software renderers
I got tired of having to maintain two separate software renderers, but didn't want to just nuke sw32, so its core changes are merged into sw. Alias model rendering is broken, but I know exactly what's wrong and how to fix it, just need to take care due to asm.
This commit is contained in:
parent
cfe0455cce
commit
6377734e32
64 changed files with 3044 additions and 13029 deletions
|
@ -95,8 +95,8 @@ if test "x$HAVE_X" = xyes; then
|
|||
QF_NEED(iqm, [vulkan])
|
||||
QF_NEED(sprite, [vulkan])
|
||||
fi
|
||||
QF_NEED(vid_render, [sw sw32 gl glsl])
|
||||
QF_NEED(render, [sw sw32 gl glsl])
|
||||
QF_NEED(vid_render, [sw gl glsl])
|
||||
QF_NEED(render, [sw gl glsl])
|
||||
QF_NEED(models, [sw gl glsl])
|
||||
QF_NEED(alias, [sw gl glsl])
|
||||
QF_NEED(brush, [sw gl glsl])
|
||||
|
@ -120,8 +120,8 @@ if test "x$HAVE_SDL" = xyes; then
|
|||
NQ_DESKTOP_DATA="$NQ_DESKTOP_DATA desktop/quakeforge-nq-sdl.desktop"
|
||||
CL_TARGETS="$CL_TARGETS SDL"
|
||||
VID_TARGETS="$VID_TARGETS libs/video/targets/libQFsdl.la"
|
||||
QF_NEED(vid_render, [sw sw32 gl glsl])
|
||||
QF_NEED(render, [sw sw32 gl glsl])
|
||||
QF_NEED(vid_render, [sw gl glsl])
|
||||
QF_NEED(render, [sw gl glsl])
|
||||
QF_NEED(models, [sw gl glsl])
|
||||
QF_NEED(alias, [sw gl glsl])
|
||||
QF_NEED(brush, [sw gl glsl])
|
||||
|
@ -175,7 +175,7 @@ if test "x$mingw" = xyes; then
|
|||
QF_NEED(iqm, [vulkan])
|
||||
QF_NEED(sprite, [vulkan])
|
||||
fi
|
||||
QF_NEED(vid_render, [sw sw32 gl glsl])
|
||||
QF_NEED(vid_render, [sw gl glsl])
|
||||
QF_NEED(models, [sw gl glsl])
|
||||
QF_NEED(alias, [sw gl glsl])
|
||||
QF_NEED(brush, [sw gl glsl])
|
||||
|
@ -356,8 +356,8 @@ QF_SUBST(progs_gz)
|
|||
QF_PROCESS_NEED_LIST(top, [libs hw nq qtv qw tools ruamoko])
|
||||
|
||||
QF_PROCESS_NEED_LIBS(swrend, [asm])
|
||||
QF_PROCESS_NEED_LIBS(render, [gl glsl sw sw32 vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_LIST(vid_render, [gl glsl sw sw32 vulkan])
|
||||
QF_PROCESS_NEED_LIBS(render, [gl glsl sw vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_LIST(vid_render, [gl glsl sw vulkan])
|
||||
QF_PROCESS_NEED_LIBS(models, [gl glsl sw vulkan], [libs/models])
|
||||
QF_PROCESS_NEED_LIBS(alias, [gl glsl sw vulkan], [libs/models/alias])
|
||||
QF_PROCESS_NEED_LIBS(brush, [gl glsl sw vulkan], [libs/models/brush])
|
||||
|
@ -407,7 +407,7 @@ if test "x$static_plugins" = xauto; then
|
|||
fi
|
||||
fi
|
||||
if test "x$static_plugins" = xyes; then
|
||||
QF_PROCESS_NEED_STATIC_PLUGINS(vid_render, [sw sw32 glsl gl vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_STATIC_PLUGINS(vid_render, [sw glsl gl vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_STATIC_PLUGINS(console, [server], [libs/console], [server])
|
||||
QF_PROCESS_NEED_STATIC_PLUGINS(console, [client], [libs/console], [client])
|
||||
|
||||
|
@ -422,7 +422,7 @@ if test "x$static_plugins" = xyes; then
|
|||
CDTYPE="$CDTYPE (static)"
|
||||
fi
|
||||
else
|
||||
QF_PROCESS_NEED_PLUGINS(vid_render, [sw sw32 glsl gl vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_PLUGINS(vid_render, [sw glsl gl vulkan], [libs/video/renderer])
|
||||
QF_PROCESS_NEED_PLUGINS(console, [server], [libs/console], [server])
|
||||
QF_PROCESS_NEED_PLUGINS(console, [client], [libs/console], [client])
|
||||
QF_PROCESS_NEED_PLUGINS(snd_output, [sdl mme sgi sun win dx oss jack alsa], [libs/audio/targets])
|
||||
|
|
|
@ -83,7 +83,6 @@ struct gl_ctx_s *X11_GL_Context (void);
|
|||
void X11_GL_Init_Cvars (void);
|
||||
|
||||
struct sw_ctx_s *X11_SW_Context (void);
|
||||
struct sw_ctx_s *X11_SW32_Context (void);
|
||||
void X11_SW_Init_Cvars (void); // sw and sw32 cvars shared
|
||||
|
||||
struct vulkan_ctx_s *X11_Vulkan_Context (void);
|
||||
|
|
|
@ -18,7 +18,6 @@ typedef struct vid_internal_s {
|
|||
|
||||
struct gl_ctx_s *(*gl_context) (void);
|
||||
struct sw_ctx_s *(*sw_context) (void);
|
||||
struct sw_ctx_s *(*sw32_context) (void);
|
||||
struct vulkan_ctx_s *(*vulkan_context) (void);
|
||||
} vid_internal_t;
|
||||
|
||||
|
@ -26,10 +25,10 @@ extern struct cvar_s *vid_fullscreen;
|
|||
extern struct cvar_s *vid_system_gamma;
|
||||
extern struct cvar_s *vid_gamma;
|
||||
|
||||
extern unsigned short sw32_8to16table[256];
|
||||
|
||||
void VID_GetWindowSize (int def_w, int def_h);
|
||||
|
||||
extern unsigned short d_8to16table[256];
|
||||
|
||||
void VID_InitGamma (const byte *);
|
||||
qboolean VID_SetGamma (double);
|
||||
void VID_UpdateGamma (struct cvar_s *);
|
||||
|
|
|
@ -1,19 +1,46 @@
|
|||
#ifndef __vid_sw_h
|
||||
#define __vid_sw_h
|
||||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
struct surf_s;
|
||||
struct vrect_s;
|
||||
struct particle_s;
|
||||
struct spanpackage_s;
|
||||
struct qpic_s;
|
||||
struct espan_s;
|
||||
struct sspan_s;
|
||||
|
||||
typedef struct sw_draw_s {
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
rettype (*name) params;
|
||||
#include "vid_sw_draw.h"
|
||||
} sw_draw_t;
|
||||
|
||||
struct vrect_s;
|
||||
typedef struct sw_ctx_s {
|
||||
int pixbytes;
|
||||
void (*choose_visual) (struct sw_ctx_s *ctx);
|
||||
void (*create_context) (struct sw_ctx_s *ctx);
|
||||
void (*set_palette) (struct sw_ctx_s *ctx, const byte *palette);
|
||||
void (*update) (struct sw_ctx_s *ctx, struct vrect_s *rects);
|
||||
void (*choose_visual) (struct sw_ctx_s *ctx);
|
||||
void (*create_context) (struct sw_ctx_s *ctx);
|
||||
void (*set_palette) (struct sw_ctx_s *ctx, const byte *palette);
|
||||
void (*update) (struct sw_ctx_s *ctx, struct vrect_s *rects);
|
||||
sw_draw_t *draw;
|
||||
} sw_ctx_t;
|
||||
|
||||
extern sw_ctx_t *sw_ctx;
|
||||
extern sw_ctx_t *sw32_ctx;
|
||||
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
rettype name##_8 params;
|
||||
#include "vid_sw_draw.h"
|
||||
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
rettype name##_16 params;
|
||||
#include "vid_sw_draw.h"
|
||||
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
rettype name##_32 params;
|
||||
#include "vid_sw_draw.h"
|
||||
|
||||
struct tex_s *sw_SCR_CaptureBGR (void);
|
||||
struct tex_s *sw32_SCR_CaptureBGR (void);
|
||||
|
||||
#endif//__vid_sw_h
|
||||
|
|
25
include/vid_sw_draw.h
Normal file
25
include/vid_sw_draw.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef SW_DRAW_FUNC
|
||||
#define SW_DRAW_FUNC(name, rettype, params)
|
||||
#endif
|
||||
|
||||
SW_DRAW_FUNC(draw_solid_usrface, void, (struct surf_s *surf, int color))
|
||||
SW_DRAW_FUNC(draw_particle, void, (struct particle_s *particle))
|
||||
SW_DRAW_FUNC(polyset_draw_spans, void, (struct spanpackage_s *spanpackage))
|
||||
SW_DRAW_FUNC(draw_character, void, (int x, int y, byte *source, int drawline))
|
||||
SW_DRAW_FUNC(draw_pixel, void, (int x, int y, byte color))
|
||||
SW_DRAW_FUNC(draw_subpic, void, (int x, int y, struct qpic_s *pic, int srcx, int srcy, int width, int height))
|
||||
SW_DRAW_FUNC(draw_console_background, void, (int lines, byte *data))
|
||||
SW_DRAW_FUNC(draw_rect, void, (struct vrect_s *rect, int rowbytes, byte *src, int transparent))
|
||||
SW_DRAW_FUNC(draw_fill, void, (int x, int y, int w, int h, int c))
|
||||
SW_DRAW_FUNC(draw_fadescreen, void, (void))
|
||||
SW_DRAW_FUNC(draw_blendscreen, void, (quat_t color))
|
||||
SW_DRAW_FUNC(warp_screen, void, (void))
|
||||
SW_DRAW_FUNC(draw_turbulent_span, void, (void))
|
||||
SW_DRAW_FUNC(draw_spans, void, (struct espan_s *span))
|
||||
SW_DRAW_FUNC(draw_sky_scans, void, (struct espan_s *span))
|
||||
SW_DRAW_FUNC(sprite_draw_spans, void, (struct sspan_s *span))
|
||||
SW_DRAW_FUNC(draw_z_point, void, (void))
|
||||
SW_DRAW_FUNC(line_grapn, void, (int x, int y, int *h_vals, int count, int height))
|
||||
SW_DRAW_FUNC(make_sky, void, (void))
|
||||
SW_DRAW_FUNC(capture_bgr, struct tex_s *, (void))
|
||||
#undef SW_DRAW_FUNC
|
|
@ -11,7 +11,6 @@ noinst_LTLIBRARIES += \
|
|||
#plugins
|
||||
EXTRA_LTLIBRARIES += \
|
||||
libs/video/renderer/vid_render_sw.la \
|
||||
libs/video/renderer/vid_render_sw32.la \
|
||||
libs/video/renderer/vid_render_gl.la \
|
||||
libs/video/renderer/vid_render_glsl.la \
|
||||
libs/video/renderer/vid_render_vulkan.la
|
||||
|
@ -19,7 +18,6 @@ EXTRA_LTLIBRARIES += \
|
|||
#helper libraries
|
||||
EXTRA_LTLIBRARIES += \
|
||||
libs/video/renderer/librender_sw.la \
|
||||
libs/video/renderer/librender_sw32.la \
|
||||
libs/video/renderer/librender_gl.la \
|
||||
libs/video/renderer/librender_glsl.la \
|
||||
libs/video/renderer/librender_vulkan.la
|
||||
|
@ -140,7 +138,6 @@ libs_video_renderer_librender_sw_la_SOURCES = \
|
|||
libs/video/renderer/sw/d_copy.S \
|
||||
libs/video/renderer/sw/d_draw.S \
|
||||
libs/video/renderer/sw/d_edge.c \
|
||||
libs/video/renderer/sw/d_fill.c \
|
||||
libs/video/renderer/sw/d_init.c \
|
||||
libs/video/renderer/sw/d_modech.c \
|
||||
libs/video/renderer/sw/d_part.c \
|
||||
|
@ -183,47 +180,6 @@ libs_video_renderer_librender_sw_la_SOURCES = \
|
|||
libs/video/renderer/sw/transform.S \
|
||||
libs/video/renderer/sw/vid_common_sw.c
|
||||
|
||||
video_renderer_sw32_libs= \
|
||||
libs/video/renderer/librender_sw32.la \
|
||||
libs/models/libmodels_sw.la
|
||||
libs_video_renderer_vid_render_sw32_la_LDFLAGS= $(plugin_ldflags)
|
||||
libs_video_renderer_vid_render_sw32_la_LIBADD= $(video_renderer_sw32_libs)
|
||||
libs_video_renderer_vid_render_sw32_la_DEPENDENCIES=$(video_renderer_sw32_libs)
|
||||
libs_video_renderer_vid_render_sw32_la_SOURCES=\
|
||||
$(video_renderer_common_sources) \
|
||||
libs/video/renderer/vid_render_sw32.c
|
||||
|
||||
libs_video_renderer_librender_sw32_la_SOURCES = \
|
||||
libs/video/renderer/sw32/d_edge.c \
|
||||
libs/video/renderer/sw32/d_fill.c \
|
||||
libs/video/renderer/sw32/d_init.c \
|
||||
libs/video/renderer/sw32/d_modech.c \
|
||||
libs/video/renderer/sw32/d_part.c \
|
||||
libs/video/renderer/sw32/d_polyse.c \
|
||||
libs/video/renderer/sw32/d_scan.c \
|
||||
libs/video/renderer/sw32/d_sky.c \
|
||||
libs/video/renderer/sw32/d_sprite.c \
|
||||
libs/video/renderer/sw32/d_surf.c \
|
||||
libs/video/renderer/sw32/d_vars.c \
|
||||
libs/video/renderer/sw32/d_zpoint.c \
|
||||
libs/video/renderer/sw32/draw.c \
|
||||
libs/video/renderer/sw32/namehack.h \
|
||||
libs/video/renderer/sw32/screen.c \
|
||||
libs/video/renderer/sw32/sw32_graph.c \
|
||||
libs/video/renderer/sw32/sw32_raclip.c \
|
||||
libs/video/renderer/sw32/sw32_ralias.c \
|
||||
libs/video/renderer/sw32/sw32_rbsp.c \
|
||||
libs/video/renderer/sw32/sw32_rdraw.c \
|
||||
libs/video/renderer/sw32/sw32_redge.c \
|
||||
libs/video/renderer/sw32/sw32_riqm.c \
|
||||
libs/video/renderer/sw32/sw32_rmain.c \
|
||||
libs/video/renderer/sw32/sw32_rmisc.c \
|
||||
libs/video/renderer/sw32/sw32_rpart.c \
|
||||
libs/video/renderer/sw32/sw32_rsky.c \
|
||||
libs/video/renderer/sw32/sw32_rsprite.c \
|
||||
libs/video/renderer/sw32/sw32_rsurf.c \
|
||||
libs/video/renderer/sw32/vid_common_sw32.c
|
||||
|
||||
pipeline_src = libs/video/renderer/vulkan/qfpipeline.plist
|
||||
pipeline_gen = libs/video/renderer/vulkan/qfpipeline.plc
|
||||
renderpass_src = libs/video/renderer/vulkan/deferred.plist
|
||||
|
|
|
@ -99,8 +99,8 @@ LClampHigh5:
|
|||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawSpans8)
|
||||
C(D_DrawSpans8):
|
||||
.globl C(draw_spans_8)
|
||||
C(draw_spans_8):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static int miplevel;
|
||||
|
||||
|
@ -72,15 +74,14 @@ D_MipLevelForScale (float scale)
|
|||
|
||||
// FIXME: clean this up
|
||||
|
||||
static void
|
||||
D_DrawSolidSurface (surf_t *surf, int color)
|
||||
void
|
||||
draw_solid_usrface_8 (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) {
|
||||
for (espan_t *span = surf->spans; span; span = span->pnext) {
|
||||
pdest = (byte *) d_viewbuffer + screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
|
@ -103,6 +104,39 @@ D_DrawSolidSurface (surf_t *surf, int color)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_solid_usrface_16 (surf_t *surf, int color)
|
||||
{
|
||||
short *pdest, pix;
|
||||
int u, u2;
|
||||
|
||||
pix = d_8to16table[color];
|
||||
for (espan_t *span = surf->spans; span; span = span->pnext) {
|
||||
pdest = (short *) d_viewbuffer + screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
for (;u <= u2; u++) {
|
||||
pdest[u] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_solid_usrface_32 (surf_t *surf, int color)
|
||||
{
|
||||
int *pdest, pix;
|
||||
int u, u2;
|
||||
|
||||
pix = d_8to24table[color];
|
||||
for (espan_t *span = surf->spans; span; span = span->pnext) {
|
||||
pdest = (int *) d_viewbuffer + screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
for (;u <= u2; u++) {
|
||||
pdest[u] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
D_CalcGradients (msurface_t *pface)
|
||||
|
@ -167,7 +201,8 @@ D_DrawSurfaces (void)
|
|||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
D_DrawSolidSurface (s, ((size_t) s->data & 0xFF));
|
||||
int color = (size_t) s->data & 0xff;
|
||||
sw_ctx->draw->draw_solid_usrface (s, color);
|
||||
D_DrawZSpans (s->spans);
|
||||
}
|
||||
} else {
|
||||
|
@ -183,10 +218,10 @@ D_DrawSurfaces (void)
|
|||
|
||||
if (s->flags & SURF_DRAWSKY) {
|
||||
if (!r_skymade) {
|
||||
R_MakeSky ();
|
||||
sw_ctx->draw->make_sky ();
|
||||
}
|
||||
|
||||
D_DrawSkyScans (s->spans);
|
||||
sw_ctx->draw->draw_sky_scans (s->spans);
|
||||
D_DrawZSpans (s->spans);
|
||||
} else if (s->flags & SURF_DRAWBACKGROUND) {
|
||||
// set up a gradient for the background surface that places
|
||||
|
@ -195,7 +230,8 @@ D_DrawSurfaces (void)
|
|||
d_zistepv = 0;
|
||||
d_ziorigin = -0.9;
|
||||
|
||||
D_DrawSolidSurface (s, r_clearcolor->int_val & 0xFF);
|
||||
int color = r_clearcolor->int_val & 0xff;
|
||||
sw_ctx->draw->draw_solid_usrface (s, color);
|
||||
D_DrawZSpans (s->spans);
|
||||
} else if (s->flags & SURF_DRAWTURB) {
|
||||
pface = s->data;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
|
@ -45,6 +46,7 @@ float d_scalemip[NUM_MIPS - 1];
|
|||
|
||||
static float basemip[NUM_MIPS - 1] = { 1.0, 0.5 * 0.8, 0.25 * 0.8 };
|
||||
|
||||
float d_zitable[65536];
|
||||
|
||||
void (*d_drawspans) (espan_t *pspan);
|
||||
|
||||
|
@ -60,7 +62,16 @@ D_Init (void)
|
|||
vr_data.vid->vid_internal->flush_caches = D_FlushCaches;
|
||||
vr_data.vid->vid_internal->init_caches = D_InitCaches;
|
||||
|
||||
// LordHavoc: compute 1/zi table for use in rendering code everywhere
|
||||
if (!d_zitable[1]) {
|
||||
int i;
|
||||
d_zitable[0] = 0;
|
||||
for (i = 1;i < 65536;i++)
|
||||
d_zitable[i] = (65536.0 * 65536.0 / (double) i);
|
||||
}
|
||||
|
||||
VID_InitBuffers ();
|
||||
VID_MakeColormaps ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -82,7 +93,7 @@ D_SetupFrame (void)
|
|||
if (r_dowarp)
|
||||
screenwidth = WARP_WIDTH;
|
||||
else
|
||||
screenwidth = vid.rowbytes;
|
||||
screenwidth = vid.rowbytes / sw_ctx->pixbytes;
|
||||
|
||||
d_roverwrapped = false;
|
||||
d_initial_rover = sc_rover;
|
||||
|
@ -92,7 +103,7 @@ D_SetupFrame (void)
|
|||
for (i = 0; i < (NUM_MIPS - 1); i++)
|
||||
d_scalemip[i] = basemip[i] * d_mipscale->value;
|
||||
|
||||
d_drawspans = D_DrawSpans8;
|
||||
d_drawspans = sw_ctx->draw->draw_spans;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -31,8 +31,9 @@
|
|||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
|
||||
|
||||
|
@ -70,7 +71,7 @@ D_ViewChanged (void)
|
|||
if (r_dowarp)
|
||||
rowpixels = WARP_WIDTH;
|
||||
else
|
||||
rowpixels = vid.rowbytes;
|
||||
rowpixels = vid.rowbytes / sw_ctx->pixbytes;
|
||||
|
||||
scale_for_mip = xscale;
|
||||
if (yscale > xscale)
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
#ifdef PIC
|
||||
|
@ -38,7 +40,7 @@
|
|||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawParticle (particle_t *pparticle)
|
||||
draw_particle_8 (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
|
@ -163,3 +165,260 @@ D_DrawParticle (particle_t *pparticle)
|
|||
}
|
||||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
void
|
||||
draw_particle_16 (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pparticle->pos, 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;
|
||||
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;
|
||||
|
||||
unsigned short *pdest = (unsigned short *) d_viewbuffer +
|
||||
d_scantable[v] + u,
|
||||
pixcolor = d_8to16table[(int) pparticle->icolor];
|
||||
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] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_particle_32 (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pparticle->pos, 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;
|
||||
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;
|
||||
|
||||
int *pdest = (int *) d_viewbuffer + d_scantable[v] + u,
|
||||
pixcolor = d_8to24table[(int) pparticle->icolor];
|
||||
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] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pixcolor;
|
||||
}
|
||||
}
|
||||
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] = pixcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
#define P 12+4
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawParticle)
|
||||
C(D_DrawParticle):
|
||||
.globl C(draw_particle_8)
|
||||
C(draw_particle_8):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi // preserve register variables
|
||||
pushl %ebx
|
||||
|
|
|
@ -756,8 +756,8 @@ LDone:
|
|||
.globl C(D_PolysetAff8Start)
|
||||
C(D_PolysetAff8Start):
|
||||
|
||||
.globl C(D_PolysetDrawSpans8)
|
||||
C(D_PolysetDrawSpans8):
|
||||
.globl C(polyset_draw_spans_8)
|
||||
C(polyset_draw_spans_8):
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
|
@ -594,7 +595,7 @@ InitGel (byte * palette)
|
|||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_PolysetDrawSpans8 (spanpackage_t * pspanpackage)
|
||||
polyset_draw_spans_8 (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int lcount;
|
||||
byte *lpdest;
|
||||
|
@ -651,6 +652,178 @@ D_PolysetDrawSpans8 (spanpackage_t * pspanpackage)
|
|||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
void
|
||||
polyset_draw_spans_16 (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int i, j, texscantable[2*MAX_LBM_HEIGHT], *texscan;
|
||||
// LordHavoc: compute skin row table
|
||||
for (i = 0, j = -r_affinetridesc.skinheight * r_affinetridesc.skinwidth;
|
||||
i < r_affinetridesc.skinheight*2;i++, j += r_affinetridesc.skinwidth)
|
||||
texscantable[i] = j;
|
||||
texscan = texscantable + r_affinetridesc.skinheight;
|
||||
|
||||
{
|
||||
int lcount, count = 0;
|
||||
short *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 = (short *) 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) // hidden
|
||||
{
|
||||
count = 0;
|
||||
goto skiploop16;
|
||||
}
|
||||
drawloop16:
|
||||
*lpz++ = lzi >> 16;
|
||||
*lpdest++ = ((short *)acolormap)[(llight & 0xFF00) | lptex[texscan[ltfrac >> 16] + (lsfrac >> 16)]];
|
||||
lzi += r_zistepx;
|
||||
lsfrac += r_sstepx;
|
||||
ltfrac += r_tstepx;
|
||||
llight += r_lstepx;
|
||||
}
|
||||
while (--lcount);
|
||||
goto done16;
|
||||
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) >= *lpz) // draw
|
||||
{
|
||||
lsfrac += r_sstepx * count;
|
||||
ltfrac += r_tstepx * count;
|
||||
llight += r_lstepx * count;
|
||||
lpdest += count;
|
||||
goto drawloop16;
|
||||
}
|
||||
skiploop16:
|
||||
count++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
}
|
||||
while (--lcount);
|
||||
done16: ;
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
while (pspanpackage->count != -999999);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
polyset_draw_spans_32 (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int i, j, texscantable[2*MAX_LBM_HEIGHT], *texscan;
|
||||
// LordHavoc: compute skin row table
|
||||
for (i = 0, j = -r_affinetridesc.skinheight * r_affinetridesc.skinwidth;
|
||||
i < r_affinetridesc.skinheight*2;i++, j += r_affinetridesc.skinwidth)
|
||||
texscantable[i] = j;
|
||||
texscan = texscantable + r_affinetridesc.skinheight;
|
||||
|
||||
{
|
||||
int lcount, count = 0;
|
||||
int *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 = (int *) 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) // hidden
|
||||
{
|
||||
count = 0;
|
||||
goto skiploop32;
|
||||
}
|
||||
drawloop32:
|
||||
*lpz++ = lzi >> 16;
|
||||
*lpdest++ =
|
||||
vid.colormap32[(llight & 0xFF00) |
|
||||
lptex[texscan[ltfrac >> 16] +
|
||||
(lsfrac >> 16)]];
|
||||
lzi += r_zistepx;
|
||||
lsfrac += r_sstepx;
|
||||
ltfrac += r_tstepx;
|
||||
llight += r_lstepx;
|
||||
}
|
||||
while (--lcount);
|
||||
goto done32;
|
||||
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) >= *lpz) // draw
|
||||
{
|
||||
lsfrac += r_sstepx * count;
|
||||
ltfrac += r_tstepx * count;
|
||||
llight += r_lstepx * count;
|
||||
lpdest += count;
|
||||
goto drawloop32;
|
||||
}
|
||||
skiploop32:
|
||||
count++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
}
|
||||
while (--lcount);
|
||||
done32: ;
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
while (pspanpackage->count != -999999);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
D_RasterizeAliasPolySmooth (void)
|
||||
|
@ -824,7 +997,7 @@ D_RasterizeAliasPolySmooth (void)
|
|||
originalcount = a_spans[initialrightheight].count;
|
||||
a_spans[initialrightheight].count = -999999; // mark end of the
|
||||
// spanpackages
|
||||
D_PolysetDrawSpans8 (a_spans);
|
||||
sw_ctx->draw->polyset_draw_spans (a_spans);
|
||||
|
||||
// scan out the bottom part of the right edge, if it exists
|
||||
if (pedgetable->numrightedges == 2) {
|
||||
|
@ -847,7 +1020,7 @@ D_RasterizeAliasPolySmooth (void)
|
|||
d_countextrastep = ubasestep + 1;
|
||||
a_spans[initialrightheight + height].count = -999999;
|
||||
// mark end of the spanpackages
|
||||
D_PolysetDrawSpans8 (pstart);
|
||||
sw_ctx->draw->polyset_draw_spans (pstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
byte *r_turb_pbase;
|
||||
byte *r_turb_pdest;
|
||||
|
@ -47,7 +49,7 @@ int r_turb_spancount;
|
|||
the sine warp, to keep the edges from wrapping
|
||||
*/
|
||||
void
|
||||
D_WarpScreen (void)
|
||||
warp_screen_8 (void)
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
|
@ -96,6 +98,105 @@ D_WarpScreen (void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
warp_screen_16 (void)
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
int scr_x = vr_data.scr_view->xpos;
|
||||
int scr_y = vr_data.scr_view->ylen;
|
||||
int scr_w = vr_data.scr_view->xpos;
|
||||
int scr_h = vr_data.scr_view->ylen;
|
||||
short *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
short **row;
|
||||
short *rowptr[MAXHEIGHT];
|
||||
int column[MAXWIDTH];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_w;
|
||||
hratio = h / (float) scr_h;
|
||||
|
||||
for (v = 0; v < scr_h + AMP2 * 2; v++) {
|
||||
rowptr[v] = (short *) d_viewbuffer +
|
||||
(r_refdef.vrect.y * screenwidth) +
|
||||
(screenwidth * (int) ((float) v * hratio * h /
|
||||
(h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_w + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
dest = (short *) vid.buffer + scr_y * (vid.rowbytes >> 1) + scr_x;
|
||||
|
||||
for (v = 0; v < scr_h; v++, dest += (vid.rowbytes >> 1)) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_w; 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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
warp_screen_32 (void)
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
int scr_x = vr_data.scr_view->xpos;
|
||||
int scr_y = vr_data.scr_view->ylen;
|
||||
int scr_w = vr_data.scr_view->xpos;
|
||||
int scr_h = vr_data.scr_view->ylen;
|
||||
int *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
int **row;
|
||||
int *rowptr[MAXHEIGHT];
|
||||
int column[MAXWIDTH];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_w;
|
||||
hratio = h / (float) scr_h;
|
||||
|
||||
for (v = 0; v < scr_h + AMP2 * 2; v++) {
|
||||
rowptr[v] = (int *) d_viewbuffer +
|
||||
(r_refdef.vrect.y * screenwidth) +
|
||||
(screenwidth * (int) ((float) v * hratio * h /
|
||||
(h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_w + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
dest = (int *) vid.buffer + scr_y * (vid.rowbytes >> 2) + scr_x;
|
||||
|
||||
for (v = 0; v < scr_h; v++, dest += (vid.rowbytes >> 2)) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_w; 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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PIC
|
||||
#undef USE_INTEL_ASM //XXX asm pic hack
|
||||
|
@ -103,7 +204,7 @@ D_WarpScreen (void)
|
|||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawTurbulent8Span (void)
|
||||
draw_turbulent_span_8 (void)
|
||||
{
|
||||
int sturb, tturb;
|
||||
|
||||
|
@ -121,6 +222,41 @@ D_DrawTurbulent8Span (void)
|
|||
}
|
||||
#endif // !USE_INTEL_ASM
|
||||
|
||||
void
|
||||
draw_turbulent_span_16 (void)
|
||||
{
|
||||
int sturb, tturb;
|
||||
short *pdest = (short *) r_turb_pdest;
|
||||
|
||||
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;
|
||||
*pdest++ = d_8to16table[r_turb_pbase[(tturb << 6) + sturb]];
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
r_turb_pdest = (byte *)pdest;
|
||||
}
|
||||
|
||||
void
|
||||
draw_turbulent_span_32 (void)
|
||||
{
|
||||
int sturb, tturb;
|
||||
int *pdest = (int *) r_turb_pdest;
|
||||
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;
|
||||
*pdest++ = d_8to24table[r_turb_pbase[(tturb << 6) + sturb]];
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
r_turb_pdest = (byte *)pdest;
|
||||
}
|
||||
|
||||
void
|
||||
Turbulent (espan_t *pspan)
|
||||
{
|
||||
|
@ -236,7 +372,7 @@ Turbulent (espan_t *pspan)
|
|||
r_turb_s = r_turb_s & ((CYCLE << 16) - 1);
|
||||
r_turb_t = r_turb_t & ((CYCLE << 16) - 1);
|
||||
|
||||
D_DrawTurbulent8Span ();
|
||||
sw_ctx->draw->draw_turbulent_span ();
|
||||
|
||||
r_turb_s = snext;
|
||||
r_turb_t = tnext;
|
||||
|
@ -248,7 +384,7 @@ Turbulent (espan_t *pspan)
|
|||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawSpans8 (espan_t *pspan)
|
||||
draw_spans_8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount;
|
||||
unsigned char *pbase, *pdest;
|
||||
|
@ -373,6 +509,285 @@ D_DrawSpans8 (espan_t *pspan)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
draw_spans_16 (espan_t *pspan)
|
||||
{
|
||||
short *pbase = (short *) cacheblock, *pdest;
|
||||
int count;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
do {
|
||||
pdest = (short *) 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) * 65536.0f;
|
||||
z = d_zitable[(unsigned short) zi];
|
||||
|
||||
s = (int) (sdivz * z) + sadjust;
|
||||
s = bound(0, s, bbextents);
|
||||
t = (int) (tdivz * z) + tadjust;
|
||||
t = bound(0, t, bbextentt);
|
||||
|
||||
while(count >= 8) {
|
||||
count -= 8;
|
||||
// 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 = d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
snext = bound(8, snext, bbextents);
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
tnext = bound(8, tnext, bbextentt);
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[4] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[5] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[6] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[7] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s = snext;t = tnext;
|
||||
pdest += 8;
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
// 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
|
||||
//countminus1 = (float) (count - 1);
|
||||
sdivz += d_sdivzstepu * count; //minus1;
|
||||
tdivz += d_tdivzstepu * count; //minus1;
|
||||
zi += d_zistepu * 65536.0f * count; //minus1;
|
||||
z = d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
snext = bound(count, snext, bbextents);
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
tnext = bound(count, tnext, bbextentt);
|
||||
|
||||
if (count > 1) {
|
||||
sstep = (snext - s) / count; //(count - 1);
|
||||
tstep = (tnext - t) / count; //(count - 1);
|
||||
|
||||
if (count & 4)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;t += tstep;
|
||||
pdest += 4;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 2;
|
||||
}
|
||||
if (count & 1)
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
}
|
||||
}
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
draw_spans_32 (espan_t *pspan)
|
||||
{
|
||||
int *pbase = (int *) cacheblock, *pdest;
|
||||
int count;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
do {
|
||||
pdest = (int *) 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) * 65536.0f;
|
||||
z = d_zitable[(unsigned short) zi];
|
||||
|
||||
s = (int) (sdivz * z) + sadjust;
|
||||
s = bound(0, s, bbextents);
|
||||
t = (int) (tdivz * z) + tadjust;
|
||||
t = bound(0, t, bbextentt);
|
||||
|
||||
while(count >= 8) {
|
||||
count -= 8;
|
||||
// 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 = d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
snext = bound(8, snext, bbextents);
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
tnext = bound(8, tnext, bbextentt);
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[4] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[5] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[6] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[7] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s = snext;
|
||||
t = tnext;
|
||||
pdest += 8;
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
// 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
|
||||
//countminus1 = (float) (count - 1);
|
||||
sdivz += d_sdivzstepu * count; //minus1;
|
||||
tdivz += d_tdivzstepu * count; //minus1;
|
||||
zi += d_zistepu * 65536.0f * count; //minus1;
|
||||
z = d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
snext = bound(count, snext, bbextents);
|
||||
tnext = (int) (tdivz * z) + tadjust;
|
||||
tnext = bound(count, tnext, bbextentt);
|
||||
|
||||
if (count > 1) {
|
||||
sstep = (snext - s) / count; //(count - 1);
|
||||
tstep = (tnext - t) / count; //(count - 1);
|
||||
|
||||
if (count & 4)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 4;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 2;
|
||||
}
|
||||
if (count & 1)
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * cachewidth + (s >> 16)];
|
||||
}
|
||||
}
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_DrawZSpans (espan_t *pspan)
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawTurbulent8Span)
|
||||
C(D_DrawTurbulent8Span):
|
||||
.globl C(draw_turbulent_span_8)
|
||||
C(draw_turbulent_span_8):
|
||||
pushl %ebp // preserve caller's stack frame pointer
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define SKY_SPAN_SHIFT 5
|
||||
#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
|
||||
|
@ -65,7 +66,7 @@ D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
|||
}
|
||||
|
||||
void
|
||||
D_DrawSkyScans (espan_t *pspan)
|
||||
draw_sky_scans_8 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
unsigned char *pdest;
|
||||
|
@ -133,3 +134,141 @@ D_DrawSkyScans (espan_t *pspan)
|
|||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
draw_sky_scans_16 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
short *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
snext = 0; // ditto
|
||||
tnext = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (short *) 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++ = ((short *) 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);
|
||||
}
|
||||
|
||||
void
|
||||
draw_sky_scans_32 (espan_t *pspan)
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
int *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
snext = 0; // ditto
|
||||
tnext = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (int *) 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++ = ((int *) 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);
|
||||
}
|
||||
|
|
|
@ -95,8 +95,8 @@ LClampHigh5:
|
|||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_SpriteDrawSpans)
|
||||
C(D_SpriteDrawSpans):
|
||||
.globl C(sprite_draw_spans_8)
|
||||
C(sprite_draw_spans_8):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static int sprite_height;
|
||||
static int minindex, maxindex;
|
||||
|
@ -45,7 +47,7 @@ static sspan_t *sprite_spans;
|
|||
|
||||
#ifndef USE_INTEL_ASM
|
||||
void
|
||||
D_SpriteDrawSpans (sspan_t *pspan)
|
||||
sprite_draw_spans_8 (sspan_t *pspan)
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
|
@ -194,6 +196,307 @@ D_SpriteDrawSpans (sspan_t *pspan)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sprite_draw_spans_16 (sspan_t *pspan)
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase;
|
||||
short *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 = (byte *) cacheblock;
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (short *) d_viewbuffer + screenwidth * pspan->v + pspan->u;
|
||||
pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan2;
|
||||
|
||||
// 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) * 65536.0f;
|
||||
z = d_zitable[(int) zi];
|
||||
// we count on FP exceptions being turned off to avoid range
|
||||
// problems
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
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 = d_zitable[(int) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from causing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
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 * 65536.0f * spancountminus1;
|
||||
z = d_zitable[(int) zi];
|
||||
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 != TRANSPARENT_COLOR) {
|
||||
if (*pz <= (izi >> 16)) {
|
||||
*pz = izi >> 16;
|
||||
*pdest = d_8to16table[btemp];
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan2:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
|
||||
void
|
||||
sprite_draw_spans_32 (sspan_t *pspan)
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase;
|
||||
int *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 = (byte *) cacheblock;
|
||||
|
||||
sdivz8stepu = d_sdivzstepu * 8;
|
||||
tdivz8stepu = d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (int *) d_viewbuffer + screenwidth * pspan->v + pspan->u;
|
||||
pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan4;
|
||||
|
||||
// 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) * 65536.0f;
|
||||
z = d_zitable[(int) zi];
|
||||
// we count on FP exceptions being turned off to avoid range
|
||||
// problems
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
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 = d_zitable[(int) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from causing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
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 * 65536.0f * spancountminus1;
|
||||
z = d_zitable[(int) zi];
|
||||
snext = (int) (sdivz * z) + sadjust;
|
||||
if (snext > bbextents)
|
||||
snext = bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps fromcausing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
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 != TRANSPARENT_COLOR) {
|
||||
if (*pz <= (izi >> 16)) {
|
||||
*pz = izi >> 16;
|
||||
*pdest = d_8to24table[btemp];
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan4:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
|
||||
static void
|
||||
D_SpriteScanLeftEdge (void)
|
||||
{
|
||||
|
@ -412,5 +715,5 @@ D_DrawSprite (void)
|
|||
D_SpriteCalculateGradients ();
|
||||
D_SpriteScanLeftEdge ();
|
||||
D_SpriteScanRightEdge ();
|
||||
D_SpriteDrawSpans (sprite_spans);
|
||||
sw_ctx->draw->sprite_draw_spans (sprite_spans);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "compat.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
float surfscale;
|
||||
|
||||
|
@ -69,7 +70,7 @@ D_SurfaceCacheForRes (void *data, int width, int height)
|
|||
if (pix > 64000)
|
||||
size += (pix - 64000) * 3;
|
||||
|
||||
return size;
|
||||
return size * sw_ctx->pixbytes;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -141,7 +142,7 @@ D_SCAlloc (int width, int size)
|
|||
if ((width < 0) || (width > 512)) // FIXME shouldn't really have a max
|
||||
Sys_Error ("D_SCAlloc: bad cache width %d", width);
|
||||
|
||||
if ((size <= 0) || (size > 0x40000)) // FIXME ditto
|
||||
if ((size <= 0) || (size > 0x40000 * sw_ctx->pixbytes)) // FIXME ditto
|
||||
Sys_Error ("D_SCAlloc: bad cache size %d", size);
|
||||
|
||||
// This adds the offset of data[0] in the surfcache_t struct.
|
||||
|
@ -195,7 +196,8 @@ D_SCAlloc (int width, int size)
|
|||
new->width = width;
|
||||
// DEBUG
|
||||
if (width > 0)
|
||||
new->height = (size - sizeof (*new) + sizeof (new->data)) / width;
|
||||
new->height = (size - sizeof (*new) + sizeof (new->data)) /
|
||||
(width * sw_ctx->pixbytes);
|
||||
|
||||
new->owner = NULL; // should be set properly after return
|
||||
|
||||
|
@ -252,14 +254,14 @@ D_CacheSurface (msurface_t *surface, int miplevel)
|
|||
surfscale = 1.0 / (1 << miplevel);
|
||||
r_drawsurf.surfmip = miplevel;
|
||||
r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
|
||||
r_drawsurf.rowbytes = r_drawsurf.surfwidth;
|
||||
r_drawsurf.rowbytes = r_drawsurf.surfwidth * sw_ctx->pixbytes;
|
||||
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);
|
||||
r_drawsurf.rowbytes * r_drawsurf.surfheight);
|
||||
surface->cachespots[miplevel] = cache;
|
||||
cache->owner = &surface->cachespots[miplevel];
|
||||
cache->mipscale = surfscale;
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
void
|
||||
D_DrawZPoint (void)
|
||||
draw_z_point_8 (void)
|
||||
{
|
||||
byte *pdest;
|
||||
short *pz;
|
||||
|
@ -48,3 +50,35 @@ D_DrawZPoint (void)
|
|||
*pdest = r_zpointdesc.color;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_z_point_16 (void)
|
||||
{
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u;
|
||||
izi = (int) (r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi) {
|
||||
*pz = izi;
|
||||
((short *) d_viewbuffer) [d_scantable[r_zpointdesc.v]
|
||||
+ r_zpointdesc.u] = d_8to16table[r_zpointdesc.color];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_z_point_32 (void)
|
||||
{
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u;
|
||||
izi = (int) (r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi) {
|
||||
*pz = izi;
|
||||
((int *) d_viewbuffer) [d_scantable[r_zpointdesc.v]
|
||||
+ r_zpointdesc.u] = d_8to24table[r_zpointdesc.color];
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,9 +37,8 @@
|
|||
#include "vid_sw.h"
|
||||
|
||||
/* SCREEN SHOTS */
|
||||
|
||||
tex_t *
|
||||
sw_SCR_CaptureBGR (void)
|
||||
capture_bgr_8 (void)
|
||||
{
|
||||
int count, x, y;
|
||||
tex_t *tex;
|
||||
|
@ -66,3 +65,21 @@ sw_SCR_CaptureBGR (void)
|
|||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
tex_t *
|
||||
capture_bgr_16 (void)
|
||||
{
|
||||
return capture_bgr_8 ();//FIXME
|
||||
}
|
||||
|
||||
tex_t *
|
||||
capture_bgr_32 (void)
|
||||
{
|
||||
return capture_bgr_8 ();//FIXME
|
||||
}
|
||||
|
||||
tex_t *
|
||||
sw_SCR_CaptureBGR (void)
|
||||
{
|
||||
return sw_ctx->draw->capture_bgr ();
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ C(R_Surf8Start):
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock_mip0)
|
||||
C(R_DrawSurfaceBlock_mip0):
|
||||
.globl C(R_DrawSurfaceBlock8_mip0)
|
||||
C(R_DrawSurfaceBlock8_mip0):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
@ -70,7 +70,7 @@ C(R_DrawSurfaceBlock_mip0):
|
|||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(psource),%esi
|
||||
|
||||
Lv_loop_mip0:
|
||||
|
||||
|
@ -256,8 +256,8 @@ LBPatch15:
|
|||
movl %edx,C(lightright)
|
||||
jc Lblockloop8_mip0
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
// if (psource >= r_sourcemax)
|
||||
// psource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip0
|
||||
|
@ -281,8 +281,8 @@ LSkip_mip0:
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock_mip1)
|
||||
C(R_DrawSurfaceBlock_mip1):
|
||||
.globl C(R_DrawSurfaceBlock8_mip1)
|
||||
C(R_DrawSurfaceBlock8_mip1):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
@ -296,7 +296,7 @@ C(R_DrawSurfaceBlock_mip1):
|
|||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(psource),%esi
|
||||
|
||||
Lv_loop_mip1:
|
||||
|
||||
|
@ -426,8 +426,8 @@ LBPatch29:
|
|||
|
||||
jc Lblockloop8_mip1
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
// if (psource >= r_sourcemax)
|
||||
// psource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip1
|
||||
|
@ -451,8 +451,8 @@ LSkip_mip1:
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock_mip2)
|
||||
C(R_DrawSurfaceBlock_mip2):
|
||||
.globl C(R_DrawSurfaceBlock8_mip2)
|
||||
C(R_DrawSurfaceBlock8_mip2):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
@ -466,7 +466,7 @@ C(R_DrawSurfaceBlock_mip2):
|
|||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(psource),%esi
|
||||
|
||||
Lv_loop_mip2:
|
||||
|
||||
|
@ -566,8 +566,8 @@ LBPatch21:
|
|||
|
||||
jc Lblockloop8_mip2
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
// if (psource >= r_sourcemax)
|
||||
// psource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip2
|
||||
|
@ -591,8 +591,8 @@ LSkip_mip2:
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock_mip3)
|
||||
C(R_DrawSurfaceBlock_mip3):
|
||||
.globl C(R_DrawSurfaceBlock8_mip3)
|
||||
C(R_DrawSurfaceBlock8_mip3):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
|
@ -606,7 +606,7 @@ C(R_DrawSurfaceBlock_mip3):
|
|||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
movl C(psource),%esi
|
||||
|
||||
Lv_loop_mip3:
|
||||
|
||||
|
@ -708,8 +708,8 @@ LBPatch31:
|
|||
addl %edx,%esi
|
||||
addl %ebp,%edi
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
// if (psource >= r_sourcemax)
|
||||
// psource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip3
|
||||
|
|
|
@ -33,23 +33,21 @@
|
|||
#include "QF/render.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
/*
|
||||
R_LineGraph
|
||||
|
||||
Called by only R_DisplayTime
|
||||
*/
|
||||
void
|
||||
R_LineGraph (int x, int y, int *h_vals, int count, int height)
|
||||
line_grapn_8 (int x, int y, int *h_vals, int count, int height)
|
||||
{
|
||||
int h, i, s, color;
|
||||
int offset = vid.rowbytes;
|
||||
byte *dest;
|
||||
|
||||
// FIXME: disable on no-buffer adapters, or put in the driver
|
||||
s = height;
|
||||
|
||||
while (count--) {
|
||||
dest = ((byte*)vid.buffer) + vid.rowbytes * y + x++;
|
||||
dest = ((byte*)vid.buffer) + offset * y + x++;
|
||||
|
||||
h = *h_vals++;
|
||||
|
||||
|
@ -65,8 +63,80 @@ R_LineGraph (int x, int y, int *h_vals, int count, int height)
|
|||
if (h > s)
|
||||
h = s;
|
||||
|
||||
for (i = 0; i < h; i++, dest -= vid.rowbytes) {
|
||||
for (i = 0; i < h; i++, dest -= offset) {
|
||||
dest[0] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
line_grapn_16 (int x, int y, int *h_vals, int count, int height)
|
||||
{
|
||||
int h, i, s, color;
|
||||
int offset = vid.rowbytes >> 1;
|
||||
uint16_t *dest;
|
||||
|
||||
// FIXME: disable on no-buffer adapters, or put in the driver
|
||||
s = height;
|
||||
|
||||
while (count--) {
|
||||
dest = ((uint16_t*)vid.buffer) + offset * y + x++;
|
||||
|
||||
h = *h_vals++;
|
||||
|
||||
if (h == 10000)
|
||||
color = d_8to16table[0x6f]; // yellow
|
||||
else if (h == 9999)
|
||||
color = d_8to16table[0x4f]; // red
|
||||
else if (h == 9998)
|
||||
color = d_8to16table[0xd0]; // blue
|
||||
else
|
||||
color = d_8to16table[0xff]; // pink
|
||||
|
||||
if (h > s)
|
||||
h = s;
|
||||
|
||||
for (i = 0; i < h; i++, dest -= offset) {
|
||||
dest[0] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
line_grapn_32 (int x, int y, int *h_vals, int count, int height)
|
||||
{
|
||||
int h, i, s, color;
|
||||
int offset = vid.rowbytes >> 2;
|
||||
uint32_t *dest;
|
||||
|
||||
// FIXME: disable on no-buffer adapters, or put in the driver
|
||||
s = height;
|
||||
|
||||
while (count--) {
|
||||
dest = ((uint32_t*)vid.buffer) + offset * y + x++;
|
||||
|
||||
h = *h_vals++;
|
||||
|
||||
if (h == 10000)
|
||||
color = d_8to24table[0x6f]; // yellow
|
||||
else if (h == 9999)
|
||||
color = d_8to24table[0x4f]; // red
|
||||
else if (h == 9998)
|
||||
color = d_8to24table[0xd0]; // blue
|
||||
else
|
||||
color = d_8to24table[0xff]; // pink
|
||||
|
||||
if (h > s)
|
||||
h = s;
|
||||
|
||||
for (i = 0; i < h; i++, dest -= offset) {
|
||||
dest[0] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_LineGraph (int x, int y, int *h_vals, int count, int height)
|
||||
{
|
||||
sw_ctx->draw->line_grapn (x, y, h_vals, count, height);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "d_ifacea.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define LIGHT_MIN 5 // lowest light value we'll allow, to
|
||||
// avoid the need for inner-loop light
|
||||
|
@ -563,6 +564,12 @@ R_AliasSetupSkin (entity_t *ent)
|
|||
r_affinetridesc.skinheight = pmdl->skinheight;
|
||||
|
||||
acolormap = vid.colormap8;
|
||||
if (sw_ctx->pixbytes != 1) {
|
||||
if (sw_ctx->pixbytes == 2)
|
||||
acolormap = vid.colormap16;
|
||||
else
|
||||
acolormap = vid.colormap32;
|
||||
}
|
||||
if (ent->renderer.skin) {
|
||||
tex_t *base;
|
||||
|
||||
|
@ -655,6 +662,12 @@ R_AliasDrawModel (alight_t *plighting)
|
|||
|
||||
if (!acolormap)
|
||||
acolormap = vid.colormap8;
|
||||
if (acolormap == vid.colormap8 && sw_ctx->pixbytes != 1) {
|
||||
if (sw_ctx->pixbytes == 2)
|
||||
acolormap = vid.colormap16;
|
||||
else
|
||||
acolormap = vid.colormap32;
|
||||
}
|
||||
|
||||
if (r_affinetridesc.drawtype) {
|
||||
D_PolysetUpdateTables (); // FIXME: precalc...
|
||||
|
|
|
@ -54,11 +54,28 @@
|
|||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#ifdef PIC
|
||||
# undef USE_INTEL_ASM //XXX asm pic hack
|
||||
#endif
|
||||
|
||||
static sw_draw_t sw_draw_8 = {
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
.name = name##_8,
|
||||
#include "vid_sw_draw.h"
|
||||
};
|
||||
static sw_draw_t sw_draw_16 = {
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
.name = name##_16,
|
||||
#include "vid_sw_draw.h"
|
||||
};
|
||||
static sw_draw_t sw_draw_32 = {
|
||||
#define SW_DRAW_FUNC(name, rettype, params) \
|
||||
.name = name##_32,
|
||||
#include "vid_sw_draw.h"
|
||||
};
|
||||
|
||||
void *colormap;
|
||||
static vec3_t viewlightvec;
|
||||
static alight_t r_viewlighting = { 128, 192, viewlightvec };
|
||||
|
@ -117,6 +134,15 @@ sw_R_Init (void)
|
|||
{
|
||||
int dummy;
|
||||
|
||||
switch (sw_ctx->pixbytes) {
|
||||
case 1: sw_ctx->draw = &sw_draw_8; break;
|
||||
case 2: sw_ctx->draw = &sw_draw_16; break;
|
||||
case 4: sw_ctx->draw = &sw_draw_32; break;
|
||||
default:
|
||||
Sys_Error("R_Init: unsupported pixbytes %i",
|
||||
sw_ctx->pixbytes);
|
||||
}
|
||||
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
|
||||
// get stack position so we can guess if we are going to overflow
|
||||
|
@ -806,7 +832,7 @@ R_RenderView_ (void)
|
|||
dp_time2 = Sys_DoubleTime ();
|
||||
|
||||
if (r_dowarp)
|
||||
D_WarpScreen ();
|
||||
sw_ctx->draw->warp_screen ();
|
||||
|
||||
if (r_timegraph->int_val)
|
||||
R_TimeGraph ();
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
void
|
||||
R_DrawParticles (void)
|
||||
|
@ -58,9 +59,10 @@ R_DrawParticles (void)
|
|||
|
||||
R_RunParticles (vr_data.frametime);
|
||||
|
||||
void (*draw) (struct particle_s *particle) = sw_ctx->draw->draw_particle;
|
||||
for (unsigned i = 0; i < r_psystem.numparticles; i++) {
|
||||
particle_t *p = &r_psystem.particles[i];
|
||||
D_DrawParticle (p);
|
||||
draw (p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,13 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
static int iskyspeed = 8;
|
||||
|
@ -47,10 +51,12 @@ int r_skymade;
|
|||
|
||||
byte bottomsky[128 * 131];
|
||||
byte bottommask[128 * 131];
|
||||
byte newsky[128 * 256]; // newsky and topsky both pack in here, 128
|
||||
// bytes of newsky on the left of each scan,
|
||||
// 128 bytes of topsky on the right, because
|
||||
// the low-level drawers need 256-byte widths
|
||||
// sky and topsky both pack in here, 128
|
||||
// bytes of sky on the left of each scan,
|
||||
// 128 bytes of topsky on the right, because
|
||||
// the low-level drawers need 256-byte widths
|
||||
byte skydata[128 * 256];
|
||||
byte skytex[128 * 256 * 4];
|
||||
|
||||
|
||||
/*
|
||||
|
@ -61,115 +67,115 @@ byte newsky[128 * 256]; // newsky and topsky both pack in here, 128
|
|||
void
|
||||
R_InitSky (texture_t *mt)
|
||||
{
|
||||
int i, j;
|
||||
byte *src;
|
||||
|
||||
src = (byte *) mt + mt->offsets[0];
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
for (j = 0; j < 128; j++) {
|
||||
newsky[(i * 256) + j + 128] = src[i * 256 + j + 128];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
for (j = 0; j < 131; j++) {
|
||||
if (src[i * 256 + (j & 0x7F)]) {
|
||||
bottomsky[(i * 131) + j] = src[i * 256 + (j & 0x7F)];
|
||||
bottommask[(i * 131) + j] = 0;
|
||||
} else {
|
||||
bottomsky[(i * 131) + j] = 0;
|
||||
bottommask[(i * 131) + j] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r_skysource = newsky;
|
||||
memcpy (skydata, (byte *) mt + mt->offsets[0], 128 * 256);
|
||||
r_skysource = skytex;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_MakeSky (void)
|
||||
make_sky_8 (void)
|
||||
{
|
||||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
byte *pnewsky;
|
||||
int x, y, xshift1, yshift1, xshift2, yshift2;
|
||||
byte *base1, *base2;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift = r_skytime * r_skyspeed;
|
||||
yshift = r_skytime * r_skyspeed;
|
||||
xshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
yshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
|
||||
if ((xshift == xlast) && (yshift == ylast))
|
||||
if ((xshift2 == xlast) && (yshift2 == ylast))
|
||||
return;
|
||||
|
||||
xlast = xshift;
|
||||
ylast = yshift;
|
||||
xlast = xshift2;
|
||||
ylast = yshift2;
|
||||
xshift1 = xshift2 >> 1;
|
||||
yshift1 = yshift2 >> 1;
|
||||
|
||||
pnewsky = &newsky[0];
|
||||
|
||||
for (y = 0; y < SKYSIZE; y++) {
|
||||
baseofs = ((y + yshift) & SKYMASK) * 131;
|
||||
for (x = 0; x < SKYSIZE; x++) {
|
||||
ofs = baseofs + ((x + xshift) & SKYMASK);
|
||||
|
||||
*pnewsky = (*(pnewsky + 128) & bottommask[ofs]) | bottomsky[ofs];
|
||||
pnewsky = pnewsky + 1;
|
||||
byte *out = (byte *) skytex;
|
||||
for (y = 0;y < 128;y++)
|
||||
{
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++)
|
||||
{
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = base1[(x + xshift1) & 127];
|
||||
else
|
||||
*out = base2[(x + xshift2) & 127];
|
||||
out++;
|
||||
}
|
||||
pnewsky += 128;
|
||||
out += 128;
|
||||
}
|
||||
|
||||
r_skymade = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
R_GenSkyTile (void *pdest)
|
||||
make_sky_16 (void)
|
||||
{
|
||||
int x, y;
|
||||
int ofs, baseofs;
|
||||
int xshift, yshift;
|
||||
unsigned int *pnewsky;
|
||||
unsigned int *pd;
|
||||
int x, y, xshift1, yshift1, xshift2, yshift2;
|
||||
byte *base1, *base2;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift = r_skytime * r_skyspeed;
|
||||
yshift = r_skytime * r_skyspeed;
|
||||
xshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
yshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
|
||||
pnewsky = (unsigned int *) &newsky[0];
|
||||
pd = (unsigned int *) pdest;
|
||||
if ((xshift2 == xlast) && (yshift2 == ylast))
|
||||
return;
|
||||
|
||||
for (y = 0; y < SKYSIZE; y++) {
|
||||
baseofs = ((y + yshift) & SKYMASK) * 131;
|
||||
xlast = xshift2;
|
||||
ylast = yshift2;
|
||||
xshift1 = xshift2 >> 1;
|
||||
yshift1 = yshift2 >> 1;
|
||||
|
||||
// FIXME: clean this up
|
||||
#if UNALIGNED_OK
|
||||
for (x = 0; x < SKYSIZE; x += 4) {
|
||||
ofs = baseofs + ((x + xshift) & SKYMASK);
|
||||
|
||||
// PORT: unaligned dword access to bottommask and bottomsky
|
||||
|
||||
*pd = (*(pnewsky + (128 / sizeof (unsigned int))) &
|
||||
*(unsigned int *) &bottommask[ofs]) |
|
||||
*(unsigned int *) &bottomsky[ofs];
|
||||
|
||||
pnewsky++;
|
||||
pd++;
|
||||
unsigned short *out = (unsigned short *) skytex;
|
||||
for (y = 0;y < 128;y++)
|
||||
{
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++)
|
||||
{
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = d_8to16table[base1[(x + xshift1) & 127]];
|
||||
else
|
||||
*out = d_8to16table[base2[(x + xshift2) & 127]];
|
||||
out++;
|
||||
}
|
||||
#else
|
||||
for (x = 0; x < SKYSIZE; x++) {
|
||||
ofs = baseofs + ((x + xshift) & SKYMASK);
|
||||
|
||||
*(byte *) pd = (*((byte *) pnewsky + 128) &
|
||||
*(byte *) & bottommask[ofs]) |
|
||||
*(byte *) & bottomsky[ofs];
|
||||
pnewsky = (unsigned int *) ((byte *) pnewsky + 1);
|
||||
pd = (unsigned int *) ((byte *) pd + 1);
|
||||
}
|
||||
#endif
|
||||
pnewsky += 128 / sizeof (unsigned int);
|
||||
out += 128;
|
||||
}
|
||||
r_skymade = 1;
|
||||
}
|
||||
|
||||
void
|
||||
make_sky_32 (void)
|
||||
{
|
||||
int x, y, xshift1, yshift1, xshift2, yshift2;
|
||||
byte *base1, *base2;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
yshift2 = r_skytime * r_skyspeed * 2.0f;
|
||||
|
||||
if ((xshift2 == xlast) && (yshift2 == ylast))
|
||||
return;
|
||||
|
||||
xlast = xshift2;
|
||||
ylast = yshift2;
|
||||
xshift1 = xshift2 >> 1;
|
||||
yshift1 = yshift2 >> 1;
|
||||
|
||||
unsigned int *out = (unsigned int *) skytex;
|
||||
for (y = 0;y < 128;y++) {
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++) {
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = d_8to24table[base1[(x + xshift1) & 127]];
|
||||
else
|
||||
*out = d_8to24table[base2[(x + xshift2) & 127]];
|
||||
out++;
|
||||
}
|
||||
out += 128;
|
||||
}
|
||||
r_skymade = 1;
|
||||
}
|
||||
|
||||
void
|
||||
R_SetSkyFrame (void)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
sw_rsurf.c
|
||||
rsurf.c
|
||||
|
||||
surface-related refresh code
|
||||
|
||||
|
@ -33,43 +33,63 @@
|
|||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
#ifdef PIC
|
||||
# undef USE_INTEL_ASM //XXX asm pic hack
|
||||
#endif
|
||||
#include "vid_sw.h"
|
||||
|
||||
drawsurf_t r_drawsurf;
|
||||
|
||||
int sourcesstep, sourcetstep;
|
||||
#ifndef USE_INTEL_ASM
|
||||
static int lightleft;
|
||||
#endif
|
||||
static int blocksize;
|
||||
int sourcetstep;
|
||||
static int lightleft, blocksize;
|
||||
int lightdelta, lightdeltastep;
|
||||
int lightright, lightleftstep, lightrightstep, blockdivshift;
|
||||
static unsigned int blockdivmask;
|
||||
void *prowdestbase;
|
||||
unsigned char *pbasesource;
|
||||
int surfrowbytes; // used by ASM files
|
||||
unsigned int *r_lightptr;
|
||||
byte *prowdestbase;
|
||||
byte *psource;
|
||||
int surfrowbytes;
|
||||
unsigned int *r_lightptr;
|
||||
int r_stepback;
|
||||
int r_lightwidth;
|
||||
static int r_numhblocks;
|
||||
int r_numvblocks;
|
||||
static unsigned char *r_source;
|
||||
unsigned char *r_sourcemax;
|
||||
static byte *r_source;
|
||||
byte *r_sourcemax;
|
||||
|
||||
void R_DrawSurfaceBlock_mip0 (void);
|
||||
void R_DrawSurfaceBlock_mip1 (void);
|
||||
void R_DrawSurfaceBlock_mip2 (void);
|
||||
void R_DrawSurfaceBlock_mip3 (void);
|
||||
void R_DrawSurfaceBlock8_mip0 (void);
|
||||
void R_DrawSurfaceBlock8_mip1 (void);
|
||||
void R_DrawSurfaceBlock8_mip2 (void);
|
||||
void R_DrawSurfaceBlock8_mip3 (void);
|
||||
static void R_DrawSurfaceBlock16_mip0 (void);
|
||||
static void R_DrawSurfaceBlock16_mip1 (void);
|
||||
static void R_DrawSurfaceBlock16_mip2 (void);
|
||||
static void R_DrawSurfaceBlock16_mip3 (void);
|
||||
static void R_DrawSurfaceBlock32_mip0 (void);
|
||||
static void R_DrawSurfaceBlock32_mip1 (void);
|
||||
static void R_DrawSurfaceBlock32_mip2 (void);
|
||||
static void R_DrawSurfaceBlock32_mip3 (void);
|
||||
|
||||
static void (*surfmiptable[4]) (void) = {
|
||||
R_DrawSurfaceBlock_mip0, R_DrawSurfaceBlock_mip1,
|
||||
R_DrawSurfaceBlock_mip2, R_DrawSurfaceBlock_mip3};
|
||||
static void (*surfmiptable8[4]) (void) = {
|
||||
R_DrawSurfaceBlock8_mip0,
|
||||
R_DrawSurfaceBlock8_mip1,
|
||||
R_DrawSurfaceBlock8_mip2,
|
||||
R_DrawSurfaceBlock8_mip3
|
||||
};
|
||||
|
||||
static unsigned int blocklights[34 * 34]; //FIXME make dynamic
|
||||
static void (*surfmiptable16[4]) (void) = {
|
||||
R_DrawSurfaceBlock16_mip0,
|
||||
R_DrawSurfaceBlock16_mip1,
|
||||
R_DrawSurfaceBlock16_mip2,
|
||||
R_DrawSurfaceBlock16_mip3
|
||||
};
|
||||
|
||||
static void (*surfmiptable32[4]) (void) = {
|
||||
R_DrawSurfaceBlock32_mip0,
|
||||
R_DrawSurfaceBlock32_mip1,
|
||||
R_DrawSurfaceBlock32_mip2,
|
||||
R_DrawSurfaceBlock32_mip3
|
||||
};
|
||||
|
||||
static unsigned blocklights[34 * 34]; //FIXME make dynamic
|
||||
|
||||
|
||||
static void
|
||||
|
@ -182,14 +202,30 @@ R_BuildLightMap (void)
|
|||
if (surf->dlightframe == r_framecount)
|
||||
R_AddDynamicLights ();
|
||||
|
||||
// bound, invert, and shift
|
||||
for (i = 0; i < size; i++) {
|
||||
t = (255 * 256 - (int) blocklights[i]) >> (8 - VID_CBITS);
|
||||
/*
|
||||
* JohnnyonFlame:
|
||||
* 32 and 16bpp modes uses the positive lighting, unlike 8bpp
|
||||
*/
|
||||
switch (sw_ctx->pixbytes) {
|
||||
case 1:
|
||||
// bound, invert, and shift
|
||||
for (i = 0; i < size; i++) {
|
||||
t = (255 * 256 - blocklights[i]) >> (8 - VID_CBITS);
|
||||
|
||||
if (t < (1 << 6))
|
||||
t = (1 << 6);
|
||||
if (t < (1 << 6))
|
||||
t = (1 << 6);
|
||||
|
||||
blocklights[i] = t;
|
||||
blocklights[i] = t;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// LordHavoc: changed to positive (not inverse) lighting
|
||||
for (i = 0; i < size; i++) {
|
||||
t = bound(256, blocklights[i] >> (8 - VID_CBITS),
|
||||
256 * (VID_GRADES - 1));
|
||||
blocklights[i] = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,34 +266,47 @@ R_DrawSurface (void)
|
|||
|
||||
//==============================
|
||||
|
||||
pblockdrawer = surfmiptable[r_drawsurf.surfmip];
|
||||
// TODO: needs to be set only when there is a display settings change
|
||||
horzblockstep = blocksize;
|
||||
|
||||
smax = mt->width >> r_drawsurf.surfmip;
|
||||
twidth = texwidth;
|
||||
tmax = mt->height >> r_drawsurf.surfmip;
|
||||
sourcetstep = texwidth;
|
||||
r_stepback = tmax * twidth;
|
||||
|
||||
r_sourcemax = r_source + (tmax * smax);
|
||||
|
||||
soffset = r_drawsurf.surf->texturemins[0];
|
||||
basetoffset = r_drawsurf.surf->texturemins[1];
|
||||
|
||||
// << 16 components are to guarantee positive values for %
|
||||
soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
|
||||
basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip)
|
||||
+ (tmax << 16)) % tmax) * twidth)];
|
||||
switch (sw_ctx->pixbytes) {
|
||||
case 1:
|
||||
pblockdrawer = surfmiptable8[r_drawsurf.surfmip];
|
||||
break;
|
||||
case 2:
|
||||
pblockdrawer = surfmiptable16[r_drawsurf.surfmip];
|
||||
break;
|
||||
case 4:
|
||||
pblockdrawer = surfmiptable32[r_drawsurf.surfmip];
|
||||
break;
|
||||
default:
|
||||
Sys_Error("R_DrawSurface: unsupported r_pixbytes %i", sw_ctx->pixbytes);
|
||||
pblockdrawer = NULL;
|
||||
}
|
||||
|
||||
pcolumndest = r_drawsurf.surfdat;
|
||||
horzblockstep = blocksize * sw_ctx->pixbytes;
|
||||
|
||||
r_sourcemax = r_source + (tmax * smax);
|
||||
|
||||
// << 16 components are to guarantee positive values for %
|
||||
basetptr = r_source + (((basetoffset >> r_drawsurf.surfmip) +
|
||||
(tmax << 16)) % tmax) * twidth;
|
||||
soffset = (((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax);
|
||||
|
||||
pcolumndest = (byte *) r_drawsurf.surfdat;
|
||||
|
||||
for (u = 0; u < r_numhblocks; u++) {
|
||||
r_lightptr = blocklights + u;
|
||||
|
||||
prowdestbase = pcolumndest;
|
||||
|
||||
pbasesource = basetptr + soffset;
|
||||
psource = basetptr + soffset;
|
||||
|
||||
(*pblockdrawer) ();
|
||||
|
||||
|
@ -269,15 +318,16 @@ R_DrawSurface (void)
|
|||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#ifndef USE_INTEL_ASM
|
||||
|
||||
void
|
||||
R_DrawSurfaceBlock_mip0 (void)
|
||||
R_DrawSurfaceBlock8_mip0 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
@ -290,15 +340,13 @@ R_DrawSurfaceBlock_mip0 (void)
|
|||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 4;
|
||||
lightstep = (lightleft - lightright) >> 4;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 15; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *) vid.colormap8)
|
||||
[(light & 0xFF00) + pix];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
|
@ -314,12 +362,11 @@ R_DrawSurfaceBlock_mip0 (void)
|
|||
}
|
||||
|
||||
void
|
||||
R_DrawSurfaceBlock_mip1 (void)
|
||||
R_DrawSurfaceBlock8_mip1 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
@ -332,15 +379,13 @@ R_DrawSurfaceBlock_mip1 (void)
|
|||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 3;
|
||||
lightstep = (lightleft - lightright) >> 3;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 7; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *) vid.colormap8)
|
||||
[(light & 0xFF00) + pix];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
|
@ -356,12 +401,11 @@ R_DrawSurfaceBlock_mip1 (void)
|
|||
}
|
||||
|
||||
void
|
||||
R_DrawSurfaceBlock_mip2 (void)
|
||||
R_DrawSurfaceBlock8_mip2 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
@ -374,15 +418,13 @@ R_DrawSurfaceBlock_mip2 (void)
|
|||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 2;
|
||||
lightstep = (lightleft - lightright) >> 2;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 3; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *) vid.colormap8)
|
||||
[(light & 0xFF00) + pix];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
|
@ -398,12 +440,11 @@ R_DrawSurfaceBlock_mip2 (void)
|
|||
}
|
||||
|
||||
void
|
||||
R_DrawSurfaceBlock_mip3 (void)
|
||||
R_DrawSurfaceBlock8_mip3 (void)
|
||||
{
|
||||
int v, i, b, lightstep, lighttemp, light;
|
||||
unsigned char pix, *psource, *prowdest;
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
psource = pbasesource;
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
@ -416,15 +457,13 @@ R_DrawSurfaceBlock_mip3 (void)
|
|||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
lighttemp = lightleft - lightright;
|
||||
lightstep = lighttemp >> 1;
|
||||
lightstep = (lightleft - lightright) >> 1;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 1; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = ((unsigned char *) vid.colormap8)
|
||||
[(light & 0xFF00) + pix];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
|
@ -442,33 +481,423 @@ R_DrawSurfaceBlock_mip3 (void)
|
|||
#endif
|
||||
|
||||
static void
|
||||
R_GenTurbTile (byte *pbasetex, void *pdest)
|
||||
R_DrawSurfaceBlock16_mip0 (void)
|
||||
{
|
||||
int *turb;
|
||||
int i, j, s, t;
|
||||
byte *pd;
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
turb = sintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
pd = (byte *) pdest;
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (i = 0; i < TILE_SIZE; i++) {
|
||||
for (j = 0; j < TILE_SIZE; j++) {
|
||||
s = (((j << 16) + turb[i & (CYCLE - 1)]) >> 16) & 63;
|
||||
t = (((i << 16) + turb[j & (CYCLE - 1)]) >> 16) & 63;
|
||||
*pd++ = *(pbasetex + (t << 6) + s);
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (k = 0; k < 16; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 4;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
|
||||
light += lightstep;
|
||||
prowdest[8] = vid.colormap16[(light & 0xFF00) + psource[8]];
|
||||
light += lightstep;
|
||||
prowdest[9] = vid.colormap16[(light & 0xFF00) + psource[9]];
|
||||
light += lightstep;
|
||||
prowdest[10] = vid.colormap16[(light & 0xFF00) + psource[10]];
|
||||
light += lightstep;
|
||||
prowdest[11] = vid.colormap16[(light & 0xFF00) + psource[11]];
|
||||
light += lightstep;
|
||||
prowdest[12] = vid.colormap16[(light & 0xFF00) + psource[12]];
|
||||
light += lightstep;
|
||||
prowdest[13] = vid.colormap16[(light & 0xFF00) + psource[13]];
|
||||
light += lightstep;
|
||||
prowdest[14] = vid.colormap16[(light & 0xFF00) + psource[14]];
|
||||
light += lightstep;
|
||||
prowdest[15] = vid.colormap16[(light & 0xFF00) + psource[15]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_GenTile (msurface_t *psurf, void *pdest)
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip1 (void)
|
||||
{
|
||||
if (psurf->flags & SURF_DRAWTURB) {
|
||||
R_GenTurbTile (((byte *) psurf->texinfo->texture +
|
||||
psurf->texinfo->texture->offsets[0]), pdest);
|
||||
} else if (psurf->flags & SURF_DRAWSKY) {
|
||||
R_GenSkyTile (pdest);
|
||||
} else {
|
||||
Sys_Error ("Unknown tile type");
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 3;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip2 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 2;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip3 (void)
|
||||
{
|
||||
int v;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
|
||||
prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip0 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (k = 0; k < 16; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 4;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
|
||||
light += lightstep;
|
||||
prowdest[8] = vid.colormap32[(light & 0xFF00) + psource[8]];
|
||||
light += lightstep;
|
||||
prowdest[9] = vid.colormap32[(light & 0xFF00) + psource[9]];
|
||||
light += lightstep;
|
||||
prowdest[10] = vid.colormap32[(light & 0xFF00) + psource[10]];
|
||||
light += lightstep;
|
||||
prowdest[11] = vid.colormap32[(light & 0xFF00) + psource[11]];
|
||||
light += lightstep;
|
||||
prowdest[12] = vid.colormap32[(light & 0xFF00) + psource[12]];
|
||||
light += lightstep;
|
||||
prowdest[13] = vid.colormap32[(light & 0xFF00) + psource[13]];
|
||||
light += lightstep;
|
||||
prowdest[14] = vid.colormap32[(light & 0xFF00) + psource[14]];
|
||||
light += lightstep;
|
||||
prowdest[15] = vid.colormap32[(light & 0xFF00) + psource[15]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip1 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 3;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip2 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 2;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip3 (void)
|
||||
{
|
||||
int v;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
|
||||
prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
R_DrawSurfaceBlock32 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> blockdivshift;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> blockdivshift;
|
||||
|
||||
for (k = 0; k < blocksize; k++) {
|
||||
int b;
|
||||
|
||||
lightstep = (lightright - lightleft) >> blockdivshift;
|
||||
|
||||
light = lightleft;
|
||||
|
||||
for (b = 0;b < blocksize;b++, light += lightstep)
|
||||
prowdest[b] = vid.colormap32[(light & 0xFF00) + psource[b]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
vid_common_sw.c
|
||||
|
||||
Common software video driver functions
|
||||
general video driver functions
|
||||
|
||||
Copyright (C) 2001 Jeff Teunissen <deek@quakeforge.net>
|
||||
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
|
||||
|
@ -28,11 +28,130 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
||||
unsigned short d_8to16table[256];
|
||||
|
||||
|
||||
/*
|
||||
VID_MakeColormap32
|
||||
|
||||
LordHavoc: makes a 32bit color*light table, RGBA order, no endian,
|
||||
may need to be re-ordered to hardware at display time
|
||||
*/
|
||||
static void
|
||||
VID_MakeColormap32 (void *outcolormap, byte *pal)
|
||||
{
|
||||
int c, l;
|
||||
byte *out;
|
||||
out = (byte *)&d_8to24table;
|
||||
|
||||
/*
|
||||
* Generates colors not affected by lighting, such as
|
||||
* HUD pieces and general sprites (such as explosions)
|
||||
*/
|
||||
for (c = 0; c < 256; c++) {
|
||||
*out++ = pal[c*3+2];
|
||||
*out++ = pal[c*3+1];
|
||||
*out++ = pal[c*3+0];
|
||||
*out++ = 255;
|
||||
}
|
||||
d_8to24table[255] = 0; // 255 is transparent
|
||||
out = (byte *) outcolormap;
|
||||
|
||||
/*
|
||||
* Generates colors affected by lighting, such as the
|
||||
* world and other models that give it life, like foes and pickups.
|
||||
*/
|
||||
for (l = 0;l < VID_GRADES;l++)
|
||||
{
|
||||
for (c = 0;c < vid.fullbright;c++)
|
||||
{
|
||||
out[(l*256+c)*4+0] = bound(0, (pal[c*3+2] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+1] = bound(0, (pal[c*3+1] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+2] = bound(0, (pal[c*3+0] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+3] = 255;
|
||||
}
|
||||
for (;c < 255;c++)
|
||||
{
|
||||
out[(l*256+c)*4+0] = pal[c*3+2];
|
||||
out[(l*256+c)*4+1] = pal[c*3+1];
|
||||
out[(l*256+c)*4+2] = pal[c*3+0];
|
||||
out[(l*256+c)*4+3] = 255;
|
||||
}
|
||||
out[(l*256+255)*4+0] = 0;
|
||||
out[(l*256+255)*4+1] = 0;
|
||||
out[(l*256+255)*4+2] = 0;
|
||||
out[(l*256+255)*4+3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
lh24to16bit (int red, int green, int blue)
|
||||
{
|
||||
red = bound(0, red, 255);
|
||||
green = bound(0, green, 255);
|
||||
blue = bound(0, blue, 255);
|
||||
red >>= 3;
|
||||
green >>= 2;
|
||||
blue >>= 3;
|
||||
red <<= 11;
|
||||
green <<= 5;
|
||||
return (unsigned short) (red | green | blue);
|
||||
}
|
||||
|
||||
/*
|
||||
VID_MakeColormap16
|
||||
|
||||
LordHavoc: makes a 16bit color*light table, RGB order, native endian,
|
||||
may need to be translated to hardware order at display time
|
||||
*/
|
||||
static void
|
||||
VID_MakeColormap16 (void *outcolormap, byte *pal)
|
||||
{
|
||||
int c, l;
|
||||
unsigned short *out;
|
||||
out = (unsigned short *)&d_8to16table;
|
||||
for (c = 0; c < 256; c++)
|
||||
*out++ = lh24to16bit(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
|
||||
d_8to16table[255] = 0; // 255 is transparent
|
||||
out = (unsigned short *) outcolormap;
|
||||
for (l = 0;l < VID_GRADES;l++)
|
||||
{
|
||||
for (c = 0;c < vid.fullbright;c++)
|
||||
out[l*256+c] = lh24to16bit(
|
||||
(pal[c*3+0] * l) >> (VID_CBITS - 1),
|
||||
(pal[c*3+1] * l) >> (VID_CBITS - 1),
|
||||
(pal[c*3+2] * l) >> (VID_CBITS - 1));
|
||||
for (;c < 255;c++)
|
||||
out[l*256+c] = lh24to16bit(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
|
||||
out[l*256+255] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
VID_MakeColormaps
|
||||
|
||||
LordHavoc: makes 8bit, 16bit, and 32bit colormaps and palettes
|
||||
*/
|
||||
void
|
||||
VID_MakeColormaps (void)
|
||||
{
|
||||
vid.colormap16 = malloc (256*VID_GRADES * sizeof (unsigned short));
|
||||
vid.colormap32 = malloc (256*VID_GRADES * sizeof (unsigned int));
|
||||
SYS_CHECKMEM (vid.colormap16 && vid.colormap32);
|
||||
VID_MakeColormap16(vid.colormap16, vid.palette);
|
||||
VID_MakeColormap32(vid.colormap32, vid.palette);
|
||||
}
|
||||
|
|
|
@ -1,325 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static int miplevel;
|
||||
|
||||
float sw32_scale_for_mip;
|
||||
|
||||
static vec3_t transformed_modelorg;
|
||||
|
||||
|
||||
void
|
||||
sw32_D_DrawPoly (void)
|
||||
{
|
||||
// this driver takes spans, not polygons
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sw32_D_MipLevelForScale (float scale)
|
||||
{
|
||||
int lmiplevel;
|
||||
|
||||
if (scale >= sw32_d_scalemip[0])
|
||||
lmiplevel = 0;
|
||||
else if (scale >= sw32_d_scalemip[1])
|
||||
lmiplevel = 1;
|
||||
else if (scale >= sw32_d_scalemip[2])
|
||||
lmiplevel = 2;
|
||||
else
|
||||
lmiplevel = 3;
|
||||
|
||||
if (lmiplevel < sw32_d_minmip)
|
||||
lmiplevel = sw32_d_minmip;
|
||||
|
||||
return lmiplevel;
|
||||
}
|
||||
|
||||
// FIXME: clean this up
|
||||
|
||||
static void
|
||||
D_DrawSolidSurface (surf_t *surf, int color)
|
||||
{
|
||||
espan_t *span;
|
||||
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
byte *pdest, pix;
|
||||
int u, u2;
|
||||
|
||||
pix = color;
|
||||
for (span = surf->spans; span; span = span->pnext)
|
||||
{
|
||||
pdest = (byte *) sw32_d_viewbuffer + sw32_screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
for (;u <= u2; u++)
|
||||
pdest[u] = pix;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
short *pdest, pix;
|
||||
int u, u2;
|
||||
|
||||
pix = sw32_8to16table[color];
|
||||
for (span = surf->spans; span; span = span->pnext)
|
||||
{
|
||||
pdest = (short *) sw32_d_viewbuffer + sw32_screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
for (;u <= u2; u++)
|
||||
pdest[u] = pix;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int *pdest, pix;
|
||||
int u, u2;
|
||||
|
||||
pix = d_8to24table[color];
|
||||
for (span = surf->spans; span; span = span->pnext)
|
||||
{
|
||||
pdest = (int *) sw32_d_viewbuffer + sw32_screenwidth * span->v;
|
||||
u = span->u;
|
||||
u2 = span->u + span->count - 1;
|
||||
for (;u <= u2; u++)
|
||||
pdest[u] = pix;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_DrawSolidSurface: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
D_CalcGradients (msurface_t *pface)
|
||||
{
|
||||
float mipscale, t;
|
||||
vec3_t p_temp1, p_saxis, p_taxis;
|
||||
|
||||
mipscale = 1.0 / (float) (1 << miplevel);
|
||||
|
||||
sw32_TransformVector (pface->texinfo->vecs[0], p_saxis);
|
||||
sw32_TransformVector (pface->texinfo->vecs[1], p_taxis);
|
||||
|
||||
t = sw32_xscaleinv * mipscale;
|
||||
sw32_d_sdivzstepu = p_saxis[0] * t;
|
||||
sw32_d_tdivzstepu = p_taxis[0] * t;
|
||||
|
||||
t = sw32_yscaleinv * mipscale;
|
||||
sw32_d_sdivzstepv = -p_saxis[1] * t;
|
||||
sw32_d_tdivzstepv = -p_taxis[1] * t;
|
||||
|
||||
sw32_d_sdivzorigin = p_saxis[2] * mipscale -
|
||||
sw32_xcenter * sw32_d_sdivzstepu -
|
||||
sw32_ycenter * sw32_d_sdivzstepv;
|
||||
sw32_d_tdivzorigin = p_taxis[2] * mipscale -
|
||||
sw32_xcenter * sw32_d_tdivzstepu -
|
||||
sw32_ycenter * sw32_d_tdivzstepv;
|
||||
|
||||
VectorScale (transformed_modelorg, mipscale, p_temp1);
|
||||
|
||||
t = 0x10000 * mipscale;
|
||||
sw32_sadjust = ((fixed16_t) (DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
((pface->texturemins[0] << 16) >> miplevel)
|
||||
+ pface->texinfo->vecs[0][3] * t;
|
||||
sw32_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
|
||||
sw32_bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
|
||||
sw32_bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_D_DrawSurfaces (void)
|
||||
{
|
||||
surf_t *s;
|
||||
msurface_t *pface;
|
||||
surfcache_t *pcurrentcache;
|
||||
vec3_t world_transformed_modelorg;
|
||||
vec3_t local_modelorg;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
sw32_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 = &sw32_surfaces[1]; s < sw32_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, ((intptr_t) s->data & 0xFF));
|
||||
sw32_D_DrawZSpans (s->spans);
|
||||
}
|
||||
} else {
|
||||
for (s = &sw32_surfaces[1]; s < sw32_surface_p; s++) {
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
sw32_r_drawnpolycount++;
|
||||
|
||||
d_zistepu = s->d_zistepu;
|
||||
d_zistepv = s->d_zistepv;
|
||||
d_ziorigin = s->d_ziorigin;
|
||||
|
||||
if (s->flags & SURF_DRAWSKY) {
|
||||
if (!sw32_r_skymade) {
|
||||
sw32_R_MakeSky ();
|
||||
}
|
||||
|
||||
sw32_D_DrawSkyScans (s->spans);
|
||||
sw32_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);
|
||||
sw32_D_DrawZSpans (s->spans);
|
||||
} else if (s->flags & SURF_DRAWTURB) {
|
||||
pface = s->data;
|
||||
miplevel = 0;
|
||||
sw32_cacheblock = ((byte *) pface->texinfo->texture +
|
||||
pface->texinfo->texture->offsets[0]);
|
||||
sw32_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 sw32_R_RotateBmodel ()
|
||||
VectorSubtract (r_origin,
|
||||
Transform_GetWorldPosition (currententity->transform),
|
||||
local_modelorg);
|
||||
sw32_TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
sw32_R_RotateBmodel (); // FIXME: don't mess with the
|
||||
// frustum, make entity passed in
|
||||
}
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
sw32_Turbulent (s->spans);
|
||||
sw32_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);
|
||||
sw32_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 sw32_R_RotateBmodel ()
|
||||
VectorSubtract (r_origin,
|
||||
Transform_GetWorldPosition (currententity->transform),
|
||||
local_modelorg);
|
||||
sw32_TransformVector (local_modelorg, transformed_modelorg);
|
||||
|
||||
sw32_R_RotateBmodel (); // FIXME: don't mess with the
|
||||
// frustum, make entity passed in
|
||||
}
|
||||
|
||||
pface = s->data;
|
||||
miplevel = sw32_D_MipLevelForScale (s->nearzi * sw32_scale_for_mip
|
||||
* pface->texinfo->mipadjust);
|
||||
|
||||
// FIXME: make this passed in to D_CacheSurface
|
||||
pcurrentcache = sw32_D_CacheSurface (pface, miplevel);
|
||||
|
||||
sw32_cacheblock = (byte *) pcurrentcache->data;
|
||||
sw32_cachewidth = pcurrentcache->width;
|
||||
|
||||
D_CalcGradients (pface);
|
||||
|
||||
sw32_D_DrawSpans (s->spans);
|
||||
|
||||
sw32_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);
|
||||
sw32_R_TransformFrustum ();
|
||||
currententity = &r_worldentity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,164 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_iface.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
void
|
||||
sw32_D_FillRect (vrect_t *rect, int color)
|
||||
{
|
||||
switch (sw32_ctx->pixbytes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
byte *dest, pix;
|
||||
|
||||
pix = color;
|
||||
|
||||
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 ((unsigned) (rx + rwidth) > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if ((unsigned) (ry + rheight) > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = (byte *) vid.buffer + ry * vid.rowbytes + rx;
|
||||
|
||||
for (ry = 0; ry < rheight; ry++)
|
||||
{
|
||||
for (rx = 0; rx < rwidth; rx++)
|
||||
dest[rx] = pix;
|
||||
dest += vid.rowbytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
unsigned short *dest, pix;
|
||||
|
||||
pix = sw32_8to16table[color];
|
||||
|
||||
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 ((unsigned) (rx + rwidth) > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if ((unsigned) (ry + rheight) > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = (unsigned short *) vid.buffer + ry * (vid.rowbytes >> 1) +
|
||||
rx;
|
||||
|
||||
for (ry = 0; ry < rheight; ry++)
|
||||
{
|
||||
for (rx = 0; rx < rwidth; rx++)
|
||||
dest[rx] = pix;
|
||||
dest += (vid.rowbytes >> 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int rx, ry, rwidth, rheight;
|
||||
unsigned int *dest, pix;
|
||||
|
||||
pix = d_8to24table[color];
|
||||
|
||||
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 ((unsigned) (rx + rwidth) > vid.width)
|
||||
rwidth = vid.width - rx;
|
||||
if ((unsigned) (ry + rheight) > vid.height)
|
||||
rheight = vid.height - rx;
|
||||
|
||||
if (rwidth < 1 || rheight < 1)
|
||||
return;
|
||||
|
||||
dest = (unsigned int *) vid.buffer + ry * (vid.rowbytes >> 2) + rx;
|
||||
|
||||
for (ry = 0; ry < rheight; ry++)
|
||||
{
|
||||
for (rx = 0; rx < rwidth; rx++)
|
||||
dest[rx] = pix;
|
||||
dest += (vid.rowbytes >> 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_FillRect: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
|
@ -1,112 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define NUM_MIPS 4
|
||||
|
||||
surfcache_t *sw32_d_initial_rover;
|
||||
qboolean sw32_d_roverwrapped;
|
||||
int sw32_d_minmip;
|
||||
float sw32_d_scalemip[NUM_MIPS - 1];
|
||||
|
||||
static float basemip[NUM_MIPS - 1] = { 1.0, 0.5 * 0.8, 0.25 * 0.8 };
|
||||
|
||||
|
||||
float sw32_d_zitable[65536];
|
||||
|
||||
|
||||
void
|
||||
sw32_D_Init (void)
|
||||
{
|
||||
sw32_r_drawpolys = false;
|
||||
sw32_r_worldpolysbacktofront = false;
|
||||
|
||||
// LordHavoc: compute 1/zi table for use in rendering code everywhere
|
||||
if (!sw32_d_zitable[1]) {
|
||||
int i;
|
||||
sw32_d_zitable[0] = 0;
|
||||
for (i = 1;i < 65536;i++)
|
||||
sw32_d_zitable[i] = (65536.0 * 65536.0 / (double) i);
|
||||
}
|
||||
|
||||
vr_data.vid->vid_internal->surf_cache_size = sw32_D_SurfaceCacheForRes;
|
||||
vr_data.vid->vid_internal->flush_caches = sw32_D_FlushCaches;
|
||||
vr_data.vid->vid_internal->init_caches = sw32_D_InitCaches;
|
||||
|
||||
VID_InitBuffers ();
|
||||
VID_MakeColormaps();
|
||||
}
|
||||
|
||||
void
|
||||
sw32_D_TurnZOn (void)
|
||||
{
|
||||
// not needed for software version
|
||||
}
|
||||
|
||||
void
|
||||
sw32_D_SetupFrame (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sw32_r_dowarp)
|
||||
sw32_d_viewbuffer = sw32_r_warpbuffer;
|
||||
else
|
||||
sw32_d_viewbuffer = vid.buffer;
|
||||
|
||||
if (sw32_r_dowarp)
|
||||
sw32_screenwidth = WARP_WIDTH;
|
||||
else
|
||||
sw32_screenwidth = vid.rowbytes / sw32_ctx->pixbytes;
|
||||
|
||||
sw32_d_roverwrapped = false;
|
||||
sw32_d_initial_rover = sw32_sc_rover;
|
||||
|
||||
sw32_d_minmip = bound (0, d_mipcap->value, 3);
|
||||
|
||||
for (i = 0; i < (NUM_MIPS - 1); i++)
|
||||
sw32_d_scalemip[i] = basemip[i] * d_mipscale->value;
|
||||
}
|
||||
|
||||
void
|
||||
sw32_D_UpdateRects (vrect_t *prect)
|
||||
{
|
||||
// the software driver draws these directly to the vid buffer
|
||||
}
|
|
@ -1,100 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
int sw32_d_vrectx, sw32_d_vrecty, sw32_d_vrectright_particle, sw32_d_vrectbottom_particle;
|
||||
|
||||
int sw32_d_y_aspect_shift, sw32_d_pix_min, sw32_d_pix_max, sw32_d_pix_shift;
|
||||
|
||||
int sw32_d_scantable[MAXHEIGHT];
|
||||
short *sw32_zspantable[MAXHEIGHT];
|
||||
|
||||
|
||||
static void
|
||||
D_Patch (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
sw32_D_ViewChanged (void)
|
||||
{
|
||||
int rowpixels;
|
||||
|
||||
if (sw32_r_dowarp)
|
||||
rowpixels = WARP_WIDTH;
|
||||
else
|
||||
rowpixels = vid.rowbytes / sw32_ctx->pixbytes;
|
||||
|
||||
sw32_scale_for_mip = sw32_xscale;
|
||||
if (sw32_yscale > sw32_xscale)
|
||||
sw32_scale_for_mip = sw32_yscale;
|
||||
|
||||
sw32_d_zrowbytes = vid.width * 2;
|
||||
sw32_d_zwidth = vid.width;
|
||||
|
||||
sw32_d_pix_min = r_refdef.vrect.width / 320;
|
||||
if (sw32_d_pix_min < 1)
|
||||
sw32_d_pix_min = 1;
|
||||
|
||||
sw32_d_pix_max = (int) ((float) r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
|
||||
sw32_d_pix_shift = 8 - (int) ((float) r_refdef.vrect.width / 320.0 + 0.5);
|
||||
if (sw32_d_pix_max < 1)
|
||||
sw32_d_pix_max = 1;
|
||||
|
||||
if (sw32_pixelAspect > 1.4)
|
||||
sw32_d_y_aspect_shift = 1;
|
||||
else
|
||||
sw32_d_y_aspect_shift = 0;
|
||||
|
||||
sw32_d_vrectx = r_refdef.vrect.x;
|
||||
sw32_d_vrecty = r_refdef.vrect.y;
|
||||
sw32_d_vrectright_particle = r_refdef.vrectright - sw32_d_pix_max;
|
||||
sw32_d_vrectbottom_particle =
|
||||
r_refdef.vrectbottom - (sw32_d_pix_max << sw32_d_y_aspect_shift);
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < vid.height; i++) {
|
||||
sw32_d_scantable[i] = i * rowpixels;
|
||||
sw32_zspantable[i] = sw32_d_pzbuffer + i * sw32_d_zwidth;
|
||||
}
|
||||
}
|
||||
|
||||
D_Patch ();
|
||||
}
|
|
@ -1,374 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
void
|
||||
sw32_D_DrawParticle (particle_t *pparticle)
|
||||
{
|
||||
vec3_t local, transformed;
|
||||
float zi;
|
||||
short *pz;
|
||||
int i, izi, pix, count, u, v;
|
||||
|
||||
// transform point
|
||||
VectorSubtract (pparticle->pos, 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 sw32_xcenter and sw32_ycenter
|
||||
zi = 1.0 / transformed[2];
|
||||
u = (int) (sw32_xcenter + zi * transformed[0] + 0.5);
|
||||
v = (int) (sw32_ycenter - zi * transformed[1] + 0.5);
|
||||
|
||||
if ((v > sw32_d_vrectbottom_particle)
|
||||
|| (u > sw32_d_vrectright_particle)
|
||||
|| (v < sw32_d_vrecty) || (u < sw32_d_vrectx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pz = sw32_d_pzbuffer + (sw32_d_zwidth * v) + u;
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
pix = izi >> sw32_d_pix_shift;
|
||||
|
||||
if (pix < sw32_d_pix_min)
|
||||
pix = sw32_d_pix_min;
|
||||
else if (pix > sw32_d_pix_max)
|
||||
pix = sw32_d_pix_max;
|
||||
|
||||
switch(sw32_ctx->pixbytes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
byte *pdest = (byte *) sw32_d_viewbuffer + sw32_d_scantable[v] + u,
|
||||
pixcolor = pparticle->icolor;
|
||||
switch (pix) {
|
||||
case 1:
|
||||
count = 1 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
count = 2 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
count = 3 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
count = 4 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
count = pix << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
for (i = 0; i < pix; i++) {
|
||||
if (pz[i] <= izi) {
|
||||
pz[i] = izi;
|
||||
pdest[i] = pixcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
unsigned short *pdest = (unsigned short *) sw32_d_viewbuffer +
|
||||
sw32_d_scantable[v] + u,
|
||||
pixcolor = sw32_8to16table[(int) pparticle->icolor];
|
||||
switch (pix) {
|
||||
case 1:
|
||||
count = 1 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
count = 2 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
count = 3 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
count = 4 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
count = pix << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
for (i = 0; i < pix; i++) {
|
||||
if (pz[i] <= izi) {
|
||||
pz[i] = izi;
|
||||
pdest[i] = pixcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int *pdest = (int *) sw32_d_viewbuffer + sw32_d_scantable[v] + u,
|
||||
pixcolor = d_8to24table[(int) pparticle->icolor];
|
||||
switch (pix) {
|
||||
case 1:
|
||||
count = 1 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
count = 2 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
count = 3 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
count = 4 << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
if (pz[0] <= izi) {
|
||||
pz[0] = izi;
|
||||
pdest[0] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[1] <= izi) {
|
||||
pz[1] = izi;
|
||||
pdest[1] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[2] <= izi) {
|
||||
pz[2] = izi;
|
||||
pdest[2] = pixcolor;
|
||||
}
|
||||
|
||||
if (pz[3] <= izi) {
|
||||
pz[3] = izi;
|
||||
pdest[3] = pixcolor;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
count = pix << sw32_d_y_aspect_shift;
|
||||
|
||||
for (; count; count--, pz += sw32_d_zwidth,
|
||||
pdest += sw32_screenwidth) {
|
||||
for (i = 0; i < pix; i++) {
|
||||
if (pz[i] <= izi) {
|
||||
pz[i] = izi;
|
||||
pdest[i] = pixcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_DrawParticles: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
|
@ -1,797 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static int ubasestep, errorterm, erroradjustup, erroradjustdown;
|
||||
|
||||
// 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 for spanpackage marking end
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
typedef struct {
|
||||
int 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;
|
||||
|
||||
static int r_p0[6], r_p1[6], r_p2[6];
|
||||
|
||||
static int d_xdenom;
|
||||
|
||||
static edgetable *pedgetable;
|
||||
|
||||
static 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},
|
||||
};
|
||||
|
||||
static int r_sstepx, r_tstepx, r_lstepx, r_lstepy, r_sstepy, r_tstepy;
|
||||
static int r_zistepx, r_zistepy;
|
||||
static int d_aspancount, d_countextrastep;
|
||||
|
||||
static spanpackage_t *a_spans;
|
||||
static spanpackage_t *d_pedgespanpackage;
|
||||
static int ystart;
|
||||
static int d_pdest;
|
||||
static byte *d_ptex;
|
||||
static short *d_pz;
|
||||
static int d_sfrac, d_tfrac, d_light, d_zi;
|
||||
static int d_ptexextrastep, d_sfracextrastep;
|
||||
static int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
|
||||
static int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
|
||||
static int d_sfracbasestep, d_tfracbasestep;
|
||||
static int d_ziextrastep, d_zibasestep;
|
||||
static int d_pzextrastep, d_pzbasestep;
|
||||
|
||||
typedef struct {
|
||||
int quotient;
|
||||
int remainder;
|
||||
} adivtab_t;
|
||||
|
||||
static adivtab_t adivtab[32 * 32] = {
|
||||
#include "adivtab.h"
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
sw32_D_PolysetSetEdgeTable (void)
|
||||
{
|
||||
int edgetableindex;
|
||||
|
||||
// assume the vertices are already in top to bottom order
|
||||
edgetableindex = 0;
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
static void
|
||||
D_DrawNonSubdiv (void)
|
||||
{
|
||||
mtriangle_t *ptri;
|
||||
finalvert_t *pfv, *index0, *index1, *index2;
|
||||
int i;
|
||||
int lnumtriangles;
|
||||
|
||||
pfv = sw32_r_affinetridesc.pfinalverts;
|
||||
ptri = sw32_r_affinetridesc.ptriangles;
|
||||
lnumtriangles = sw32_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] += sw32_r_affinetridesc.seamfixupX16;
|
||||
if (index1->flags & ALIAS_ONSEAM)
|
||||
r_p1[2] += sw32_r_affinetridesc.seamfixupX16;
|
||||
if (index2->flags & ALIAS_ONSEAM)
|
||||
r_p2[2] += sw32_r_affinetridesc.seamfixupX16;
|
||||
}
|
||||
|
||||
sw32_D_PolysetSetEdgeTable ();
|
||||
sw32_D_RasterizeAliasPolySmooth ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_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 *)
|
||||
(((intptr_t) &spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
|
||||
D_DrawNonSubdiv ();
|
||||
}
|
||||
|
||||
void
|
||||
sw32_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 += sw32_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 += sw32_r_affinetridesc.skinwidth;
|
||||
d_tfrac &= 0xFFFF;
|
||||
}
|
||||
d_light += d_lightbasestep;
|
||||
d_zi += d_zibasestep;
|
||||
}
|
||||
} while (--height);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_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);
|
||||
|
||||
// a_sstepxfrac = r_sstepx & 0xFFFF;
|
||||
// a_tstepxfrac = r_tstepx & 0xFFFF;
|
||||
|
||||
// a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
D_PolysetDrawSpans (spanpackage_t * pspanpackage)
|
||||
{
|
||||
int i, j, texscantable[2*MAX_LBM_HEIGHT], *texscan;
|
||||
// LordHavoc: compute skin row table
|
||||
for (i = 0, j = -sw32_r_affinetridesc.skinheight * sw32_r_affinetridesc.skinwidth;
|
||||
i < sw32_r_affinetridesc.skinheight*2;i++, j += sw32_r_affinetridesc.skinwidth)
|
||||
texscantable[i] = j;
|
||||
texscan = texscantable + sw32_r_affinetridesc.skinheight;
|
||||
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
int lcount, count = 0;
|
||||
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 = (byte *) sw32_d_viewbuffer + pspanpackage->pdest;
|
||||
lptex = pspanpackage->ptex;
|
||||
lpz = pspanpackage->pz;
|
||||
lsfrac = pspanpackage->sfrac;
|
||||
ltfrac = pspanpackage->tfrac;
|
||||
llight = pspanpackage->light;
|
||||
lzi = pspanpackage->zi;
|
||||
|
||||
// LordHavoc: optimized zbuffer check (switchs between
|
||||
// loops when state changes, and quickly skips groups
|
||||
// of hidden pixels)
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) < *lpz) // hidden
|
||||
{
|
||||
count = 0;
|
||||
goto skiploop8;
|
||||
}
|
||||
drawloop8:
|
||||
*lpz++ = lzi >> 16;
|
||||
*lpdest++ = ((byte *)sw32_acolormap)
|
||||
[(llight & 0xFF00) | lptex[texscan[ltfrac >> 16] +
|
||||
(lsfrac >> 16)]];
|
||||
lzi += r_zistepx;
|
||||
lsfrac += r_sstepx;
|
||||
ltfrac += r_tstepx;
|
||||
llight += r_lstepx;
|
||||
}
|
||||
while (--lcount);
|
||||
goto done8;
|
||||
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) >= *lpz) // draw
|
||||
{
|
||||
lsfrac += r_sstepx * count;
|
||||
ltfrac += r_tstepx * count;
|
||||
llight += r_lstepx * count;
|
||||
lpdest += count;
|
||||
goto drawloop8;
|
||||
}
|
||||
skiploop8:
|
||||
count++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
}
|
||||
while (--lcount);
|
||||
done8: ;
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
while (pspanpackage->count != -999999);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
int lcount, count = 0;
|
||||
short *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 = (short *) sw32_d_viewbuffer + 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) // hidden
|
||||
{
|
||||
count = 0;
|
||||
goto skiploop16;
|
||||
}
|
||||
drawloop16:
|
||||
*lpz++ = lzi >> 16;
|
||||
*lpdest++ = ((short *)sw32_acolormap)[(llight & 0xFF00) | lptex[texscan[ltfrac >> 16] + (lsfrac >> 16)]];
|
||||
lzi += r_zistepx;
|
||||
lsfrac += r_sstepx;
|
||||
ltfrac += r_tstepx;
|
||||
llight += r_lstepx;
|
||||
}
|
||||
while (--lcount);
|
||||
goto done16;
|
||||
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) >= *lpz) // draw
|
||||
{
|
||||
lsfrac += r_sstepx * count;
|
||||
ltfrac += r_tstepx * count;
|
||||
llight += r_lstepx * count;
|
||||
lpdest += count;
|
||||
goto drawloop16;
|
||||
}
|
||||
skiploop16:
|
||||
count++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
}
|
||||
while (--lcount);
|
||||
done16: ;
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
while (pspanpackage->count != -999999);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
int lcount, count = 0;
|
||||
int *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 = (int *) sw32_d_viewbuffer + 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) // hidden
|
||||
{
|
||||
count = 0;
|
||||
goto skiploop32;
|
||||
}
|
||||
drawloop32:
|
||||
*lpz++ = lzi >> 16;
|
||||
*lpdest++ =
|
||||
vid.colormap32[(llight & 0xFF00) |
|
||||
lptex[texscan[ltfrac >> 16] +
|
||||
(lsfrac >> 16)]];
|
||||
lzi += r_zistepx;
|
||||
lsfrac += r_sstepx;
|
||||
ltfrac += r_tstepx;
|
||||
llight += r_lstepx;
|
||||
}
|
||||
while (--lcount);
|
||||
goto done32;
|
||||
|
||||
do
|
||||
{
|
||||
if ((lzi >> 16) >= *lpz) // draw
|
||||
{
|
||||
lsfrac += r_sstepx * count;
|
||||
ltfrac += r_tstepx * count;
|
||||
llight += r_lstepx * count;
|
||||
lpdest += count;
|
||||
goto drawloop32;
|
||||
}
|
||||
skiploop32:
|
||||
count++;
|
||||
lzi += r_zistepx;
|
||||
lpz++;
|
||||
}
|
||||
while (--lcount);
|
||||
done32: ;
|
||||
}
|
||||
|
||||
pspanpackage++;
|
||||
}
|
||||
while (pspanpackage->count != -999999);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sys_Error("D_PolysetDrawSpans: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_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
|
||||
sw32_D_PolysetCalcGradients (sw32_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 *) sw32_r_affinetridesc.pskin + (plefttop[2] >> 16) +
|
||||
(plefttop[3] >> 16) * sw32_r_affinetridesc.skinwidth;
|
||||
d_sfrac = plefttop[2] & 0xFFFF;
|
||||
d_tfrac = plefttop[3] & 0xFFFF;
|
||||
d_pzbasestep = sw32_d_zwidth + ubasestep;
|
||||
d_pzextrastep = d_pzbasestep + 1;
|
||||
d_light = plefttop[4];
|
||||
d_zi = plefttop[5];
|
||||
|
||||
d_pdestbasestep = sw32_screenwidth + ubasestep;
|
||||
d_pdestextrastep = d_pdestbasestep + 1;
|
||||
// LordHavoc: d_pdest has been changed to pixel offset
|
||||
d_pdest = ystart * sw32_screenwidth + plefttop[0];
|
||||
d_pz = sw32_d_pzbuffer + ystart * sw32_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) * sw32_r_affinetridesc.skinwidth;
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
|
||||
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) *
|
||||
sw32_r_affinetridesc.skinwidth;
|
||||
d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
|
||||
d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
|
||||
d_lightextrastep = d_lightbasestep + working_lstepx;
|
||||
d_ziextrastep = d_zibasestep + r_zistepx;
|
||||
|
||||
sw32_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 *) sw32_r_affinetridesc.pskin + (plefttop[2] >> 16) +
|
||||
(plefttop[3] >> 16) * sw32_r_affinetridesc.skinwidth;
|
||||
d_sfrac = 0;
|
||||
d_tfrac = 0;
|
||||
d_light = plefttop[4];
|
||||
d_zi = plefttop[5];
|
||||
|
||||
d_pdestbasestep = sw32_screenwidth + ubasestep;
|
||||
d_pdestextrastep = d_pdestbasestep + 1;
|
||||
// LordHavoc: d_pdest and relatives have been changed to pixel
|
||||
// offsets into framebuffer
|
||||
d_pdest = ystart * sw32_screenwidth + plefttop[0];
|
||||
d_pzbasestep = sw32_d_zwidth + ubasestep;
|
||||
d_pzextrastep = d_pzbasestep + 1;
|
||||
d_pz = sw32_d_pzbuffer + ystart * sw32_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) *
|
||||
sw32_r_affinetridesc.skinwidth;
|
||||
d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
|
||||
d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
|
||||
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) *
|
||||
sw32_r_affinetridesc.skinwidth;
|
||||
d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
|
||||
d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
|
||||
d_lightextrastep = d_lightbasestep + working_lstepx;
|
||||
d_ziextrastep = d_zibasestep + r_zistepx;
|
||||
|
||||
sw32_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_PolysetDrawSpans (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_PolysetDrawSpans (pstart);
|
||||
}
|
||||
}
|
|
@ -1,883 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/qendian.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static byte *r_turb_pbase;
|
||||
static void *r_turb_pdest;
|
||||
static fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
|
||||
static int *r_turb_turb;
|
||||
static int r_turb_spancount;
|
||||
|
||||
/*
|
||||
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
|
||||
sw32_D_WarpScreen (void)
|
||||
{
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
int scr_x = vr_data.scr_view->xpos;
|
||||
int scr_y = vr_data.scr_view->ylen;
|
||||
int scr_w = vr_data.scr_view->xpos;
|
||||
int scr_h = vr_data.scr_view->ylen;
|
||||
byte *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
byte **row;
|
||||
byte *rowptr[MAXHEIGHT];
|
||||
int column[MAXWIDTH];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_w;
|
||||
hratio = h / (float) scr_h;
|
||||
|
||||
for (v = 0; v < scr_h + AMP2 * 2; v++) {
|
||||
rowptr[v] = (byte *) sw32_d_viewbuffer + (r_refdef.vrect.y *
|
||||
sw32_screenwidth) +
|
||||
(sw32_screenwidth * (int) ((float) v * hratio * h /
|
||||
(h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_w + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = sw32_intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
dest = (byte *)vid.buffer + scr_y * vid.rowbytes + scr_x;
|
||||
|
||||
for (v = 0; v < scr_h; v++, dest += vid.rowbytes) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_w; 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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
int scr_x = vr_data.scr_view->xpos;
|
||||
int scr_y = vr_data.scr_view->ylen;
|
||||
int scr_w = vr_data.scr_view->xpos;
|
||||
int scr_h = vr_data.scr_view->ylen;
|
||||
short *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
short **row;
|
||||
short *rowptr[MAXHEIGHT];
|
||||
int column[MAXWIDTH];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_w;
|
||||
hratio = h / (float) scr_h;
|
||||
|
||||
for (v = 0; v < scr_h + AMP2 * 2; v++) {
|
||||
rowptr[v] = (short *) sw32_d_viewbuffer +
|
||||
(r_refdef.vrect.y * sw32_screenwidth) +
|
||||
(sw32_screenwidth * (int) ((float) v * hratio * h /
|
||||
(h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_w + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = sw32_intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
dest = (short *) vid.buffer + scr_y * (vid.rowbytes >> 1) + scr_x;
|
||||
|
||||
for (v = 0; v < scr_h; v++, dest += (vid.rowbytes >> 1)) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_w; 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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int w, h;
|
||||
int u, v;
|
||||
int scr_x = vr_data.scr_view->xpos;
|
||||
int scr_y = vr_data.scr_view->ylen;
|
||||
int scr_w = vr_data.scr_view->xpos;
|
||||
int scr_h = vr_data.scr_view->ylen;
|
||||
int *dest;
|
||||
int *turb;
|
||||
int *col;
|
||||
int **row;
|
||||
int *rowptr[MAXHEIGHT];
|
||||
int column[MAXWIDTH];
|
||||
float wratio, hratio;
|
||||
|
||||
w = r_refdef.vrect.width;
|
||||
h = r_refdef.vrect.height;
|
||||
|
||||
wratio = w / (float) scr_w;
|
||||
hratio = h / (float) scr_h;
|
||||
|
||||
for (v = 0; v < scr_h + AMP2 * 2; v++) {
|
||||
rowptr[v] = (int *) sw32_d_viewbuffer +
|
||||
(r_refdef.vrect.y * sw32_screenwidth) +
|
||||
(sw32_screenwidth * (int) ((float) v * hratio * h /
|
||||
(h + AMP2 * 2)));
|
||||
}
|
||||
|
||||
for (u = 0; u < scr_w + AMP2 * 2; u++) {
|
||||
column[u] = r_refdef.vrect.x +
|
||||
(int) ((float) u * wratio * w / (w + AMP2 * 2));
|
||||
}
|
||||
|
||||
turb = sw32_intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
dest = (int *) vid.buffer + scr_y * (vid.rowbytes >> 2) + scr_x;
|
||||
|
||||
for (v = 0; v < scr_h; v++, dest += (vid.rowbytes >> 2)) {
|
||||
col = &column[turb[v]];
|
||||
row = &rowptr[v];
|
||||
for (u = 0; u < scr_w; 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]];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_WarpScreen: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
D_DrawTurbulentSpan (void)
|
||||
{
|
||||
int sturb, tturb;
|
||||
|
||||
switch (sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
byte *pdest = (byte *) r_turb_pdest;
|
||||
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;
|
||||
*pdest++ = r_turb_pbase[(tturb << 6) + sturb];
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
r_turb_pdest = (byte *)pdest;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
short *pdest = (short *) r_turb_pdest;
|
||||
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;
|
||||
*pdest++ = sw32_8to16table[r_turb_pbase[(tturb << 6) + sturb]];
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
r_turb_pdest = (byte *)pdest;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int *pdest = (int *) r_turb_pdest;
|
||||
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;
|
||||
*pdest++ = d_8to24table[r_turb_pbase[(tturb << 6) + sturb]];
|
||||
r_turb_s += r_turb_sstep;
|
||||
r_turb_t += r_turb_tstep;
|
||||
} while (--r_turb_spancount > 0);
|
||||
r_turb_pdest = (byte *)pdest;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_DrawTurbulentSpan: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_Turbulent (espan_t *pspan)
|
||||
{
|
||||
int count;
|
||||
fixed16_t snext, tnext;
|
||||
float sdivz, tdivz, zi, z, du, dv, spancountminus1;
|
||||
float sdivz16stepu, tdivz16stepu, zi16stepu;
|
||||
|
||||
r_turb_turb = sw32_sintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
|
||||
|
||||
r_turb_sstep = 0; // keep compiler happy
|
||||
r_turb_tstep = 0; // ditto
|
||||
|
||||
r_turb_pbase = (byte *) sw32_cacheblock;
|
||||
|
||||
sdivz16stepu = sw32_d_sdivzstepu * 16;
|
||||
tdivz16stepu = sw32_d_tdivzstepu * 16;
|
||||
zi16stepu = d_zistepu * 16 * 65536;
|
||||
|
||||
do {
|
||||
r_turb_pdest = (byte *) sw32_d_viewbuffer + ((sw32_screenwidth * pspan->v) +
|
||||
pspan->u) * sw32_ctx->pixbytes;
|
||||
|
||||
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 = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
r_turb_s = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (r_turb_s > sw32_bbextents)
|
||||
r_turb_s = sw32_bbextents;
|
||||
else if (r_turb_s < 0)
|
||||
r_turb_s = 0;
|
||||
|
||||
r_turb_t = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (r_turb_t > sw32_bbextentt)
|
||||
r_turb_t = sw32_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 = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_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) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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 += sw32_d_sdivzstepu * spancountminus1;
|
||||
tdivz += sw32_d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * 65536.0f * spancountminus1;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_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) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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_DrawTurbulentSpan ();
|
||||
|
||||
r_turb_s = snext;
|
||||
r_turb_t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_D_DrawSpans (espan_t *pspan)
|
||||
{
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
byte *pbase = (byte *) sw32_cacheblock, *pdest;
|
||||
int count;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
do {
|
||||
pdest = (byte *) sw32_d_viewbuffer + (sw32_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 = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
s = bound(0, s, sw32_bbextents);
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
t = bound(0, t, sw32_bbextentt);
|
||||
|
||||
while(count >= 8) {
|
||||
count -= 8;
|
||||
// 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 = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(8, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(8, tnext, sw32_bbextentt);
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[4] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[5] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[6] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[7] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s = snext;
|
||||
t = tnext;
|
||||
pdest += 8;
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
// 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
|
||||
//countminus1 = (float) (count - 1);
|
||||
sdivz += sw32_d_sdivzstepu * count; //minus1;
|
||||
tdivz += sw32_d_tdivzstepu * count; //minus1;
|
||||
zi += d_zistepu * 65536.0f * count; //minus1;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(count, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(count, tnext, sw32_bbextentt);
|
||||
|
||||
if (count > 1) {
|
||||
sstep = (snext - s) / count; //(count - 1);
|
||||
tstep = (tnext - t) / count; //(count - 1);
|
||||
|
||||
if (count & 4)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 4;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 2;
|
||||
}
|
||||
if (count & 1)
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
}
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
short *pbase = (short *) sw32_cacheblock, *pdest;
|
||||
int count;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
do {
|
||||
pdest = (short *) sw32_d_viewbuffer + (sw32_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 = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
s = bound(0, s, sw32_bbextents);
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
t = bound(0, t, sw32_bbextentt);
|
||||
|
||||
while(count >= 8) {
|
||||
count -= 8;
|
||||
// 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 = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(8, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(8, tnext, sw32_bbextentt);
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[4] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[5] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[6] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[7] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s = snext;t = tnext;
|
||||
pdest += 8;
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
// 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
|
||||
//countminus1 = (float) (count - 1);
|
||||
sdivz += sw32_d_sdivzstepu * count; //minus1;
|
||||
tdivz += sw32_d_tdivzstepu * count; //minus1;
|
||||
zi += d_zistepu * 65536.0f * count; //minus1;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(count, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(count, tnext, sw32_bbextentt);
|
||||
|
||||
if (count > 1) {
|
||||
sstep = (snext - s) / count; //(count - 1);
|
||||
tstep = (tnext - t) / count; //(count - 1);
|
||||
|
||||
if (count & 4)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;t += tstep;
|
||||
pdest += 4;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 2;
|
||||
}
|
||||
if (count & 1)
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
}
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int *pbase = (int *) sw32_cacheblock, *pdest;
|
||||
int count;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
float sdivz, tdivz, zi, z, du, dv;
|
||||
float sdivz8stepu, tdivz8stepu, zi8stepu;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
do {
|
||||
pdest = (int *) sw32_d_viewbuffer + (sw32_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 = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
s = bound(0, s, sw32_bbextents);
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
t = bound(0, t, sw32_bbextentt);
|
||||
|
||||
while(count >= 8) {
|
||||
count -= 8;
|
||||
// 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 = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(8, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(8, tnext, sw32_bbextentt);
|
||||
|
||||
sstep = (snext - s) >> 3;
|
||||
tstep = (tnext - t) >> 3;
|
||||
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[4] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[5] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[6] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[7] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s = snext;
|
||||
t = tnext;
|
||||
pdest += 8;
|
||||
}
|
||||
if (count)
|
||||
{
|
||||
// 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
|
||||
//countminus1 = (float) (count - 1);
|
||||
sdivz += sw32_d_sdivzstepu * count; //minus1;
|
||||
tdivz += sw32_d_tdivzstepu * count; //minus1;
|
||||
zi += d_zistepu * 65536.0f * count; //minus1;
|
||||
z = sw32_d_zitable[(unsigned short) zi];
|
||||
|
||||
// prevent round-off error on <0 steps from from causing
|
||||
// overstepping & running off the edge of the texture
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
snext = bound(count, snext, sw32_bbextents);
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
tnext = bound(count, tnext, sw32_bbextentt);
|
||||
|
||||
if (count > 1) {
|
||||
sstep = (snext - s) / count; //(count - 1);
|
||||
tstep = (tnext - t) / count; //(count - 1);
|
||||
|
||||
if (count & 4)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[2] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[3] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 4;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest[1] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
pdest += 2;
|
||||
}
|
||||
if (count & 1)
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pdest[0] = pbase[(t >> 16) * sw32_cachewidth + (s >> 16)];
|
||||
}
|
||||
}
|
||||
} while ((pspan = pspan->pnext) != NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_DrawSpans: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_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 = sw32_d_pzbuffer + (sw32_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);
|
||||
|
||||
// LordHavoc: added big endian case, the old code is not correct on
|
||||
// big-endian (results in swapped depth pairs), and is tuned more for
|
||||
// x86, PowerPC compilers can probably do a good job with raw loop
|
||||
// unrolling if it is even necessary...
|
||||
if (bigendien)
|
||||
{
|
||||
do
|
||||
{
|
||||
*pdest++ = (short) (izi >> 16);
|
||||
izi += izistep;
|
||||
}
|
||||
while(--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((intptr_t) 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);
|
||||
}
|
|
@ -1,286 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define SKY_SPAN_SHIFT 5
|
||||
#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT)
|
||||
|
||||
|
||||
static void
|
||||
D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t)
|
||||
{
|
||||
float wu, wv, temp;
|
||||
vec3_t end;
|
||||
int half_width = vid.width >> 1;
|
||||
int half_height = vid.height >> 1;
|
||||
|
||||
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 - half_width) / temp;
|
||||
wv = 8192.0 * (float) (half_height - 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 = sw32_r_skytime * sw32_r_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
|
||||
sw32_D_DrawSkyScans (espan_t *pspan)
|
||||
{
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
byte *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
snext = 0; // ditto
|
||||
tnext = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (byte *) sw32_d_viewbuffer + sw32_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++ = ((byte *) sw32_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);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
short *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
snext = 0; // ditto
|
||||
tnext = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (short *) sw32_d_viewbuffer + sw32_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++ = ((short *) sw32_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);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
int count, spancount, u, v;
|
||||
int *pdest;
|
||||
fixed16_t s, t, snext, tnext, sstep, tstep;
|
||||
int spancountminus1;
|
||||
|
||||
sstep = 0; // keep compiler happy
|
||||
tstep = 0; // ditto
|
||||
snext = 0; // ditto
|
||||
tnext = 0; // ditto
|
||||
|
||||
do {
|
||||
pdest = (int *) sw32_d_viewbuffer + sw32_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++ = ((int *) sw32_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);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sys_Error("D_DrawSkyScans: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
|
@ -1,732 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static int sprite_height;
|
||||
static int minindex, maxindex;
|
||||
static sspan_t *sprite_spans;
|
||||
|
||||
|
||||
|
||||
void
|
||||
sw32_D_SpriteDrawSpans (sspan_t *pspan)
|
||||
{
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase;
|
||||
byte *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 = (byte *) sw32_cacheblock;
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536.0f;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (byte *) sw32_d_viewbuffer + sw32_screenwidth * pspan->v + pspan->u;
|
||||
pz = sw32_d_pzbuffer + (sw32_d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan1;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
// we count on FP exceptions being turned off to avoid range
|
||||
// problems
|
||||
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (s > sw32_bbextents)
|
||||
s = sw32_bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (t > sw32_bbextentt)
|
||||
t = sw32_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 = sw32_d_zitable[(int) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from causing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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 += sw32_d_sdivzstepu * spancountminus1;
|
||||
tdivz += sw32_d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * 65536.0f * spancountminus1;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_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) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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) * sw32_cachewidth];
|
||||
if (btemp != TRANSPARENT_COLOR) {
|
||||
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);
|
||||
|
||||
NextSpan1:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase;
|
||||
short *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 = (byte *) sw32_cacheblock;
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (short *) sw32_d_viewbuffer + sw32_screenwidth * pspan->v + pspan->u;
|
||||
pz = sw32_d_pzbuffer + (sw32_d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan2;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
// we count on FP exceptions being turned off to avoid range
|
||||
// problems
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (s > sw32_bbextents)
|
||||
s = sw32_bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (t > sw32_bbextentt)
|
||||
t = sw32_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 = sw32_d_zitable[(int) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from causing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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 += sw32_d_sdivzstepu * spancountminus1;
|
||||
tdivz += sw32_d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * 65536.0f * spancountminus1;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_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) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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) * sw32_cachewidth];
|
||||
if (btemp != TRANSPARENT_COLOR) {
|
||||
if (*pz <= (izi >> 16)) {
|
||||
*pz = izi >> 16;
|
||||
*pdest = sw32_8to16table[btemp];
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan2:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
int count, spancount, izistep;
|
||||
int izi;
|
||||
byte *pbase;
|
||||
int *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 = (byte *) sw32_cacheblock;
|
||||
|
||||
sdivz8stepu = sw32_d_sdivzstepu * 8;
|
||||
tdivz8stepu = sw32_d_tdivzstepu * 8;
|
||||
zi8stepu = d_zistepu * 8 * 65536;
|
||||
|
||||
// we count on FP exceptions being turned off to avoid range problems
|
||||
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
|
||||
|
||||
do {
|
||||
pdest = (int *) sw32_d_viewbuffer + sw32_screenwidth * pspan->v + pspan->u;
|
||||
pz = sw32_d_pzbuffer + (sw32_d_zwidth * pspan->v) + pspan->u;
|
||||
|
||||
count = pspan->count;
|
||||
|
||||
if (count <= 0)
|
||||
goto NextSpan4;
|
||||
|
||||
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
|
||||
du = (float) pspan->u;
|
||||
dv = (float) pspan->v;
|
||||
|
||||
sdivz = sw32_d_sdivzorigin + dv * sw32_d_sdivzstepv + du * sw32_d_sdivzstepu;
|
||||
tdivz = sw32_d_tdivzorigin + dv * sw32_d_tdivzstepv + du * sw32_d_tdivzstepu;
|
||||
zi = (d_ziorigin + dv * d_zistepv + du * d_zistepu) * 65536.0f;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
// we count on FP exceptions being turned off to avoid range
|
||||
// problems
|
||||
izi = (int) (zi * 0x8000);
|
||||
|
||||
s = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (s > sw32_bbextents)
|
||||
s = sw32_bbextents;
|
||||
else if (s < 0)
|
||||
s = 0;
|
||||
|
||||
t = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (t > sw32_bbextentt)
|
||||
t = sw32_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 = sw32_d_zitable[(int) zi];
|
||||
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps from causing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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 += sw32_d_sdivzstepu * spancountminus1;
|
||||
tdivz += sw32_d_tdivzstepu * spancountminus1;
|
||||
zi += d_zistepu * 65536.0f * spancountminus1;
|
||||
z = sw32_d_zitable[(int) zi];
|
||||
snext = (int) (sdivz * z) + sw32_sadjust;
|
||||
if (snext > sw32_bbextents)
|
||||
snext = sw32_bbextents;
|
||||
else if (snext < 8)
|
||||
snext = 8; // prevent round-off error on <0
|
||||
// steps fromcausing overstepping
|
||||
// & running off the texture's edge
|
||||
|
||||
tnext = (int) (tdivz * z) + sw32_tadjust;
|
||||
if (tnext > sw32_bbextentt)
|
||||
tnext = sw32_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) * sw32_cachewidth];
|
||||
if (btemp != TRANSPARENT_COLOR) {
|
||||
if (*pz <= (izi >> 16)) {
|
||||
*pz = izi >> 16;
|
||||
*pdest = d_8to24table[btemp];
|
||||
}
|
||||
}
|
||||
|
||||
izi += izistep;
|
||||
pdest++;
|
||||
pz++;
|
||||
s += sstep;
|
||||
t += tstep;
|
||||
} while (--spancount > 0);
|
||||
|
||||
s = snext;
|
||||
t = tnext;
|
||||
|
||||
} while (count > 0);
|
||||
|
||||
NextSpan4:
|
||||
pspan++;
|
||||
|
||||
} while (pspan->count != DS_SPAN_LIST_END);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sys_Error("D_SpriteDrawSpans: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
|
||||
static 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 = sw32_r_spritedesc.nump;
|
||||
|
||||
lmaxindex = maxindex;
|
||||
if (lmaxindex == 0)
|
||||
lmaxindex = sw32_r_spritedesc.nump;
|
||||
|
||||
vtop = ceil (sw32_r_spritedesc.pverts[i].v);
|
||||
|
||||
do {
|
||||
pvert = &sw32_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 = sw32_r_spritedesc.nump;
|
||||
|
||||
} while (i != lmaxindex);
|
||||
}
|
||||
|
||||
static 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 = sw32_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 = &sw32_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 == sw32_r_spritedesc.nump)
|
||||
i = 0;
|
||||
|
||||
} while (i != maxindex);
|
||||
|
||||
pspan->count = DS_SPAN_LIST_END; // mark the end of the span list
|
||||
}
|
||||
|
||||
static void
|
||||
D_SpriteCalculateGradients (void)
|
||||
{
|
||||
vec3_t p_normal, p_saxis, p_taxis, p_temp1;
|
||||
float distinv;
|
||||
|
||||
sw32_TransformVector (sw32_r_spritedesc.vpn, p_normal);
|
||||
sw32_TransformVector (sw32_r_spritedesc.vright, p_saxis);
|
||||
sw32_TransformVector (sw32_r_spritedesc.vup, p_taxis);
|
||||
VectorNegate (p_taxis, p_taxis);
|
||||
|
||||
distinv = 1.0 / (-DotProduct (modelorg, sw32_r_spritedesc.vpn));
|
||||
distinv = min (distinv, 1.0);
|
||||
|
||||
sw32_d_sdivzstepu = p_saxis[0] * sw32_xscaleinv;
|
||||
sw32_d_tdivzstepu = p_taxis[0] * sw32_xscaleinv;
|
||||
|
||||
sw32_d_sdivzstepv = -p_saxis[1] * sw32_yscaleinv;
|
||||
sw32_d_tdivzstepv = -p_taxis[1] * sw32_yscaleinv;
|
||||
|
||||
d_zistepu = p_normal[0] * sw32_xscaleinv * distinv;
|
||||
d_zistepv = -p_normal[1] * sw32_yscaleinv * distinv;
|
||||
|
||||
sw32_d_sdivzorigin = p_saxis[2] - sw32_xcenter * sw32_d_sdivzstepu -
|
||||
sw32_ycenter * sw32_d_sdivzstepv;
|
||||
sw32_d_tdivzorigin = p_taxis[2] - sw32_xcenter * sw32_d_tdivzstepu -
|
||||
sw32_ycenter * sw32_d_tdivzstepv;
|
||||
d_ziorigin = p_normal[2] * distinv - sw32_xcenter * d_zistepu -
|
||||
sw32_ycenter * d_zistepv;
|
||||
|
||||
sw32_TransformVector (modelorg, p_temp1);
|
||||
|
||||
sw32_sadjust = ((fixed16_t) (DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
|
||||
(-(sw32_cachewidth >> 1) << 16);
|
||||
sw32_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
|
||||
sw32_bbextents = (sw32_cachewidth << 16) - 1;
|
||||
sw32_bbextentt = (sprite_height << 16) - 1;
|
||||
}
|
||||
|
||||
void
|
||||
sw32_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 = sw32_r_spritedesc.pverts;
|
||||
|
||||
for (i = 0; i < sw32_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
|
||||
|
||||
sw32_cachewidth = sw32_r_spritedesc.pspriteframe->width;
|
||||
sprite_height = sw32_r_spritedesc.pspriteframe->height;
|
||||
sw32_cacheblock = &sw32_r_spritedesc.pspriteframe->pixels[0];
|
||||
|
||||
// copy the first vertex to the last vertex, so we don't have to deal with
|
||||
// wrapping
|
||||
nump = sw32_r_spritedesc.nump;
|
||||
pverts = sw32_r_spritedesc.pverts;
|
||||
pverts[nump] = pverts[0];
|
||||
|
||||
D_SpriteCalculateGradients ();
|
||||
D_SpriteScanLeftEdge ();
|
||||
D_SpriteScanRightEdge ();
|
||||
sw32_D_SpriteDrawSpans (sprite_spans);
|
||||
}
|
|
@ -1,287 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static float surfscale;
|
||||
|
||||
static int sc_size;
|
||||
surfcache_t *sw32_sc_rover;
|
||||
static surfcache_t *sc_base;
|
||||
|
||||
#define GUARDSIZE 4
|
||||
|
||||
|
||||
void *
|
||||
sw32_D_SurfaceCacheAddress (void)
|
||||
{
|
||||
return sc_base;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sw32_D_SurfaceCacheForRes (void *data, 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;
|
||||
|
||||
size *= sw32_ctx->pixbytes;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static 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");
|
||||
}
|
||||
|
||||
|
||||
static 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
|
||||
sw32_D_InitCaches (void *data, void *buffer, int size)
|
||||
{
|
||||
Sys_MaskPrintf (SYS_dev, "D_InitCaches: %ik surface cache\n", size/1024);
|
||||
|
||||
sc_size = size - GUARDSIZE;
|
||||
sc_base = (surfcache_t *) buffer;
|
||||
sw32_sc_rover = sc_base;
|
||||
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
|
||||
sw32_d_pzbuffer = vid.zbuffer;
|
||||
|
||||
D_ClearCacheGuard ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_D_FlushCaches (void *data)
|
||||
{
|
||||
surfcache_t *c;
|
||||
|
||||
if (!sc_base)
|
||||
return;
|
||||
|
||||
for (c = sc_base; c; c = c->next) {
|
||||
if (c->owner)
|
||||
*c->owner = NULL;
|
||||
}
|
||||
|
||||
sw32_sc_rover = sc_base;
|
||||
sc_base->next = NULL;
|
||||
sc_base->owner = NULL;
|
||||
sc_base->size = sc_size;
|
||||
}
|
||||
|
||||
|
||||
static surfcache_t *
|
||||
D_SCAlloc (int width, int size)
|
||||
{
|
||||
surfcache_t *new;
|
||||
qboolean wrapped_this_time;
|
||||
|
||||
if ((width < 0) || (width > 512)) // FIXME shouldn't really have a max
|
||||
Sys_Error ("D_SCAlloc: bad cache width %d", width);
|
||||
|
||||
if ((size <= 0) || (size > (0x40000 * sw32_ctx->pixbytes))) //FIXME ditto
|
||||
Sys_Error ("D_SCAlloc: bad cache size %d", size);
|
||||
|
||||
/* This adds the offset of data[0] in the surfcache_t struct. */
|
||||
size += field_offset (surfcache_t, 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 (!sw32_sc_rover || (byte *) sw32_sc_rover - (byte *) sc_base > sc_size - size) {
|
||||
if (sw32_sc_rover) {
|
||||
wrapped_this_time = true;
|
||||
}
|
||||
sw32_sc_rover = sc_base;
|
||||
}
|
||||
// colect and free surfcache_t blocks until the rover block is large enough
|
||||
new = sw32_sc_rover;
|
||||
if (sw32_sc_rover->owner)
|
||||
*sw32_sc_rover->owner = NULL;
|
||||
|
||||
while (new->size < size) {
|
||||
// free another
|
||||
sw32_sc_rover = sw32_sc_rover->next;
|
||||
if (!sw32_sc_rover)
|
||||
Sys_Error ("D_SCAlloc: hit the end of memory");
|
||||
if (sw32_sc_rover->owner)
|
||||
*sw32_sc_rover->owner = NULL;
|
||||
|
||||
new->size += sw32_sc_rover->size;
|
||||
new->next = sw32_sc_rover->next;
|
||||
}
|
||||
|
||||
// create a fragment out of any leftovers
|
||||
if (new->size - size > 256) {
|
||||
sw32_sc_rover = (surfcache_t *) ((byte *) new + size);
|
||||
sw32_sc_rover->size = new->size - size;
|
||||
sw32_sc_rover->next = new->next;
|
||||
sw32_sc_rover->width = 0;
|
||||
sw32_sc_rover->owner = NULL;
|
||||
new->next = sw32_sc_rover;
|
||||
new->size = size;
|
||||
} else
|
||||
sw32_sc_rover = new->next;
|
||||
|
||||
new->width = width;
|
||||
// DEBUG
|
||||
if (width > 0)
|
||||
new->height = (size - sizeof (*new) + sizeof (new->data)) /
|
||||
(width * sw32_ctx->pixbytes);
|
||||
|
||||
new->owner = NULL; // should be set properly after return
|
||||
|
||||
if (sw32_d_roverwrapped) {
|
||||
if (wrapped_this_time || (sw32_sc_rover >= sw32_d_initial_rover))
|
||||
r_cache_thrash = true;
|
||||
} else if (wrapped_this_time) {
|
||||
sw32_d_roverwrapped = true;
|
||||
}
|
||||
|
||||
D_CheckCacheGuard (); // DEBUG
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
surfcache_t *
|
||||
sw32_D_CacheSurface (msurface_t *surface, int miplevel)
|
||||
{
|
||||
surfcache_t *cache;
|
||||
|
||||
// if the surface is animating or flashing, flush the cache
|
||||
sw32_r_drawsurf.texture = R_TextureAnimation (currententity, surface);
|
||||
sw32_r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]];
|
||||
sw32_r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]];
|
||||
sw32_r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]];
|
||||
sw32_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 == sw32_r_drawsurf.texture
|
||||
&& cache->lightadj[0] == sw32_r_drawsurf.lightadj[0]
|
||||
&& cache->lightadj[1] == sw32_r_drawsurf.lightadj[1]
|
||||
&& cache->lightadj[2] == sw32_r_drawsurf.lightadj[2]
|
||||
&& cache->lightadj[3] == sw32_r_drawsurf.lightadj[3])
|
||||
return cache;
|
||||
|
||||
// determine shape of surface
|
||||
surfscale = 1.0 / (1 << miplevel);
|
||||
sw32_r_drawsurf.surfmip = miplevel;
|
||||
sw32_r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
|
||||
sw32_r_drawsurf.rowbytes = sw32_r_drawsurf.surfwidth * sw32_ctx->pixbytes;
|
||||
sw32_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 (sw32_r_drawsurf.surfwidth,
|
||||
sw32_r_drawsurf.rowbytes * sw32_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;
|
||||
|
||||
sw32_r_drawsurf.surfdat = (byte *) cache->data;
|
||||
|
||||
cache->texture = sw32_r_drawsurf.texture;
|
||||
cache->lightadj[0] = sw32_r_drawsurf.lightadj[0];
|
||||
cache->lightadj[1] = sw32_r_drawsurf.lightadj[1];
|
||||
cache->lightadj[2] = sw32_r_drawsurf.lightadj[2];
|
||||
cache->lightadj[3] = sw32_r_drawsurf.lightadj[3];
|
||||
|
||||
// draw and light the surface texture
|
||||
sw32_r_drawsurf.surf = surface;
|
||||
|
||||
sw32_c_surf++;
|
||||
sw32_R_DrawSurface ();
|
||||
|
||||
return surface->cachespots[miplevel];
|
||||
}
|
|
@ -1,55 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/qtypes.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 sw32_d_sdivzstepu, sw32_d_tdivzstepu, sw32_d_zistepu;
|
||||
float sw32_d_sdivzstepv, sw32_d_tdivzstepv, sw32_d_zistepv;
|
||||
float sw32_d_sdivzorigin, sw32_d_tdivzorigin, sw32_d_ziorigin;
|
||||
|
||||
fixed16_t sw32_sadjust, sw32_tadjust, sw32_bbextents, sw32_bbextentt;
|
||||
|
||||
byte *sw32_cacheblock;
|
||||
int sw32_cachewidth;
|
||||
byte *sw32_d_viewbuffer;
|
||||
short *sw32_d_pzbuffer;
|
||||
int sw32_d_zrowbytes;
|
||||
int sw32_d_zwidth;
|
|
@ -1,73 +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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
void
|
||||
sw32_D_DrawZPoint (void)
|
||||
{
|
||||
short *pz;
|
||||
int izi;
|
||||
|
||||
pz = sw32_d_pzbuffer + (sw32_d_zwidth * sw32_r_zpointdesc.v) + sw32_r_zpointdesc.u;
|
||||
izi = (int) (sw32_r_zpointdesc.zi * 0x8000);
|
||||
|
||||
if (*pz <= izi) {
|
||||
*pz = izi;
|
||||
switch(sw32_ctx->pixbytes)
|
||||
{
|
||||
case 1:
|
||||
((byte *) sw32_d_viewbuffer) [sw32_d_scantable[sw32_r_zpointdesc.v] +
|
||||
sw32_r_zpointdesc.u] = sw32_r_zpointdesc.color;
|
||||
break;
|
||||
case 2:
|
||||
((short *) sw32_d_viewbuffer) [sw32_d_scantable[sw32_r_zpointdesc.v] +
|
||||
sw32_r_zpointdesc.u] =
|
||||
sw32_8to16table[sw32_r_zpointdesc.color];
|
||||
break;
|
||||
case 4:
|
||||
((int *) sw32_d_viewbuffer) [sw32_d_scantable[sw32_r_zpointdesc.v] +
|
||||
sw32_r_zpointdesc.u] =
|
||||
d_8to24table[sw32_r_zpointdesc.color];
|
||||
break;
|
||||
default:
|
||||
Sys_Error("D_DrawZPoint: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,473 +0,0 @@
|
|||
#ifdef NH_DEFINE
|
||||
#undef NH_DEFINE
|
||||
#define D_CacheSurface sw32_D_CacheSurface
|
||||
#define D_DrawParticle sw32_D_DrawParticle
|
||||
#define D_DrawPoly sw32_D_DrawPoly
|
||||
#define D_DrawSkyScans sw32_D_DrawSkyScans
|
||||
#define D_DrawSpans sw32_D_DrawSpans
|
||||
#define D_DrawSprite sw32_D_DrawSprite
|
||||
#define D_DrawSurfaces sw32_D_DrawSurfaces
|
||||
#define D_DrawZPoint sw32_D_DrawZPoint
|
||||
#define D_DrawZSpans sw32_D_DrawZSpans
|
||||
#define D_FillRect sw32_D_FillRect
|
||||
#define D_FlushCaches sw32_D_FlushCaches
|
||||
#define D_Init sw32_D_Init
|
||||
#define D_InitCaches sw32_D_InitCaches
|
||||
#define D_MipLevelForScale sw32_D_MipLevelForScale
|
||||
#define D_PolysetCalcGradients sw32_D_PolysetCalcGradients
|
||||
#define D_PolysetDraw sw32_D_PolysetDraw
|
||||
#define D_PolysetScanLeftEdge sw32_D_PolysetScanLeftEdge
|
||||
#define D_PolysetSetEdgeTable sw32_D_PolysetSetEdgeTable
|
||||
#define D_RasterizeAliasPolySmooth sw32_D_RasterizeAliasPolySmooth
|
||||
#define D_SetupFrame sw32_D_SetupFrame
|
||||
#define D_SpriteDrawSpans sw32_D_SpriteDrawSpans
|
||||
#define D_SurfaceCacheAddress sw32_D_SurfaceCacheAddress
|
||||
#define D_SurfaceCacheForRes sw32_D_SurfaceCacheForRes
|
||||
#define D_TurnZOn sw32_D_TurnZOn
|
||||
#define D_UpdateRects sw32_D_UpdateRects
|
||||
#define D_ViewChanged sw32_D_ViewChanged
|
||||
#define D_WarpScreen sw32_D_WarpScreen
|
||||
#define Draw_AltString sw32_Draw_AltString
|
||||
#define Draw_BlendScreen sw32_Draw_BlendScreen
|
||||
#define Draw_CachePic sw32_Draw_CachePic
|
||||
#define Draw_Character sw32_Draw_Character
|
||||
#define Draw_ConsoleBackground sw32_Draw_ConsoleBackground
|
||||
#define Draw_Crosshair sw32_Draw_Crosshair
|
||||
#define Draw_CrosshairAt sw32_Draw_CrosshairAt
|
||||
#define Draw_DestroyPic sw32_Draw_DestroyPic
|
||||
#define Draw_FadeScreen sw32_Draw_FadeScreen
|
||||
#define Draw_Fill sw32_Draw_Fill
|
||||
#define Draw_Init sw32_Draw_Init
|
||||
#define Draw_MakePic sw32_Draw_MakePic
|
||||
#define Draw_Pic sw32_Draw_Pic
|
||||
#define Draw_PicFromWad sw32_Draw_PicFromWad
|
||||
#define Draw_Picf sw32_Draw_Picf
|
||||
#define Draw_String sw32_Draw_String
|
||||
#define Draw_SubPic sw32_Draw_SubPic
|
||||
#define Draw_TextBox sw32_Draw_TextBox
|
||||
#define Draw_TileClear sw32_Draw_TileClear
|
||||
#define Draw_UncachePic sw32_Draw_UncachePic
|
||||
#define Draw_nString sw32_Draw_nString
|
||||
#define R_AliasCheckBBox sw32_R_AliasCheckBBox
|
||||
#define R_AliasClipTriangle sw32_R_AliasClipTriangle
|
||||
#define R_AliasClipAndProjectFinalVert sw32_R_AliasClipAndProjectFinalVert
|
||||
#define R_AliasDrawModel sw32_R_AliasDrawModel
|
||||
#define R_AliasProjectFinalVert sw32_R_AliasProjectFinalVert
|
||||
#define R_AliasSetUpTransform sw32_R_AliasSetUpTransform
|
||||
#define R_AliasTransformAndProjectFinalVerts sw32_R_AliasTransformAndProjectFinalVerts
|
||||
#define R_AliasTransformFinalVert sw32_R_AliasTransformFinalVert
|
||||
#define R_AliasTransformVector sw32_R_AliasTransformVector
|
||||
#define R_Alias_clip_bottom sw32_R_Alias_clip_bottom
|
||||
#define R_Alias_clip_left sw32_R_Alias_clip_left
|
||||
#define R_Alias_clip_right sw32_R_Alias_clip_right
|
||||
#define R_Alias_clip_top sw32_R_Alias_clip_top
|
||||
#define R_IQMDrawModel sw32_R_IQMDrawModel
|
||||
#define R_BeginEdgeFrame sw32_R_BeginEdgeFrame
|
||||
#define R_ClearState sw32_R_ClearState
|
||||
#define R_ClipEdge sw32_R_ClipEdge
|
||||
#define R_DrawParticles sw32_R_DrawParticles
|
||||
#define R_DrawSolidClippedSubmodelPolygons sw32_R_DrawSolidClippedSubmodelPolygons
|
||||
#define R_DrawSprite sw32_R_DrawSprite
|
||||
#define R_DrawSubmodelPolygons sw32_R_DrawSubmodelPolygons
|
||||
#define R_DrawSurface sw32_R_DrawSurface
|
||||
#define R_EmitEdge sw32_R_EmitEdge
|
||||
#define R_GenerateSpans sw32_R_GenerateSpans
|
||||
#define R_InitParticles sw32_R_InitParticles
|
||||
#define R_InitSky sw32_R_InitSky
|
||||
#define R_InitTurb sw32_R_InitTurb
|
||||
#define R_InsertNewEdges sw32_R_InsertNewEdges
|
||||
#define R_LineGraph sw32_R_LineGraph
|
||||
#define R_LoadSky_f sw32_R_LoadSky_f
|
||||
#define R_LoadSkys sw32_R_LoadSkys
|
||||
#define R_MakeSky sw32_R_MakeSky
|
||||
#define R_NewMap sw32_R_NewMap
|
||||
#define R_Particle_New sw32_R_Particle_New
|
||||
#define R_Particle_NewRandom sw32_R_Particle_NewRandom
|
||||
#define R_Particles_Init_Cvars sw32_R_Particles_Init_Cvars
|
||||
#define R_PrintAliasStats sw32_R_PrintAliasStats
|
||||
#define R_PrintTimes sw32_R_PrintTimes
|
||||
#define R_ReadPointFile_f sw32_R_ReadPointFile_f
|
||||
#define R_RemoveEdges sw32_R_RemoveEdges
|
||||
#define R_RenderBmodelFace sw32_R_RenderBmodelFace
|
||||
#define R_RenderFace sw32_R_RenderFace
|
||||
#define R_RenderPoly sw32_R_RenderPoly
|
||||
#define R_RenderView sw32_R_RenderView
|
||||
#define R_RenderWorld sw32_R_RenderWorld
|
||||
#define R_RotateBmodel sw32_R_RotateBmodel
|
||||
#define R_ScanEdges sw32_R_ScanEdges
|
||||
#define R_SetSkyFrame sw32_R_SetSkyFrame
|
||||
#define R_SetupFrame sw32_R_SetupFrame
|
||||
#define R_StepActiveU sw32_R_StepActiveU
|
||||
#define R_Textures_Init sw32_R_Textures_Init
|
||||
#define R_TimeRefresh_f sw32_R_TimeRefresh_f
|
||||
#define R_TransformFrustum sw32_R_TransformFrustum
|
||||
#define R_TransformPlane sw32_R_TransformPlane
|
||||
#define R_ViewChanged sw32_R_ViewChanged
|
||||
#define R_ZDrawSubmodelPolys sw32_R_ZDrawSubmodelPolys
|
||||
#define SCR_ScreenShot sw32_SCR_ScreenShot
|
||||
#define SCR_ScreenShot_f sw32_SCR_ScreenShot_f
|
||||
#define R_RenderFrame sw32_R_RenderFrame
|
||||
#define TransformVector sw32_TransformVector
|
||||
#define Turbulent sw32_Turbulent
|
||||
#define acolormap sw32_acolormap
|
||||
#define aliastransform sw32_aliastransform
|
||||
#define aliasxcenter sw32_aliasxcenter
|
||||
#define aliasxscale sw32_aliasxscale
|
||||
#define aliasycenter sw32_aliasycenter
|
||||
#define aliasyscale sw32_aliasyscale
|
||||
#define auxedges sw32_auxedges
|
||||
#define bbextents sw32_bbextents
|
||||
#define bbextentt sw32_bbextentt
|
||||
#define c_faceclip sw32_c_faceclip
|
||||
#define c_surf sw32_c_surf
|
||||
#define cacheblock sw32_cacheblock
|
||||
#define cachewidth sw32_cachewidth
|
||||
#define d_initial_rover sw32_d_initial_rover
|
||||
#define d_minmip sw32_d_minmip
|
||||
#define d_pix_max sw32_d_pix_max
|
||||
#define d_pix_min sw32_d_pix_min
|
||||
#define d_pix_shift sw32_d_pix_shift
|
||||
#define d_pzbuffer sw32_d_pzbuffer
|
||||
#define d_roverwrapped sw32_d_roverwrapped
|
||||
#define d_scalemip sw32_d_scalemip
|
||||
#define d_scantable sw32_d_scantable
|
||||
#define d_sdivzorigin sw32_d_sdivzorigin
|
||||
#define d_sdivzstepu sw32_d_sdivzstepu
|
||||
#define d_sdivzstepv sw32_d_sdivzstepv
|
||||
#define d_tdivzorigin sw32_d_tdivzorigin
|
||||
#define d_tdivzstepu sw32_d_tdivzstepu
|
||||
#define d_tdivzstepv sw32_d_tdivzstepv
|
||||
#define d_viewbuffer sw32_d_viewbuffer
|
||||
#define d_vrectbottom_particle sw32_d_vrectbottom_particle
|
||||
#define d_vrectright_particle sw32_d_vrectright_particle
|
||||
#define d_vrectx sw32_d_vrectx
|
||||
#define d_vrecty sw32_d_vrecty
|
||||
#define d_y_aspect_shift sw32_d_y_aspect_shift
|
||||
#define d_ziorigin sw32_d_ziorigin
|
||||
#define d_zistepu sw32_d_zistepu
|
||||
#define d_zistepv sw32_d_zistepv
|
||||
#define d_zitable sw32_d_zitable
|
||||
#define d_zrowbytes sw32_d_zrowbytes
|
||||
#define d_zwidth sw32_d_zwidth
|
||||
#define edge_max sw32_edge_max
|
||||
#define edge_p sw32_edge_p
|
||||
#define insubmodel sw32_insubmodel
|
||||
#define intsintable sw32_intsintable
|
||||
#define newedges sw32_newedges
|
||||
#define numbtofpolys sw32_numbtofpolys
|
||||
#define pauxverts sw32_pauxverts
|
||||
#define pfinalverts sw32_pfinalverts
|
||||
#define pfrustum_indexes sw32_pfrustum_indexes
|
||||
#define pixelAspect sw32_pixelAspect
|
||||
#define r_affinetridesc sw32_r_affinetridesc
|
||||
#define r_aliastransition sw32_r_aliastransition
|
||||
#define r_aliasuvscale sw32_r_aliasuvscale
|
||||
#define r_ambientlight sw32_r_ambientlight
|
||||
#define r_amodels_drawn sw32_r_amodels_drawn
|
||||
#define r_apverts sw32_r_apverts
|
||||
#define r_ceilv1 sw32_r_ceilv1
|
||||
#define r_clipflags sw32_r_clipflags
|
||||
#define r_currentbkey sw32_r_currentbkey
|
||||
#define r_currentkey sw32_r_currentkey
|
||||
#define r_dowarp sw32_r_dowarp
|
||||
#define r_dowarpold sw32_r_dowarpold
|
||||
#define r_drawculledpolys sw32_r_drawculledpolys
|
||||
#define r_drawnpolycount sw32_r_drawnpolycount
|
||||
#define r_drawpolys sw32_r_drawpolys
|
||||
#define r_drawsurf sw32_r_drawsurf
|
||||
#define r_easter_eggs_f sw32_r_easter_eggs_f
|
||||
#define r_edges sw32_r_edges
|
||||
#define r_emitted sw32_r_emitted
|
||||
#define r_frustum_indexes sw32_r_frustum_indexes
|
||||
#define r_lastvertvalid sw32_r_lastvertvalid
|
||||
#define r_leftclipped sw32_r_leftclipped
|
||||
#define r_leftenter sw32_r_leftenter
|
||||
#define r_leftexit sw32_r_leftexit
|
||||
#define r_lzi1 sw32_r_lzi1
|
||||
#define r_maxedgesseen sw32_r_maxedgesseen
|
||||
#define r_maxsurfsseen sw32_r_maxsurfsseen
|
||||
#define r_nearzi sw32_r_nearzi
|
||||
#define r_nearzionly sw32_r_nearzionly
|
||||
#define r_numallocatededges sw32_r_numallocatededges
|
||||
#define r_outofedges sw32_r_outofedges
|
||||
#define r_outofsurfaces sw32_r_outofsurfaces
|
||||
#define r_particles_style_f sw32_r_particles_style_f
|
||||
#define r_pedge sw32_r_pedge
|
||||
#define r_pixbytes sw32_r_pixbytes
|
||||
#define r_plightvec sw32_r_plightvec
|
||||
#define r_polycount sw32_r_polycount
|
||||
#define r_resfudge sw32_r_resfudge
|
||||
#define r_rightclipped sw32_r_rightclipped
|
||||
#define r_rightenter sw32_r_rightenter
|
||||
#define r_rightexit sw32_r_rightexit
|
||||
#define r_shadelight sw32_r_shadelight
|
||||
#define r_skymade sw32_r_skymade
|
||||
#define r_skysource sw32_r_skysource
|
||||
#define r_skyspeed sw32_r_skyspeed
|
||||
#define r_skytime sw32_r_skytime
|
||||
#define r_spritedesc sw32_r_spritedesc
|
||||
#define r_u1 sw32_r_u1
|
||||
#define r_v1 sw32_r_v1
|
||||
#define r_viewchanged sw32_r_viewchanged
|
||||
#define r_warpbuffer sw32_r_warpbuffer
|
||||
#define r_worldmodelorg sw32_r_worldmodelorg
|
||||
#define r_worldpolysbacktofront sw32_r_worldpolysbacktofront
|
||||
#define r_zpointdesc sw32_r_zpointdesc
|
||||
#define removeedges sw32_removeedges
|
||||
#define sadjust sw32_sadjust
|
||||
#define sc_rover sw32_sc_rover
|
||||
#define scale_for_mip sw32_scale_for_mip
|
||||
#define screenedge sw32_screenedge
|
||||
#define screenwidth sw32_screenwidth
|
||||
#define sintable sw32_sintable
|
||||
#define surf_max sw32_surf_max
|
||||
#define surface_p sw32_surface_p
|
||||
extern struct surf_s *sw32_surfaces;
|
||||
//#define surfaces sw32_surfaces
|
||||
#define tadjust sw32_tadjust
|
||||
#define view_clipplanes sw32_view_clipplanes
|
||||
#define xcenter sw32_xcenter
|
||||
#define xscale sw32_xscale
|
||||
#define xscaleinv sw32_xscaleinv
|
||||
#define xscaleshrink sw32_xscaleshrink
|
||||
#define ycenter sw32_ycenter
|
||||
#define yscale sw32_yscale
|
||||
#define yscaleinv sw32_yscaleinv
|
||||
#define yscaleshrink sw32_yscaleshrink
|
||||
#define zspantable sw32_zspantable
|
||||
#else
|
||||
#undef D_CacheSurface
|
||||
#undef D_DrawParticle
|
||||
#undef D_DrawPoly
|
||||
#undef D_DrawSkyScans
|
||||
#undef D_DrawSpans
|
||||
#undef D_DrawSprite
|
||||
#undef D_DrawSurfaces
|
||||
#undef D_DrawZPoint
|
||||
#undef D_DrawZSpans
|
||||
#undef D_FillRect
|
||||
#undef D_FlushCaches
|
||||
#undef D_Init
|
||||
#undef D_InitCaches
|
||||
#undef D_MipLevelForScale
|
||||
#undef D_PolysetCalcGradients
|
||||
#undef D_PolysetDraw
|
||||
#undef D_PolysetScanLeftEdge
|
||||
#undef D_PolysetSetEdgeTable
|
||||
#undef D_RasterizeAliasPolySmooth
|
||||
#undef D_SetupFrame
|
||||
#undef D_SpriteDrawSpans
|
||||
#undef D_SurfaceCacheAddress
|
||||
#undef D_SurfaceCacheForRes
|
||||
#undef D_TurnZOn
|
||||
#undef D_UpdateRects
|
||||
#undef D_ViewChanged
|
||||
#undef D_WarpScreen
|
||||
#undef Draw_AltString
|
||||
#undef Draw_BlendScreen
|
||||
#undef Draw_CachePic
|
||||
#undef Draw_Character
|
||||
#undef Draw_ConsoleBackground
|
||||
#undef Draw_Crosshair
|
||||
#undef Draw_CrosshairAt
|
||||
#undef Draw_DestroyPic
|
||||
#undef Draw_FadeScreen
|
||||
#undef Draw_Fill
|
||||
#undef Draw_Init
|
||||
#undef Draw_MakePic
|
||||
#undef Draw_Pic
|
||||
#undef Draw_PicFromWad
|
||||
#undef Draw_Picf
|
||||
#undef Draw_String
|
||||
#undef Draw_SubPic
|
||||
#undef Draw_TextBox
|
||||
#undef Draw_TileClear
|
||||
#undef Draw_UncachePic
|
||||
#undef Draw_nString
|
||||
#undef R_AliasCheckBBox
|
||||
#undef R_AliasClipTriangle
|
||||
#undef R_AliasClipAndProjectFinalVert
|
||||
#undef R_AliasDrawModel
|
||||
#undef R_AliasProjectFinalVert
|
||||
#undef R_AliasSetUpTransform
|
||||
#undef R_AliasTransformAndProjectFinalVerts
|
||||
#undef R_AliasTransformFinalVert
|
||||
#undef R_AliasTransformVector
|
||||
#undef R_Alias_clip_bottom
|
||||
#undef R_Alias_clip_left
|
||||
#undef R_Alias_clip_right
|
||||
#undef R_Alias_clip_top
|
||||
#undef R_IQMDrawModel
|
||||
#undef R_BeginEdgeFrame
|
||||
#undef R_ClearState
|
||||
#undef R_ClipEdge
|
||||
#undef R_DrawParticles
|
||||
#undef R_DrawSolidClippedSubmodelPolygons
|
||||
#undef R_DrawSprite
|
||||
#undef R_DrawSubmodelPolygons
|
||||
#undef R_DrawSurface
|
||||
#undef R_EmitEdge
|
||||
#undef R_GenerateSpans
|
||||
#undef R_Init
|
||||
#undef R_InitParticles
|
||||
#undef R_InitSky
|
||||
#undef R_InitTurb
|
||||
#undef R_InsertNewEdges
|
||||
#undef R_LineGraph
|
||||
#undef R_LoadSky_f
|
||||
#undef R_LoadSkys
|
||||
#undef R_MakeSky
|
||||
#undef R_NewMap
|
||||
#undef R_Particle_New
|
||||
#undef R_Particle_NewRandom
|
||||
#undef R_Particles_Init_Cvars
|
||||
#undef R_PrintAliasStats
|
||||
#undef R_PrintTimes
|
||||
#undef R_ReadPointFile_f
|
||||
#undef R_RemoveEdges
|
||||
#undef R_RenderBmodelFace
|
||||
#undef R_RenderFace
|
||||
#undef R_RenderPoly
|
||||
#undef R_RenderView
|
||||
#undef R_RenderWorld
|
||||
#undef R_RotateBmodel
|
||||
#undef R_ScanEdges
|
||||
#undef R_SetSkyFrame
|
||||
#undef R_SetupFrame
|
||||
#undef R_StepActiveU
|
||||
#undef R_Textures_Init
|
||||
#undef R_TimeRefresh_f
|
||||
#undef R_TransformFrustum
|
||||
#undef R_TransformPlane
|
||||
#undef R_ViewChanged
|
||||
#undef R_ZDrawSubmodelPolys
|
||||
#undef SCR_CaptureBGR
|
||||
#undef SCR_ScreenShot
|
||||
#undef SCR_ScreenShot_f
|
||||
#undef R_RenderFrame
|
||||
#undef TransformVector
|
||||
#undef Turbulent
|
||||
#undef VID_InitBuffers
|
||||
#undef VID_ShiftPalette
|
||||
#undef acolormap
|
||||
#undef aliasxcenter
|
||||
#undef aliasxscale
|
||||
#undef aliasycenter
|
||||
#undef aliasyscale
|
||||
#undef auxedges
|
||||
#undef bbextents
|
||||
#undef bbextentt
|
||||
#undef c_faceclip
|
||||
#undef c_surf
|
||||
#undef cacheblock
|
||||
#undef cachewidth
|
||||
#undef d_initial_rover
|
||||
#undef d_minmip
|
||||
#undef d_pix_max
|
||||
#undef d_pix_min
|
||||
#undef d_pix_shift
|
||||
#undef d_pzbuffer
|
||||
#undef d_roverwrapped
|
||||
#undef d_scalemip
|
||||
#undef d_scantable
|
||||
#undef d_sdivzorigin
|
||||
#undef d_sdivzstepu
|
||||
#undef d_sdivzstepv
|
||||
#undef d_tdivzorigin
|
||||
#undef d_tdivzstepu
|
||||
#undef d_tdivzstepv
|
||||
#undef d_viewbuffer
|
||||
#undef d_vrectbottom_particle
|
||||
#undef d_vrectright_particle
|
||||
#undef d_vrectx
|
||||
#undef d_vrecty
|
||||
#undef d_y_aspect_shift
|
||||
#undef d_zitable
|
||||
#undef d_zrowbytes
|
||||
#undef d_zwidth
|
||||
#undef edge_max
|
||||
#undef edge_p
|
||||
#undef insubmodel
|
||||
#undef intsintable
|
||||
#undef newedges
|
||||
#undef numbtofpolys
|
||||
#undef pauxverts
|
||||
#undef pfinalverts
|
||||
#undef pfrustum_indexes
|
||||
#undef pixelAspect
|
||||
#undef r_affinetridesc
|
||||
#undef r_aliastransition
|
||||
#undef r_aliasuvscale
|
||||
#undef r_ambientlight
|
||||
#undef r_amodels_drawn
|
||||
#undef r_apverts
|
||||
#undef r_ceilv1
|
||||
#undef r_clipflags
|
||||
#undef r_currentbkey
|
||||
#undef r_currentkey
|
||||
#undef r_dowarp
|
||||
#undef r_dowarpold
|
||||
#undef r_drawculledpolys
|
||||
#undef r_drawnpolycount
|
||||
#undef r_drawpolys
|
||||
#undef r_drawsurf
|
||||
#undef r_easter_eggs_f
|
||||
#undef r_edges
|
||||
#undef r_emitted
|
||||
#undef r_frustum_indexes
|
||||
#undef r_lastvertvalid
|
||||
#undef r_leftclipped
|
||||
#undef r_leftenter
|
||||
#undef r_leftexit
|
||||
#undef r_lzi1
|
||||
#undef r_maxedgesseen
|
||||
#undef r_maxsurfsseen
|
||||
#undef r_nearzi
|
||||
#undef r_nearzionly
|
||||
#undef r_numallocatededges
|
||||
#undef r_outofedges
|
||||
#undef r_outofsurfaces
|
||||
#undef r_particles_style_f
|
||||
#undef r_pedge
|
||||
#undef r_pixbytes
|
||||
#undef r_plightvec
|
||||
#undef r_polycount
|
||||
#undef r_resfudge
|
||||
#undef r_rightclipped
|
||||
#undef r_rightenter
|
||||
#undef r_rightexit
|
||||
#undef r_shadelight
|
||||
#undef r_skymade
|
||||
#undef r_skysource
|
||||
#undef r_skyspeed
|
||||
#undef r_skytime
|
||||
#undef r_spritedesc
|
||||
#undef r_u1
|
||||
#undef r_v1
|
||||
#undef r_viewchanged
|
||||
#undef r_warpbuffer
|
||||
#undef r_worldmodelorg
|
||||
#undef r_worldpolysbacktofront
|
||||
#undef r_zpointdesc
|
||||
#undef removeedges
|
||||
#undef sadjust
|
||||
#undef sc_rover
|
||||
#undef scale_for_mip
|
||||
#undef screenedge
|
||||
#undef screenwidth
|
||||
#undef sintable
|
||||
#undef surf_max
|
||||
#undef surface_p
|
||||
//#undef surfaces
|
||||
#undef tadjust
|
||||
#undef view_clipplanes
|
||||
#undef xcenter
|
||||
#undef xscale
|
||||
#undef xscaleinv
|
||||
#undef xscaleshrink
|
||||
#undef ycenter
|
||||
#undef yscale
|
||||
#undef yscaleinv
|
||||
#undef yscaleshrink
|
||||
#undef zspantable
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
screen.c
|
||||
|
||||
master for refresh, status bar, console, chat, notify, 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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/image.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
/* SCREEN SHOTS */
|
||||
|
||||
tex_t *
|
||||
sw32_SCR_CaptureBGR (void)
|
||||
{
|
||||
int count, x, y;
|
||||
tex_t *tex;
|
||||
const byte *src;
|
||||
byte *dst;
|
||||
|
||||
count = vid.width * vid.height;
|
||||
tex = malloc (sizeof (tex_t) + count * 3);
|
||||
tex->data = (byte *) (tex + 1);
|
||||
SYS_CHECKMEM (tex);
|
||||
tex->width = vid.width;
|
||||
tex->height = vid.height;
|
||||
tex->format = tex_rgb;
|
||||
tex->palette = 0;
|
||||
src = vid.buffer;
|
||||
for (y = 0; y < tex->height; y++) {
|
||||
dst = tex->data + (tex->height - 1 - y) * tex->width * 3;
|
||||
for (x = 0; x < tex->width; x++) {
|
||||
*dst++ = vid.basepal[*src * 3 + 2]; // blue
|
||||
*dst++ = vid.basepal[*src * 3 + 1]; // green
|
||||
*dst++ = vid.basepal[*src * 3 + 0]; // red
|
||||
src++;
|
||||
}
|
||||
}
|
||||
return tex;
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
sw32_graph.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/draw.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
/*
|
||||
R_LineGraph
|
||||
|
||||
Called by only R_DisplayTime
|
||||
*/
|
||||
void
|
||||
sw32_R_LineGraph (int x, int y, int *h_vals, int count, int height)
|
||||
{
|
||||
int h, i, s, color;
|
||||
|
||||
// FIXME: disable on no-buffer adapters, or put in the driver
|
||||
s = height;
|
||||
|
||||
while (count--) {
|
||||
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 = 0xff; // pink
|
||||
|
||||
if (h > s)
|
||||
h = s;
|
||||
|
||||
switch(sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
{
|
||||
byte *dest = (byte *) vid.buffer + vid.rowbytes * y + x;
|
||||
for (i = 0; i < h; i++, dest -= vid.rowbytes)
|
||||
*dest = color;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
short *dest = (short *) vid.buffer +
|
||||
(vid.rowbytes >> 1) * y + x;
|
||||
color = sw32_8to16table[color];
|
||||
for (i = 0; i < h; i++, dest -= (vid.rowbytes >> 1))
|
||||
*dest = color;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
int *dest = (int *) vid.buffer +
|
||||
(vid.rowbytes >> 2) * y + x;
|
||||
color = d_8to24table[color];
|
||||
for (i = 0; i < h; i++, dest -= (vid.rowbytes >> 2))
|
||||
*dest = color;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("R_LineGraph: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,315 +0,0 @@
|
|||
/*
|
||||
r_aclip.c
|
||||
|
||||
clip routines for drawing Alias models directly to the screen
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "d_local.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
static finalvert_t fv[2][8];
|
||||
static auxvert_t av[8];
|
||||
|
||||
/*
|
||||
R_Alias_clip_z
|
||||
|
||||
pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
|
||||
*/
|
||||
static void
|
||||
R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
auxvert_t *pav0, *pav1, avout;
|
||||
|
||||
pav0 = &av[pfv0 - &fv[0][0]];
|
||||
pav1 = &av[pfv1 - &fv[0][0]];
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1]) {
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
|
||||
(pav1->fv[2] - pav0->fv[2]);
|
||||
|
||||
avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
|
||||
avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
|
||||
out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
|
||||
out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
|
||||
} else {
|
||||
scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
|
||||
(pav0->fv[2] - pav1->fv[2]);
|
||||
|
||||
avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
|
||||
avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
|
||||
avout.fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
|
||||
out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
|
||||
out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
|
||||
out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
|
||||
}
|
||||
|
||||
sw32_R_AliasProjectFinalVert (out, &avout);
|
||||
|
||||
if (out->v[0] < r_refdef.aliasvrect.x)
|
||||
out->flags |= ALIAS_LEFT_CLIP;
|
||||
if (out->v[1] < r_refdef.aliasvrect.y)
|
||||
out->flags |= ALIAS_TOP_CLIP;
|
||||
if (out->v[0] > r_refdef.aliasvrectright)
|
||||
out->flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out->v[1] > r_refdef.aliasvrectbottom)
|
||||
out->flags |= ALIAS_BOTTOM_CLIP;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1]) {
|
||||
scale = (float) (r_refdef.aliasvrect.x - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
|
||||
} else {
|
||||
scale = (float) (r_refdef.aliasvrect.x - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1]) {
|
||||
scale = (float) (r_refdef.aliasvrectright - pfv0->v[0]) /
|
||||
(pfv1->v[0] - pfv0->v[0]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
|
||||
} else {
|
||||
scale = (float) (r_refdef.aliasvrectright - pfv1->v[0]) /
|
||||
(pfv0->v[0] - pfv1->v[0]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1]) {
|
||||
scale = (float) (r_refdef.aliasvrect.y - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
|
||||
} else {
|
||||
scale = (float) (r_refdef.aliasvrect.y - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
|
||||
{
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (pfv0->v[1] >= pfv1->v[1]) {
|
||||
scale = (float) (r_refdef.aliasvrectbottom - pfv0->v[1]) /
|
||||
(pfv1->v[1] - pfv0->v[1]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i]) * scale + 0.5;
|
||||
} else {
|
||||
scale = (float) (r_refdef.aliasvrectbottom - pfv1->v[1]) /
|
||||
(pfv0->v[1] - pfv1->v[1]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i]) * scale + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
|
||||
void (*clip) (finalvert_t *pfv0, finalvert_t *pfv1,
|
||||
finalvert_t *out))
|
||||
{
|
||||
int i, j, k;
|
||||
int flags, oldflags;
|
||||
|
||||
j = count - 1;
|
||||
k = 0;
|
||||
for (i = 0; i < count; j = i, i++) {
|
||||
oldflags = in[j].flags & flag;
|
||||
flags = in[i].flags & flag;
|
||||
|
||||
if (flags && oldflags)
|
||||
continue;
|
||||
if (oldflags ^ flags) {
|
||||
clip (&in[j], &in[i], &out[k]);
|
||||
out[k].flags = 0;
|
||||
if (out[k].v[0] < r_refdef.aliasvrect.x)
|
||||
out[k].flags |= ALIAS_LEFT_CLIP;
|
||||
if (out[k].v[1] < r_refdef.aliasvrect.y)
|
||||
out[k].flags |= ALIAS_TOP_CLIP;
|
||||
if (out[k].v[0] > r_refdef.aliasvrectright)
|
||||
out[k].flags |= ALIAS_RIGHT_CLIP;
|
||||
if (out[k].v[1] > r_refdef.aliasvrectbottom)
|
||||
out[k].flags |= ALIAS_BOTTOM_CLIP;
|
||||
k++;
|
||||
}
|
||||
if (!flags) {
|
||||
out[k] = in[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_AliasClipTriangle (mtriangle_t *ptri)
|
||||
{
|
||||
int i, k, pingpong;
|
||||
mtriangle_t mtri;
|
||||
unsigned int clipflags;
|
||||
|
||||
// copy vertexes and fix seam texture coordinates
|
||||
if (ptri->facesfront) {
|
||||
fv[0][0] = pfinalverts[ptri->vertindex[0]];
|
||||
fv[0][1] = pfinalverts[ptri->vertindex[1]];
|
||||
fv[0][2] = pfinalverts[ptri->vertindex[2]];
|
||||
} else {
|
||||
for (i = 0; i < 3; i++) {
|
||||
fv[0][i] = pfinalverts[ptri->vertindex[i]];
|
||||
|
||||
if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM))
|
||||
fv[0][i].v[2] += sw32_r_affinetridesc.seamfixupX16;
|
||||
}
|
||||
}
|
||||
|
||||
// clip
|
||||
clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
|
||||
|
||||
if (clipflags & ALIAS_Z_CLIP) {
|
||||
for (i = 0; i < 3; i++)
|
||||
av[i] = sw32_pauxverts[ptri->vertindex[i]];
|
||||
|
||||
k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong = 1;
|
||||
clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
|
||||
} else {
|
||||
pingpong = 0;
|
||||
k = 3;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_LEFT_CLIP) {
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_LEFT_CLIP, k, sw32_R_Alias_clip_left);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_RIGHT_CLIP) {
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_RIGHT_CLIP, k, sw32_R_Alias_clip_right);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_BOTTOM_CLIP) {
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_BOTTOM_CLIP, k, sw32_R_Alias_clip_bottom);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
if (clipflags & ALIAS_TOP_CLIP) {
|
||||
k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
|
||||
ALIAS_TOP_CLIP, k, sw32_R_Alias_clip_top);
|
||||
if (k == 0)
|
||||
return;
|
||||
|
||||
pingpong ^= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < k; i++) {
|
||||
if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
|
||||
else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
|
||||
fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
|
||||
|
||||
if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
|
||||
else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
|
||||
fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
|
||||
|
||||
fv[pingpong][i].flags = 0;
|
||||
}
|
||||
|
||||
// draw triangles
|
||||
mtri.facesfront = ptri->facesfront;
|
||||
sw32_r_affinetridesc.ptriangles = &mtri;
|
||||
sw32_r_affinetridesc.pfinalverts = fv[pingpong];
|
||||
|
||||
// FIXME: do all at once as trifan?
|
||||
mtri.vertindex[0] = 0;
|
||||
for (i = 1; i < k - 1; i++) {
|
||||
mtri.vertindex[1] = i;
|
||||
mtri.vertindex[2] = i + 1;
|
||||
sw32_D_PolysetDraw ();
|
||||
}
|
||||
}
|
|
@ -1,681 +0,0 @@
|
|||
/*
|
||||
sw32_ralias.c
|
||||
|
||||
routines for setting up to draw 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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/image.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/skin.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "d_ifacea.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#define LIGHT_MIN 5 // lowest light value we'll allow, to
|
||||
// avoid the need for inner-loop light
|
||||
// clamping
|
||||
|
||||
affinetridesc_t sw32_r_affinetridesc;
|
||||
|
||||
void *sw32_acolormap; // FIXME: should go away
|
||||
|
||||
trivertx_t *sw32_r_apverts;
|
||||
|
||||
// TODO: these probably will go away with optimized rasterization
|
||||
static mdl_t *pmdl;
|
||||
vec3_t sw32_r_plightvec;
|
||||
int sw32_r_ambientlight;
|
||||
float sw32_r_shadelight;
|
||||
static aliashdr_t *paliashdr;
|
||||
finalvert_t *sw32_pfinalverts;
|
||||
auxvert_t *sw32_pauxverts;
|
||||
float sw32_ziscale;
|
||||
static model_t *pmodel;
|
||||
|
||||
static vec3_t alias_forward, alias_right, alias_up;
|
||||
|
||||
static maliasskindesc_t *pskindesc;
|
||||
|
||||
int sw32_r_amodels_drawn;
|
||||
static int a_skinwidth;
|
||||
static int r_anumverts;
|
||||
|
||||
float sw32_aliastransform[3][4];
|
||||
|
||||
typedef struct {
|
||||
int index0;
|
||||
int index1;
|
||||
} aedge_t;
|
||||
|
||||
static aedge_t aedges[12] = {
|
||||
{0, 1}, {1, 2}, {2, 3}, {3, 0},
|
||||
{4, 5}, {5, 6}, {6, 7}, {7, 4},
|
||||
{0, 5}, {1, 4}, {2, 7}, {3, 6}
|
||||
};
|
||||
|
||||
qboolean
|
||||
sw32_R_AliasCheckBBox (void)
|
||||
{
|
||||
int i, flags, frame, numv;
|
||||
aliashdr_t *pahdr;
|
||||
float zi, basepts[8][3], v0, v1, frac;
|
||||
finalvert_t *pv0, *pv1, viewpts[16];
|
||||
auxvert_t *pa0, *pa1, viewaux[16];
|
||||
maliasframedesc_t *pframedesc;
|
||||
qboolean zclipped, zfullyclipped;
|
||||
unsigned int anyclip, allclip;
|
||||
int minz;
|
||||
|
||||
// expand, rotate, and translate points into worldspace
|
||||
currententity->visibility.trivial_accept = 0;
|
||||
pmodel = currententity->renderer.model;
|
||||
if (!(pahdr = pmodel->aliashdr))
|
||||
pahdr = Cache_Get (&pmodel->cache);
|
||||
pmdl = (mdl_t *) ((byte *) pahdr + pahdr->model);
|
||||
|
||||
sw32_R_AliasSetUpTransform (0);
|
||||
|
||||
// construct the base bounding box for this frame
|
||||
frame = currententity->animation.frame;
|
||||
// TODO: don't repeat this check when drawing?
|
||||
if ((frame >= pmdl->numframes) || (frame < 0)) {
|
||||
Sys_MaskPrintf (SYS_dev, "No such frame %d %s\n", frame, pmodel->path);
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
pframedesc = &pahdr->frames[frame];
|
||||
|
||||
// x worldspace coordinates
|
||||
basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] =
|
||||
(float) pframedesc->bboxmin.v[0];
|
||||
basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] =
|
||||
(float) pframedesc->bboxmax.v[0];
|
||||
|
||||
// y worldspace coordinates
|
||||
basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] =
|
||||
(float) pframedesc->bboxmin.v[1];
|
||||
basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] =
|
||||
(float) pframedesc->bboxmax.v[1];
|
||||
|
||||
// z worldspace coordinates
|
||||
basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] =
|
||||
(float) pframedesc->bboxmin.v[2];
|
||||
basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] =
|
||||
(float) pframedesc->bboxmax.v[2];
|
||||
|
||||
zclipped = false;
|
||||
zfullyclipped = true;
|
||||
|
||||
minz = 9999;
|
||||
for (i = 0; i < 8; i++) {
|
||||
sw32_R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]);
|
||||
|
||||
if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) {
|
||||
// we must clip points that are closer than the near clip plane
|
||||
viewpts[i].flags = ALIAS_Z_CLIP;
|
||||
zclipped = true;
|
||||
} else {
|
||||
if (viewaux[i].fv[2] < minz)
|
||||
minz = viewaux[i].fv[2];
|
||||
viewpts[i].flags = 0;
|
||||
zfullyclipped = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (zfullyclipped) {
|
||||
if (!pmodel->aliashdr)
|
||||
Cache_Release (&pmodel->cache);
|
||||
return false; // everything was near-z-clipped
|
||||
}
|
||||
|
||||
numv = 8;
|
||||
|
||||
if (zclipped) {
|
||||
// organize points by edges, use edges to get new points (possible
|
||||
// trivial reject)
|
||||
for (i = 0; i < 12; i++) {
|
||||
// edge endpoints
|
||||
pv0 = &viewpts[aedges[i].index0];
|
||||
pv1 = &viewpts[aedges[i].index1];
|
||||
pa0 = &viewaux[aedges[i].index0];
|
||||
pa1 = &viewaux[aedges[i].index1];
|
||||
|
||||
// if one end is clipped and the other isn't, make a new point
|
||||
if (pv0->flags ^ pv1->flags) {
|
||||
frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) /
|
||||
(pa1->fv[2] - pa0->fv[2]);
|
||||
viewaux[numv].fv[0] = pa0->fv[0] +
|
||||
(pa1->fv[0] - pa0->fv[0]) * frac;
|
||||
viewaux[numv].fv[1] = pa0->fv[1] +
|
||||
(pa1->fv[1] - pa0->fv[1]) * frac;
|
||||
viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE;
|
||||
viewpts[numv].flags = 0;
|
||||
numv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// project the vertices that remain after clipping
|
||||
anyclip = 0;
|
||||
allclip = ALIAS_XY_CLIP_MASK;
|
||||
|
||||
// TODO: probably should do this loop in ASM, especially if we use floats
|
||||
for (i = 0; i < numv; i++) {
|
||||
// we don't need to bother with vertices that were z-clipped
|
||||
if (viewpts[i].flags & ALIAS_Z_CLIP)
|
||||
continue;
|
||||
|
||||
zi = 1.0 / viewaux[i].fv[2];
|
||||
|
||||
// FIXME: do with chop mode in ASM, or convert to float
|
||||
v0 = (viewaux[i].fv[0] * sw32_xscale * zi) + sw32_xcenter;
|
||||
v1 = (viewaux[i].fv[1] * sw32_yscale * zi) + sw32_ycenter;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (v0 < r_refdef.fvrectx)
|
||||
flags |= ALIAS_LEFT_CLIP;
|
||||
if (v1 < r_refdef.fvrecty)
|
||||
flags |= ALIAS_TOP_CLIP;
|
||||
if (v0 > r_refdef.fvrectright)
|
||||
flags |= ALIAS_RIGHT_CLIP;
|
||||
if (v1 > r_refdef.fvrectbottom)
|
||||
flags |= ALIAS_BOTTOM_CLIP;
|
||||
|
||||
anyclip |= flags;
|
||||
allclip &= flags;
|
||||
}
|
||||
|
||||
if (allclip) {
|
||||
if (!pmodel->aliashdr)
|
||||
Cache_Release (&pmodel->cache);
|
||||
return false; // trivial reject off one side
|
||||
}
|
||||
|
||||
currententity->visibility.trivial_accept = !anyclip & !zclipped;
|
||||
|
||||
if (currententity->visibility.trivial_accept) {
|
||||
if (minz > (sw32_r_aliastransition + (pmdl->size * sw32_r_resfudge))) {
|
||||
currententity->visibility.trivial_accept |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pmodel->aliashdr)
|
||||
Cache_Release (&pmodel->cache);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_AliasTransformVector (vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = DotProduct (in, sw32_aliastransform[0])
|
||||
+ sw32_aliastransform[0][3];
|
||||
out[1] = DotProduct (in, sw32_aliastransform[1])
|
||||
+ sw32_aliastransform[1][3];
|
||||
out[2] = DotProduct (in, sw32_aliastransform[2])
|
||||
+ sw32_aliastransform[2][3];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_AliasClipAndProjectFinalVert (finalvert_t *fv, auxvert_t *av)
|
||||
{
|
||||
if (av->fv[2] < ALIAS_Z_CLIP_PLANE) {
|
||||
fv->flags |= ALIAS_Z_CLIP;
|
||||
return;
|
||||
}
|
||||
|
||||
sw32_R_AliasProjectFinalVert (fv, av);
|
||||
|
||||
if (fv->v[0] < r_refdef.aliasvrect.x)
|
||||
fv->flags |= ALIAS_LEFT_CLIP;
|
||||
if (fv->v[1] < r_refdef.aliasvrect.y)
|
||||
fv->flags |= ALIAS_TOP_CLIP;
|
||||
if (fv->v[0] > r_refdef.aliasvrectright)
|
||||
fv->flags |= ALIAS_RIGHT_CLIP;
|
||||
if (fv->v[1] > r_refdef.aliasvrectbottom)
|
||||
fv->flags |= ALIAS_BOTTOM_CLIP;
|
||||
}
|
||||
|
||||
static void
|
||||
R_AliasTransformFinalVert16 (auxvert_t *av, trivertx_t *pverts)
|
||||
{
|
||||
trivertx_t * pextra;
|
||||
float vextra[3];
|
||||
|
||||
pextra = pverts + pmdl->numverts;
|
||||
vextra[0] = pverts->v[0] + pextra->v[0] / (float)256;
|
||||
vextra[1] = pverts->v[1] + pextra->v[1] / (float)256;
|
||||
vextra[2] = pverts->v[2] + pextra->v[2] / (float)256;
|
||||
av->fv[0] = DotProduct (vextra, sw32_aliastransform[0]) +
|
||||
sw32_aliastransform[0][3];
|
||||
av->fv[1] = DotProduct (vextra, sw32_aliastransform[1]) +
|
||||
sw32_aliastransform[1][3];
|
||||
av->fv[2] = DotProduct (vextra, sw32_aliastransform[2]) +
|
||||
sw32_aliastransform[2][3];
|
||||
}
|
||||
|
||||
static void
|
||||
R_AliasTransformFinalVert8 (auxvert_t *av, trivertx_t *pverts)
|
||||
{
|
||||
av->fv[0] = DotProduct (pverts->v, sw32_aliastransform[0]) +
|
||||
sw32_aliastransform[0][3];
|
||||
av->fv[1] = DotProduct (pverts->v, sw32_aliastransform[1]) +
|
||||
sw32_aliastransform[1][3];
|
||||
av->fv[2] = DotProduct (pverts->v, sw32_aliastransform[2]) +
|
||||
sw32_aliastransform[2][3];
|
||||
}
|
||||
|
||||
/*
|
||||
R_AliasPreparePoints
|
||||
|
||||
General clipped case
|
||||
*/
|
||||
static void
|
||||
R_AliasPreparePoints (void)
|
||||
{
|
||||
int i;
|
||||
stvert_t *pstverts;
|
||||
finalvert_t *fv;
|
||||
auxvert_t *av;
|
||||
mtriangle_t *ptri;
|
||||
finalvert_t *pfv[3];
|
||||
|
||||
pstverts = (stvert_t *) ((byte *) paliashdr + paliashdr->stverts);
|
||||
r_anumverts = pmdl->numverts;
|
||||
fv = pfinalverts;
|
||||
av = sw32_pauxverts;
|
||||
|
||||
if (pmdl->ident == HEADER_MDL16) {
|
||||
for (i = 0; i < r_anumverts; i++, fv++, av++, sw32_r_apverts++,
|
||||
pstverts++) {
|
||||
R_AliasTransformFinalVert16 (av, sw32_r_apverts);
|
||||
sw32_R_AliasTransformFinalVert (fv, sw32_r_apverts, pstverts);
|
||||
R_AliasClipAndProjectFinalVert (fv, av);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < r_anumverts; i++, fv++, av++, sw32_r_apverts++,
|
||||
pstverts++) {
|
||||
R_AliasTransformFinalVert8 (av, sw32_r_apverts);
|
||||
sw32_R_AliasTransformFinalVert (fv, sw32_r_apverts, pstverts);
|
||||
R_AliasClipAndProjectFinalVert (fv, av);
|
||||
}
|
||||
}
|
||||
|
||||
// clip and draw all triangles
|
||||
sw32_r_affinetridesc.numtriangles = 1;
|
||||
|
||||
ptri = (mtriangle_t *) ((byte *) paliashdr + paliashdr->triangles);
|
||||
for (i = 0; i < pmdl->numtris; i++, ptri++) {
|
||||
pfv[0] = &pfinalverts[ptri->vertindex[0]];
|
||||
pfv[1] = &pfinalverts[ptri->vertindex[1]];
|
||||
pfv[2] = &pfinalverts[ptri->vertindex[2]];
|
||||
|
||||
if (pfv[0]->flags & pfv[1]->flags & pfv[2]->
|
||||
flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP))
|
||||
continue; // completely clipped
|
||||
|
||||
if (!((pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) &
|
||||
(ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP))) { // totally unclipped
|
||||
sw32_r_affinetridesc.pfinalverts = pfinalverts;
|
||||
sw32_r_affinetridesc.ptriangles = ptri;
|
||||
sw32_D_PolysetDraw ();
|
||||
} else { // partially clipped
|
||||
sw32_R_AliasClipTriangle (ptri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_AliasSetUpTransform (int trivial_accept)
|
||||
{
|
||||
int i;
|
||||
float rotationmatrix[3][4], t2matrix[3][4];
|
||||
static float tmatrix[3][4];
|
||||
static float viewmatrix[3][4];
|
||||
|
||||
mat4f_t mat;
|
||||
Transform_GetWorldMatrix (currententity->transform, mat);
|
||||
VectorCopy (mat[0], alias_forward);
|
||||
VectorNegate (mat[1], alias_right);
|
||||
VectorCopy (mat[2], alias_up);
|
||||
|
||||
tmatrix[0][0] = pmdl->scale[0];
|
||||
tmatrix[1][1] = pmdl->scale[1];
|
||||
tmatrix[2][2] = pmdl->scale[2];
|
||||
|
||||
tmatrix[0][3] = pmdl->scale_origin[0];
|
||||
tmatrix[1][3] = pmdl->scale_origin[1];
|
||||
tmatrix[2][3] = pmdl->scale_origin[2];
|
||||
|
||||
// TODO: can do this with simple matrix rearrangement
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
t2matrix[i][0] = alias_forward[i];
|
||||
t2matrix[i][1] = -alias_right[i];
|
||||
t2matrix[i][2] = alias_up[i];
|
||||
}
|
||||
|
||||
t2matrix[0][3] = -modelorg[0];
|
||||
t2matrix[1][3] = -modelorg[1];
|
||||
t2matrix[2][3] = -modelorg[2];
|
||||
|
||||
// FIXME: can do more efficiently than full concatenation
|
||||
R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix);
|
||||
|
||||
// TODO: should be global, set when vright, etc., set
|
||||
VectorCopy (vright, viewmatrix[0]);
|
||||
VectorCopy (vup, viewmatrix[1]);
|
||||
VectorNegate (viewmatrix[1], viewmatrix[1]);
|
||||
VectorCopy (vpn, viewmatrix[2]);
|
||||
|
||||
// viewmatrix[0][3] = 0;
|
||||
// viewmatrix[1][3] = 0;
|
||||
// viewmatrix[2][3] = 0;
|
||||
|
||||
R_ConcatTransforms (viewmatrix, rotationmatrix, sw32_aliastransform);
|
||||
|
||||
// do the scaling up of x and y to screen coordinates as part of the transform
|
||||
// for the unclipped case (it would mess up clipping in the clipped case).
|
||||
// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y
|
||||
// correspondingly so the projected x and y come out right
|
||||
// FIXME: make this work for clipped case too?
|
||||
if (trivial_accept) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
sw32_aliastransform[0][i] *= sw32_aliasxscale *
|
||||
(1.0 / ((float) 0x8000 * 0x10000));
|
||||
sw32_aliastransform[1][i] *= sw32_aliasyscale *
|
||||
(1.0 / ((float) 0x8000 * 0x10000));
|
||||
sw32_aliastransform[2][i] *= 1.0 / ((float) 0x8000 * 0x10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
sw32_R_AliasTransformFinalVert
|
||||
|
||||
now this function just copies the texture coordinates and calculates lighting
|
||||
actual 3D transform is done by R_AliasTransformFinalVert8/16 functions above
|
||||
*/
|
||||
void
|
||||
sw32_R_AliasTransformFinalVert (finalvert_t *fv, trivertx_t *pverts,
|
||||
stvert_t *pstverts)
|
||||
{
|
||||
int temp;
|
||||
float lightcos, *plightnormal;
|
||||
|
||||
fv->v[2] = pstverts->s;
|
||||
fv->v[3] = pstverts->t;
|
||||
|
||||
fv->flags = pstverts->onseam;
|
||||
|
||||
// lighting
|
||||
// LordHavoc: flipped lightcos so it is + for bright, not -
|
||||
plightnormal = r_avertexnormals[pverts->lightnormalindex];
|
||||
lightcos = -DotProduct (plightnormal, sw32_r_plightvec);
|
||||
temp = sw32_r_ambientlight;
|
||||
|
||||
if (lightcos > 0) {
|
||||
temp += (int) (sw32_r_shadelight * lightcos);
|
||||
|
||||
// clamp; because we limited the minimum ambient and shading light,
|
||||
// we don't have to clamp low light, just bright
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
}
|
||||
|
||||
fv->v[4] = temp;
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts)
|
||||
{
|
||||
int i, temp;
|
||||
float lightcos, *plightnormal, zi;
|
||||
trivertx_t *pverts;
|
||||
|
||||
pverts = sw32_r_apverts;
|
||||
|
||||
for (i = 0; i < r_anumverts; i++, fv++, pverts++, pstverts++) {
|
||||
// transform and project
|
||||
zi = 1.0 / (DotProduct (pverts->v, sw32_aliastransform[2]) +
|
||||
sw32_aliastransform[2][3]);
|
||||
|
||||
// x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
|
||||
// scaled up by 1/2**31, and the scaling cancels out for x and y in
|
||||
// the projection
|
||||
fv->v[5] = zi;
|
||||
|
||||
fv->v[0] = ((DotProduct (pverts->v, sw32_aliastransform[0]) +
|
||||
sw32_aliastransform[0][3]) * zi) + sw32_aliasxcenter;
|
||||
fv->v[1] = ((DotProduct (pverts->v, sw32_aliastransform[1]) +
|
||||
sw32_aliastransform[1][3]) * zi) + sw32_aliasycenter;
|
||||
|
||||
fv->v[2] = pstverts->s;
|
||||
fv->v[3] = pstverts->t;
|
||||
fv->flags = pstverts->onseam;
|
||||
|
||||
// lighting
|
||||
// LordHavoc: flipped lightcos so it is + for bright, not -
|
||||
plightnormal = r_avertexnormals[pverts->lightnormalindex];
|
||||
lightcos = -DotProduct (plightnormal, sw32_r_plightvec);
|
||||
temp = sw32_r_ambientlight;
|
||||
|
||||
if (lightcos > 0) {
|
||||
temp += (int) (sw32_r_shadelight * lightcos);
|
||||
|
||||
// clamp; because we limited the minimum ambient and shading
|
||||
// light, we don't have to clamp low light, just bright
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
}
|
||||
|
||||
fv->v[4] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av)
|
||||
{
|
||||
float zi;
|
||||
|
||||
// project points
|
||||
zi = 1.0 / av->fv[2];
|
||||
|
||||
fv->v[5] = zi * sw32_ziscale;
|
||||
|
||||
fv->v[0] = (av->fv[0] * sw32_aliasxscale * zi) + sw32_aliasxcenter;
|
||||
fv->v[1] = (av->fv[1] * sw32_aliasyscale * zi) + sw32_aliasycenter;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
R_AliasPrepareUnclippedPoints (void)
|
||||
{
|
||||
stvert_t *pstverts;
|
||||
|
||||
pstverts = (stvert_t *) ((byte *) paliashdr + paliashdr->stverts);
|
||||
r_anumverts = pmdl->numverts;
|
||||
|
||||
sw32_R_AliasTransformAndProjectFinalVerts (pfinalverts, pstverts);
|
||||
|
||||
sw32_r_affinetridesc.pfinalverts = pfinalverts;
|
||||
sw32_r_affinetridesc.ptriangles = (mtriangle_t *)
|
||||
((byte *) paliashdr + paliashdr->triangles);
|
||||
sw32_r_affinetridesc.numtriangles = pmdl->numtris;
|
||||
|
||||
sw32_D_PolysetDraw ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
R_AliasSetupSkin (entity_t *ent)
|
||||
{
|
||||
int skinnum;
|
||||
|
||||
skinnum = ent->renderer.skinnum;
|
||||
if ((skinnum >= pmdl->numskins) || (skinnum < 0)) {
|
||||
Sys_MaskPrintf (SYS_dev, "R_AliasSetupSkin: no such skin # %d\n",
|
||||
skinnum);
|
||||
skinnum = 0;
|
||||
}
|
||||
|
||||
pskindesc = R_AliasGetSkindesc (&ent->animation, skinnum, paliashdr);
|
||||
a_skinwidth = pmdl->skinwidth;
|
||||
|
||||
sw32_r_affinetridesc.pskin = (void *) ((byte *) paliashdr + pskindesc->skin);
|
||||
sw32_r_affinetridesc.skinwidth = a_skinwidth;
|
||||
sw32_r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16;
|
||||
sw32_r_affinetridesc.skinheight = pmdl->skinheight;
|
||||
|
||||
sw32_acolormap = vid.colormap8;
|
||||
if (ent->renderer.skin) {
|
||||
tex_t *base;
|
||||
|
||||
base = ent->renderer.skin->texels;
|
||||
if (base) {
|
||||
sw32_r_affinetridesc.pskin = base->data;
|
||||
sw32_r_affinetridesc.skinwidth = base->width;
|
||||
sw32_r_affinetridesc.skinheight = base->height;
|
||||
}
|
||||
sw32_acolormap = ent->renderer.skin->colormap;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_AliasSetupLighting (alight_t *plighting)
|
||||
{
|
||||
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't
|
||||
// have to clamp off the bottom
|
||||
sw32_r_ambientlight = plighting->ambientlight;
|
||||
|
||||
if (sw32_r_ambientlight < LIGHT_MIN)
|
||||
sw32_r_ambientlight = LIGHT_MIN;
|
||||
|
||||
sw32_r_ambientlight = (/*255 -*/ sw32_r_ambientlight) << VID_CBITS;
|
||||
|
||||
// if (sw32_r_ambientlight < LIGHT_MIN)
|
||||
// sw32_r_ambientlight = LIGHT_MIN;
|
||||
|
||||
sw32_r_shadelight = plighting->shadelight;
|
||||
|
||||
if (sw32_r_shadelight < 0)
|
||||
sw32_r_shadelight = 0;
|
||||
|
||||
sw32_r_shadelight *= VID_GRADES;
|
||||
|
||||
// rotate the lighting vector into the model's frame of reference
|
||||
sw32_r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward);
|
||||
sw32_r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right);
|
||||
sw32_r_plightvec[2] = DotProduct (plighting->plightvec, alias_up);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_AliasSetupFrame
|
||||
|
||||
set sw32_r_apverts
|
||||
*/
|
||||
static void
|
||||
R_AliasSetupFrame (entity_t *ent)
|
||||
{
|
||||
maliasframedesc_t *frame;
|
||||
|
||||
frame = R_AliasGetFramedesc (&ent->animation, paliashdr);
|
||||
sw32_r_apverts = (trivertx_t *) ((byte *) paliashdr + frame->frame);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_AliasDrawModel (alight_t *plighting)
|
||||
{
|
||||
entity_t *ent = currententity;
|
||||
int size;
|
||||
finalvert_t *finalverts;
|
||||
|
||||
sw32_r_amodels_drawn++;
|
||||
|
||||
if (!(paliashdr = ent->renderer.model->aliashdr))
|
||||
paliashdr = Cache_Get (&ent->renderer.model->cache);
|
||||
pmdl = (mdl_t *) ((byte *) paliashdr + paliashdr->model);
|
||||
|
||||
size = (CACHE_SIZE - 1)
|
||||
+ sizeof (finalvert_t) * (pmdl->numverts + 1)
|
||||
+ sizeof (auxvert_t) * pmdl->numverts;
|
||||
finalverts = (finalvert_t *) Hunk_TempAlloc (0, size);
|
||||
if (!finalverts)
|
||||
Sys_Error ("R_AliasDrawModel: out of memory");
|
||||
|
||||
// cache align
|
||||
pfinalverts = (finalvert_t *)
|
||||
(((intptr_t) &finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
sw32_pauxverts = (auxvert_t *) &pfinalverts[pmdl->numverts + 1];
|
||||
|
||||
R_AliasSetupSkin (ent);
|
||||
sw32_R_AliasSetUpTransform (ent->visibility.trivial_accept);
|
||||
R_AliasSetupLighting (plighting);
|
||||
R_AliasSetupFrame (ent);
|
||||
|
||||
if (!sw32_acolormap)
|
||||
sw32_acolormap = vid.colormap8;
|
||||
if (sw32_acolormap == &vid.colormap8 && sw32_ctx->pixbytes != 1)
|
||||
{
|
||||
if (sw32_ctx->pixbytes == 2)
|
||||
sw32_acolormap = vid.colormap16;
|
||||
else if (sw32_ctx->pixbytes == 4)
|
||||
sw32_acolormap = vid.colormap32;
|
||||
else
|
||||
Sys_Error("R_AliasDrawmodel: unsupported r_pixbytes %i",
|
||||
sw32_ctx->pixbytes);
|
||||
}
|
||||
|
||||
if (ent != vr_data.view_model)
|
||||
sw32_ziscale = (float) 0x8000 *(float) 0x10000;
|
||||
else
|
||||
sw32_ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
|
||||
|
||||
if (ent->visibility.trivial_accept) {
|
||||
R_AliasPrepareUnclippedPoints ();
|
||||
} else {
|
||||
R_AliasPreparePoints ();
|
||||
}
|
||||
|
||||
if (!ent->renderer.model->aliashdr) {
|
||||
Cache_Release (&ent->renderer.model->cache);
|
||||
}
|
||||
}
|
|
@ -1,536 +0,0 @@
|
|||
/*
|
||||
sw32_r_bsp.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "qfalloca.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
|
||||
// current entity info
|
||||
qboolean sw32_insubmodel;
|
||||
vec3_t sw32_r_worldmodelorg;
|
||||
static float entity_rotation[3][3];
|
||||
|
||||
int sw32_r_currentbkey;
|
||||
|
||||
typedef enum { touchessolid, drawnode, nodrawnode } solidstate_t;
|
||||
|
||||
#define MAX_BMODEL_VERTS 500 // 6K
|
||||
#define MAX_BMODEL_EDGES 1000 // 12K
|
||||
|
||||
static mvertex_t *pbverts;
|
||||
static bedge_t *pbedges;
|
||||
static int numbverts, numbedges;
|
||||
|
||||
int sw32_numbtofpolys;
|
||||
static btofpoly_t *pbtofpolys;
|
||||
|
||||
static mvertex_t *pfrontenter, *pfrontexit;
|
||||
|
||||
static qboolean makeclippededge;
|
||||
|
||||
|
||||
static void
|
||||
R_EntityRotate (vec3_t vec)
|
||||
{
|
||||
vec3_t tvec;
|
||||
|
||||
VectorCopy (vec, tvec);
|
||||
vec[0] = DotProduct (entity_rotation[0], tvec);
|
||||
vec[1] = DotProduct (entity_rotation[1], tvec);
|
||||
vec[2] = DotProduct (entity_rotation[2], tvec);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_RotateBmodel (void)
|
||||
{
|
||||
mat4f_t mat;
|
||||
Transform_GetWorldMatrix (currententity->transform, mat);
|
||||
VectorCopy (mat[0], entity_rotation[0]);
|
||||
VectorCopy (mat[1], entity_rotation[1]);
|
||||
VectorCopy (mat[2], entity_rotation[2]);
|
||||
|
||||
// rotate modelorg and the transformation matrix
|
||||
R_EntityRotate (modelorg);
|
||||
R_EntityRotate (vpn);
|
||||
R_EntityRotate (vright);
|
||||
R_EntityRotate (vup);
|
||||
|
||||
sw32_R_TransformFrustum ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf)
|
||||
{
|
||||
bedge_t *psideedges[2], *pnextedge, *ptedge;
|
||||
int i, side, lastside;
|
||||
float dist, frac, lastdist;
|
||||
plane_t *splitplane, tplane;
|
||||
mvertex_t *pvert, *plastvert, *ptvert;
|
||||
mnode_t *pn;
|
||||
|
||||
psideedges[0] = psideedges[1] = NULL;
|
||||
|
||||
makeclippededge = false;
|
||||
|
||||
// transform the BSP plane into model space
|
||||
// FIXME: cache these?
|
||||
splitplane = pnode->plane;
|
||||
tplane.dist = splitplane->dist -
|
||||
DotProduct (r_entorigin, splitplane->normal);
|
||||
tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
|
||||
tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
|
||||
tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal);
|
||||
|
||||
// clip edges to BSP plane
|
||||
for (; pedges; pedges = pnextedge) {
|
||||
pnextedge = pedges->pnext;
|
||||
|
||||
// set the status for the last point as the previous point
|
||||
// FIXME: cache this stuff somehow?
|
||||
plastvert = pedges->v[0];
|
||||
lastdist = DotProduct (plastvert->position, tplane.normal) -
|
||||
tplane.dist;
|
||||
|
||||
if (lastdist > 0)
|
||||
lastside = 0;
|
||||
else
|
||||
lastside = 1;
|
||||
|
||||
pvert = pedges->v[1];
|
||||
|
||||
dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
|
||||
|
||||
if (dist > 0)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
|
||||
if (side != lastside) {
|
||||
// clipped
|
||||
if (numbverts >= MAX_BMODEL_VERTS)
|
||||
return;
|
||||
|
||||
// generate the clipped vertex
|
||||
frac = lastdist / (lastdist - dist);
|
||||
ptvert = &pbverts[numbverts++];
|
||||
ptvert->position[0] = plastvert->position[0] +
|
||||
frac * (pvert->position[0] - plastvert->position[0]);
|
||||
ptvert->position[1] = plastvert->position[1] +
|
||||
frac * (pvert->position[1] - plastvert->position[1]);
|
||||
ptvert->position[2] = plastvert->position[2] +
|
||||
frac * (pvert->position[2] - plastvert->position[2]);
|
||||
|
||||
// split into two edges, one on each side, and remember entering
|
||||
// and exiting points
|
||||
// FIXME: share the clip edge by having a winding direction flag?
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 1)) {
|
||||
Sys_Printf ("Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[lastside];
|
||||
psideedges[lastside] = ptedge;
|
||||
ptedge->v[0] = plastvert;
|
||||
ptedge->v[1] = ptvert;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[side];
|
||||
psideedges[side] = ptedge;
|
||||
ptedge->v[0] = ptvert;
|
||||
ptedge->v[1] = pvert;
|
||||
|
||||
numbedges += 2;
|
||||
|
||||
if (side == 0) {
|
||||
// entering for front, exiting for back
|
||||
pfrontenter = ptvert;
|
||||
makeclippededge = true;
|
||||
} else {
|
||||
pfrontexit = ptvert;
|
||||
makeclippededge = true;
|
||||
}
|
||||
} else {
|
||||
// add the edge to the appropriate side
|
||||
pedges->pnext = psideedges[side];
|
||||
psideedges[side] = pedges;
|
||||
}
|
||||
}
|
||||
|
||||
// if anything was clipped, reconstitute and add the edges along the clip
|
||||
// plane to both sides (but in opposite directions)
|
||||
if (makeclippededge) {
|
||||
if (numbedges >= (MAX_BMODEL_EDGES - 2)) {
|
||||
Sys_Printf ("Out of edges for bmodel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ptedge = &pbedges[numbedges];
|
||||
ptedge->pnext = psideedges[0];
|
||||
psideedges[0] = ptedge;
|
||||
ptedge->v[0] = pfrontexit;
|
||||
ptedge->v[1] = pfrontenter;
|
||||
|
||||
ptedge = &pbedges[numbedges + 1];
|
||||
ptedge->pnext = psideedges[1];
|
||||
psideedges[1] = ptedge;
|
||||
ptedge->v[0] = pfrontenter;
|
||||
ptedge->v[1] = pfrontexit;
|
||||
|
||||
numbedges += 2;
|
||||
}
|
||||
// draw or recurse further
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (psideedges[i]) {
|
||||
// draw if we've reached a non-solid leaf, done if all that's left
|
||||
// is a solid leaf, and continue down the tree if it's not a leaf
|
||||
pn = pnode->children[i];
|
||||
|
||||
// we're done with this branch if the node or leaf isn't in the PVS
|
||||
if (pn->visframe == r_visframecount) {
|
||||
if (pn->contents < 0) {
|
||||
if (pn->contents != CONTENTS_SOLID) {
|
||||
sw32_r_currentbkey = ((mleaf_t *) pn)->key;
|
||||
sw32_R_RenderBmodelFace (psideedges[i], psurf);
|
||||
}
|
||||
} else {
|
||||
R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
|
||||
psurf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_DrawSolidClippedSubmodelPolygons (model_t *model)
|
||||
{
|
||||
int i, j, lindex;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces;
|
||||
plane_t *pplane;
|
||||
mvertex_t bverts[MAX_BMODEL_VERTS];
|
||||
bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
|
||||
medge_t *pedge, *pedges;
|
||||
mod_brush_t *brush = &model->brush;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &brush->surfaces[brush->firstmodelsurface];
|
||||
numsurfaces = brush->nummodelsurfaces;
|
||||
pedges = brush->edges;
|
||||
|
||||
for (i = 0; i < numsurfaces; i++, psurf++) {
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
// copy the edges to bedges, flipping if necessary so always
|
||||
// clockwise winding
|
||||
// FIXME: if edges and vertices get caches, these assignments must
|
||||
// move outside the loop, and overflow checking must be done here
|
||||
pbverts = bverts;
|
||||
pbedges = bedges;
|
||||
numbverts = numbedges = 0;
|
||||
|
||||
if (psurf->numedges > 0) {
|
||||
pbedge = &bedges[numbedges];
|
||||
numbedges += psurf->numedges;
|
||||
|
||||
for (j = 0; j < psurf->numedges; j++) {
|
||||
lindex = brush->surfedges[psurf->firstedge + j];
|
||||
|
||||
if (lindex > 0) {
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
} else {
|
||||
lindex = -lindex;
|
||||
pedge = &pedges[lindex];
|
||||
pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
|
||||
pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
|
||||
}
|
||||
|
||||
pbedge[j].pnext = &pbedge[j + 1];
|
||||
}
|
||||
|
||||
pbedge[j - 1].pnext = NULL; // mark end of edges
|
||||
|
||||
R_RecursiveClipBPoly (pbedge,
|
||||
currententity->visibility.topnode,
|
||||
psurf);
|
||||
} else {
|
||||
Sys_Error ("no edges in bmodel");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_DrawSubmodelPolygons (model_t *model, int clipflags)
|
||||
{
|
||||
int i;
|
||||
vec_t dot;
|
||||
msurface_t *psurf;
|
||||
int numsurfaces;
|
||||
plane_t *pplane;
|
||||
mod_brush_t *brush = &model->brush;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
|
||||
psurf = &brush->surfaces[brush->firstmodelsurface];
|
||||
numsurfaces = brush->nummodelsurfaces;
|
||||
|
||||
for (i = 0; i < numsurfaces; i++, psurf++) {
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
|
||||
sw32_r_currentkey
|
||||
= ((mleaf_t *) currententity->visibility.topnode)->key;
|
||||
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
sw32_R_RenderFace (psurf, clipflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
visit_leaf (mleaf_t *leaf)
|
||||
{
|
||||
// deal with model fragments in this leaf
|
||||
if (leaf->efrags)
|
||||
R_StoreEfrags (leaf->efrags);
|
||||
leaf->key = sw32_r_currentkey;
|
||||
sw32_r_currentkey++; // all bmodels in a leaf share the same key
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_side (mnode_t *node)
|
||||
{
|
||||
// find which side of the node we are on
|
||||
plane_t *plane = node->plane;
|
||||
|
||||
if (plane->type < 3)
|
||||
return (modelorg[plane->type] - plane->dist) < 0;
|
||||
return (DotProduct (modelorg, plane->normal) - plane->dist) < 0;
|
||||
}
|
||||
|
||||
static void
|
||||
visit_node (mod_brush_t *brush, mnode_t *node, int side, int clipflags)
|
||||
{
|
||||
int c;
|
||||
msurface_t *surf;
|
||||
|
||||
// sneaky hack for side = side ? SURF_PLANEBACK : 0;
|
||||
side = (~side + 1) & SURF_PLANEBACK;
|
||||
// draw stuff
|
||||
if ((c = node->numsurfaces)) {
|
||||
surf = brush->surfaces + node->firstsurface;
|
||||
for (; c; c--, surf++) {
|
||||
if (surf->visframe != r_visframecount)
|
||||
continue;
|
||||
|
||||
// side is either 0 or SURF_PLANEBACK
|
||||
if (side ^ (surf->flags & SURF_PLANEBACK))
|
||||
continue; // wrong side
|
||||
|
||||
if (sw32_r_drawpolys) {
|
||||
if (sw32_r_worldpolysbacktofront) {
|
||||
if (sw32_numbtofpolys < MAX_BTOFPOLYS) {
|
||||
pbtofpolys[sw32_numbtofpolys].clipflags = clipflags;
|
||||
pbtofpolys[sw32_numbtofpolys].psurf = surf;
|
||||
sw32_numbtofpolys++;
|
||||
}
|
||||
} else {
|
||||
sw32_R_RenderPoly (surf, clipflags);
|
||||
}
|
||||
} else {
|
||||
sw32_R_RenderFace (surf, clipflags);
|
||||
}
|
||||
}
|
||||
// all surfaces on the same node share the same sequence number
|
||||
sw32_r_currentkey++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_node (mnode_t *node, int *clipflags)
|
||||
{
|
||||
int i, *pindex;
|
||||
vec3_t acceptpt, rejectpt;
|
||||
double d;
|
||||
|
||||
if (node->contents < 0)
|
||||
return 0;
|
||||
if (node->visframe != r_visframecount)
|
||||
return 0;
|
||||
// cull the clipping planes if not trivial accept
|
||||
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
||||
// twice as fast in ASM
|
||||
if (*clipflags) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!(*clipflags & (1 << i)))
|
||||
continue; // don't need to clip against it
|
||||
|
||||
// generate accept and reject points
|
||||
// FIXME: do with fast look-ups or integer tests based on the
|
||||
// sign bit of the floating point values
|
||||
|
||||
pindex = sw32_pfrustum_indexes[i];
|
||||
|
||||
rejectpt[0] = (float) node->minmaxs[pindex[0]];
|
||||
rejectpt[1] = (float) node->minmaxs[pindex[1]];
|
||||
rejectpt[2] = (float) node->minmaxs[pindex[2]];
|
||||
|
||||
d = DotProduct (rejectpt, sw32_view_clipplanes[i].normal);
|
||||
d -= sw32_view_clipplanes[i].dist;
|
||||
|
||||
if (d <= 0)
|
||||
return 0;
|
||||
|
||||
acceptpt[0] = (float) node->minmaxs[pindex[3 + 0]];
|
||||
acceptpt[1] = (float) node->minmaxs[pindex[3 + 1]];
|
||||
acceptpt[2] = (float) node->minmaxs[pindex[3 + 2]];
|
||||
|
||||
d = DotProduct (acceptpt, sw32_view_clipplanes[i].normal);
|
||||
d -= sw32_view_clipplanes[i].dist;
|
||||
if (d >= 0)
|
||||
*clipflags &= ~(1 << i); // node is entirely on screen
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
R_VisitWorldNodes (mod_brush_t *brush, int clipflags)
|
||||
{
|
||||
typedef struct {
|
||||
mnode_t *node;
|
||||
int side, clipflags;
|
||||
} rstack_t;
|
||||
rstack_t *node_ptr;
|
||||
rstack_t *node_stack;
|
||||
mnode_t *node;
|
||||
mnode_t *front;
|
||||
int side, cf;
|
||||
|
||||
node = brush->nodes;
|
||||
// +2 for paranoia
|
||||
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
||||
node_ptr = node_stack;
|
||||
|
||||
cf = clipflags;
|
||||
while (1) {
|
||||
while (test_node (node, &cf)) {
|
||||
cf = clipflags;
|
||||
side = get_side (node);
|
||||
front = node->children[side];
|
||||
if (test_node (front, &cf)) {
|
||||
node_ptr->node = node;
|
||||
node_ptr->side = side;
|
||||
node_ptr->clipflags = clipflags;
|
||||
node_ptr++;
|
||||
clipflags = cf;
|
||||
node = front;
|
||||
continue;
|
||||
}
|
||||
if (front->contents < 0 && front->contents != CONTENTS_SOLID)
|
||||
visit_leaf ((mleaf_t *) front);
|
||||
visit_node (brush, node, side, clipflags);
|
||||
node = node->children[!side];
|
||||
}
|
||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
||||
visit_leaf ((mleaf_t *) node);
|
||||
if (node_ptr != node_stack) {
|
||||
node_ptr--;
|
||||
node = node_ptr->node;
|
||||
side = node_ptr->side;
|
||||
clipflags = node_ptr->clipflags;
|
||||
visit_node (brush, node, side, clipflags);
|
||||
node = node->children[!side];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
||||
visit_leaf ((mleaf_t *) node);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_RenderWorld (void)
|
||||
{
|
||||
int i;
|
||||
btofpoly_t btofpolys[MAX_BTOFPOLYS];
|
||||
mod_brush_t *brush;
|
||||
|
||||
pbtofpolys = btofpolys;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
VectorCopy (r_origin, modelorg);
|
||||
brush = ¤tentity->renderer.model->brush;
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
|
||||
R_VisitWorldNodes (brush, 15);
|
||||
|
||||
// if the driver wants the polygons back to front, play the visible ones
|
||||
// back in that order
|
||||
if (sw32_r_worldpolysbacktofront) {
|
||||
for (i = sw32_numbtofpolys - 1; i >= 0; i--) {
|
||||
sw32_R_RenderPoly (btofpolys[i].psurf, btofpolys[i].clipflags);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,804 +0,0 @@
|
|||
/*
|
||||
sw32_r_draw.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
#define MAXLEFTCLIPEDGES 100
|
||||
|
||||
// !!! if these are changed, they must be changed in asm_draw.h too !!!
|
||||
#define FULLY_CLIPPED_CACHED 0x80000000
|
||||
#define FRAMECOUNT_MASK 0x7FFFFFFF
|
||||
|
||||
static unsigned int cacheoffset;
|
||||
|
||||
int sw32_c_faceclip; // number of faces clipped
|
||||
|
||||
zpointdesc_t sw32_r_zpointdesc;
|
||||
|
||||
static polydesc_t r_polydesc;
|
||||
|
||||
clipplane_t sw32_view_clipplanes[4];
|
||||
|
||||
medge_t *sw32_r_pedge;
|
||||
|
||||
qboolean sw32_r_leftclipped, sw32_r_rightclipped;
|
||||
static qboolean makeleftedge, makerightedge;
|
||||
qboolean sw32_r_nearzionly;
|
||||
|
||||
int sw32_sintable[SIN_BUFFER_SIZE];
|
||||
int sw32_intsintable[SIN_BUFFER_SIZE];
|
||||
|
||||
mvertex_t sw32_r_leftenter, sw32_r_leftexit;
|
||||
mvertex_t sw32_r_rightenter, sw32_r_rightexit;
|
||||
|
||||
typedef struct {
|
||||
float u, v;
|
||||
int ceilv;
|
||||
} evert_t;
|
||||
|
||||
int sw32_r_emitted;
|
||||
float sw32_r_nearzi;
|
||||
float sw32_r_u1, sw32_r_v1, sw32_r_lzi1;
|
||||
int sw32_r_ceilv1;
|
||||
|
||||
qboolean sw32_r_lastvertvalid;
|
||||
|
||||
|
||||
void
|
||||
sw32_R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
|
||||
{
|
||||
edge_t *edge, *pcheck;
|
||||
int u_check;
|
||||
float u, u_step;
|
||||
vec3_t local, transformed;
|
||||
float *world;
|
||||
int v, v2, ceilv0;
|
||||
float scale, lzi0, u0, v0;
|
||||
int side;
|
||||
|
||||
if (sw32_r_lastvertvalid) {
|
||||
u0 = sw32_r_u1;
|
||||
v0 = sw32_r_v1;
|
||||
lzi0 = sw32_r_lzi1;
|
||||
ceilv0 = sw32_r_ceilv1;
|
||||
} else {
|
||||
world = &pv0->position[0];
|
||||
|
||||
// transform and project
|
||||
VectorSubtract (world, modelorg, local);
|
||||
sw32_TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
lzi0 = 1.0 / transformed[2];
|
||||
|
||||
// FIXME: build x/sw32_yscale into transform?
|
||||
scale = sw32_xscale * lzi0;
|
||||
u0 = (sw32_xcenter + scale * transformed[0]);
|
||||
if (u0 < r_refdef.fvrectx_adj)
|
||||
u0 = r_refdef.fvrectx_adj;
|
||||
if (u0 > r_refdef.fvrectright_adj)
|
||||
u0 = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = sw32_yscale * lzi0;
|
||||
v0 = (sw32_ycenter - scale * transformed[1]);
|
||||
if (v0 < r_refdef.fvrecty_adj)
|
||||
v0 = r_refdef.fvrecty_adj;
|
||||
if (v0 > r_refdef.fvrectbottom_adj)
|
||||
v0 = r_refdef.fvrectbottom_adj;
|
||||
|
||||
ceilv0 = (int) ceil (v0);
|
||||
}
|
||||
|
||||
world = &pv1->position[0];
|
||||
|
||||
// transform and project
|
||||
VectorSubtract (world, modelorg, local);
|
||||
sw32_TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
sw32_r_lzi1 = 1.0 / transformed[2];
|
||||
|
||||
scale = sw32_xscale * sw32_r_lzi1;
|
||||
sw32_r_u1 = (sw32_xcenter + scale * transformed[0]);
|
||||
if (sw32_r_u1 < r_refdef.fvrectx_adj)
|
||||
sw32_r_u1 = r_refdef.fvrectx_adj;
|
||||
if (sw32_r_u1 > r_refdef.fvrectright_adj)
|
||||
sw32_r_u1 = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = sw32_yscale * sw32_r_lzi1;
|
||||
sw32_r_v1 = (sw32_ycenter - scale * transformed[1]);
|
||||
if (sw32_r_v1 < r_refdef.fvrecty_adj)
|
||||
sw32_r_v1 = r_refdef.fvrecty_adj;
|
||||
if (sw32_r_v1 > r_refdef.fvrectbottom_adj)
|
||||
sw32_r_v1 = r_refdef.fvrectbottom_adj;
|
||||
|
||||
if (sw32_r_lzi1 > lzi0)
|
||||
lzi0 = sw32_r_lzi1;
|
||||
|
||||
if (lzi0 > sw32_r_nearzi) // for mipmap finding
|
||||
sw32_r_nearzi = lzi0;
|
||||
|
||||
// for right edges, all we want is the effect on 1/z
|
||||
if (sw32_r_nearzionly)
|
||||
return;
|
||||
|
||||
sw32_r_emitted = 1;
|
||||
|
||||
sw32_r_ceilv1 = (int) ceil (sw32_r_v1);
|
||||
|
||||
// create the edge
|
||||
if (ceilv0 == sw32_r_ceilv1) {
|
||||
// we cache unclipped horizontal edges as fully clipped
|
||||
if (cacheoffset != 0x7FFFFFFF) {
|
||||
cacheoffset = FULLY_CLIPPED_CACHED |
|
||||
(r_framecount & FRAMECOUNT_MASK);
|
||||
}
|
||||
|
||||
return; // horizontal edge
|
||||
}
|
||||
|
||||
side = ceilv0 > sw32_r_ceilv1;
|
||||
|
||||
edge = sw32_edge_p++;
|
||||
|
||||
edge->owner = sw32_r_pedge;
|
||||
|
||||
edge->nearzi = lzi0;
|
||||
|
||||
if (side == 0) {
|
||||
// trailing edge (go from p1 to p2)
|
||||
v = ceilv0;
|
||||
v2 = sw32_r_ceilv1 - 1;
|
||||
|
||||
edge->surfs[0] = sw32_surface_p - sw32_surfaces;
|
||||
edge->surfs[1] = 0;
|
||||
|
||||
u_step = ((sw32_r_u1 - u0) / (sw32_r_v1 - v0));
|
||||
u = u0 + ((float) v - v0) * u_step;
|
||||
} else {
|
||||
// leading edge (go from p2 to p1)
|
||||
v2 = ceilv0 - 1;
|
||||
v = sw32_r_ceilv1;
|
||||
|
||||
edge->surfs[0] = 0;
|
||||
edge->surfs[1] = sw32_surface_p - sw32_surfaces;
|
||||
|
||||
u_step = ((u0 - sw32_r_u1) / (v0 - sw32_r_v1));
|
||||
u = sw32_r_u1 + ((float) v - sw32_r_v1) * u_step;
|
||||
}
|
||||
|
||||
edge->u_step = u_step * 0x100000;
|
||||
edge->u = u * 0x100000 + 0xFFFFF;
|
||||
|
||||
// we need to do this to avoid stepping off the edges if a very nearly
|
||||
// horizontal edge is less than epsilon above a scan, and numeric error
|
||||
// causes it to incorrectly extend to the scan, and the extension of the
|
||||
// line goes off the edge of the screen
|
||||
// FIXME: is this actually needed?
|
||||
if (edge->u < r_refdef.vrect_x_adj_shift20)
|
||||
edge->u = r_refdef.vrect_x_adj_shift20;
|
||||
if (edge->u > r_refdef.vrectright_adj_shift20)
|
||||
edge->u = r_refdef.vrectright_adj_shift20;
|
||||
|
||||
// sort the edge in normally
|
||||
u_check = edge->u;
|
||||
if (edge->surfs[0])
|
||||
u_check++; // sort trailers after leaders
|
||||
|
||||
if (!sw32_newedges[v] || sw32_newedges[v]->u >= u_check) {
|
||||
edge->next = sw32_newedges[v];
|
||||
sw32_newedges[v] = edge;
|
||||
} else {
|
||||
pcheck = sw32_newedges[v];
|
||||
while (pcheck->next && pcheck->next->u < u_check)
|
||||
pcheck = pcheck->next;
|
||||
edge->next = pcheck->next;
|
||||
pcheck->next = edge;
|
||||
}
|
||||
|
||||
edge->nextremove = sw32_removeedges[v2];
|
||||
sw32_removeedges[v2] = edge;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
|
||||
{
|
||||
float d0, d1, f;
|
||||
mvertex_t clipvert;
|
||||
|
||||
if (clip) {
|
||||
do {
|
||||
d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
|
||||
d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
|
||||
|
||||
if (d0 >= 0) {
|
||||
// point 0 is unclipped
|
||||
if (d1 >= 0) {
|
||||
// both points are unclipped
|
||||
continue;
|
||||
}
|
||||
// only point 1 is clipped
|
||||
|
||||
// we don't cache clipped edges
|
||||
cacheoffset = 0x7FFFFFFF;
|
||||
|
||||
f = d0 / (d0 - d1);
|
||||
clipvert.position[0] = pv0->position[0] +
|
||||
f * (pv1->position[0] - pv0->position[0]);
|
||||
clipvert.position[1] = pv0->position[1] +
|
||||
f * (pv1->position[1] - pv0->position[1]);
|
||||
clipvert.position[2] = pv0->position[2] +
|
||||
f * (pv1->position[2] - pv0->position[2]);
|
||||
|
||||
if (clip->leftedge) {
|
||||
sw32_r_leftclipped = true;
|
||||
sw32_r_leftexit = clipvert;
|
||||
} else if (clip->rightedge) {
|
||||
sw32_r_rightclipped = true;
|
||||
sw32_r_rightexit = clipvert;
|
||||
}
|
||||
|
||||
sw32_R_ClipEdge (pv0, &clipvert, clip->next);
|
||||
return;
|
||||
} else {
|
||||
// point 0 is clipped
|
||||
if (d1 < 0) {
|
||||
// both points are clipped
|
||||
// we do cache fully clipped edges
|
||||
if (!sw32_r_leftclipped)
|
||||
cacheoffset = FULLY_CLIPPED_CACHED |
|
||||
(r_framecount & FRAMECOUNT_MASK);
|
||||
return;
|
||||
}
|
||||
// only point 0 is clipped
|
||||
sw32_r_lastvertvalid = false;
|
||||
|
||||
// we don't cache partially clipped edges
|
||||
cacheoffset = 0x7FFFFFFF;
|
||||
|
||||
f = d0 / (d0 - d1);
|
||||
clipvert.position[0] = pv0->position[0] +
|
||||
f * (pv1->position[0] - pv0->position[0]);
|
||||
clipvert.position[1] = pv0->position[1] +
|
||||
f * (pv1->position[1] - pv0->position[1]);
|
||||
clipvert.position[2] = pv0->position[2] +
|
||||
f * (pv1->position[2] - pv0->position[2]);
|
||||
|
||||
if (clip->leftedge) {
|
||||
sw32_r_leftclipped = true;
|
||||
sw32_r_leftenter = clipvert;
|
||||
} else if (clip->rightedge) {
|
||||
sw32_r_rightclipped = true;
|
||||
sw32_r_rightenter = clipvert;
|
||||
}
|
||||
|
||||
sw32_R_ClipEdge (&clipvert, pv1, clip->next);
|
||||
return;
|
||||
}
|
||||
} while ((clip = clip->next) != NULL);
|
||||
}
|
||||
// add the edge
|
||||
sw32_R_EmitEdge (pv0, pv1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
R_EmitCachedEdge (void)
|
||||
{
|
||||
edge_t *pedge_t;
|
||||
|
||||
pedge_t = (edge_t *) ((intptr_t) sw32_r_edges + sw32_r_pedge->cachededgeoffset);
|
||||
|
||||
if (!pedge_t->surfs[0])
|
||||
pedge_t->surfs[0] = sw32_surface_p - sw32_surfaces;
|
||||
else
|
||||
pedge_t->surfs[1] = sw32_surface_p - sw32_surfaces;
|
||||
|
||||
if (pedge_t->nearzi > sw32_r_nearzi) // for mipmap finding
|
||||
sw32_r_nearzi = pedge_t->nearzi;
|
||||
|
||||
sw32_r_emitted = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_RenderFace (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex;
|
||||
unsigned int mask;
|
||||
plane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
medge_t *pedges, tedge;
|
||||
clipplane_t *pclip;
|
||||
mod_brush_t *brush = ¤tentity->renderer.model->brush;
|
||||
|
||||
// skip out if no more surfs
|
||||
if ((sw32_surface_p) >= sw32_surf_max) {
|
||||
sw32_r_outofsurfaces++;
|
||||
return;
|
||||
}
|
||||
// ditto if not enough edges left, or switch to auxedges if possible
|
||||
if ((sw32_edge_p + fa->numedges + 4) >= sw32_edge_max) {
|
||||
sw32_r_outofedges += fa->numedges;
|
||||
return;
|
||||
}
|
||||
|
||||
sw32_c_faceclip++;
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1) {
|
||||
if (clipflags & mask) {
|
||||
sw32_view_clipplanes[i].next = pclip;
|
||||
pclip = &sw32_view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// push the edges through
|
||||
sw32_r_emitted = 0;
|
||||
sw32_r_nearzi = 0;
|
||||
sw32_r_nearzionly = false;
|
||||
makeleftedge = makerightedge = false;
|
||||
pedges = brush->edges;
|
||||
sw32_r_lastvertvalid = false;
|
||||
|
||||
for (i = 0; i < fa->numedges; i++) {
|
||||
lindex = brush->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0) {
|
||||
sw32_r_pedge = &pedges[lindex];
|
||||
|
||||
// if the edge is cached, we can just reuse the edge
|
||||
if (!insubmodel) {
|
||||
if (sw32_r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) {
|
||||
if ((sw32_r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
|
||||
(unsigned int) r_framecount) {
|
||||
sw32_r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((((uintptr_t) sw32_edge_p - (uintptr_t) sw32_r_edges) >
|
||||
sw32_r_pedge->cachededgeoffset) &&
|
||||
(((edge_t *) ((intptr_t) sw32_r_edges +
|
||||
sw32_r_pedge->cachededgeoffset))->owner ==
|
||||
sw32_r_pedge)) {
|
||||
R_EmitCachedEdge ();
|
||||
sw32_r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// assume it's cacheable
|
||||
cacheoffset = (byte *) sw32_edge_p - (byte *) sw32_r_edges;
|
||||
sw32_r_leftclipped = sw32_r_rightclipped = false;
|
||||
sw32_R_ClipEdge (&r_pcurrentvertbase[sw32_r_pedge->v[0]],
|
||||
&r_pcurrentvertbase[sw32_r_pedge->v[1]], pclip);
|
||||
sw32_r_pedge->cachededgeoffset = cacheoffset;
|
||||
|
||||
if (sw32_r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (sw32_r_rightclipped)
|
||||
makerightedge = true;
|
||||
sw32_r_lastvertvalid = true;
|
||||
} else {
|
||||
lindex = -lindex;
|
||||
sw32_r_pedge = &pedges[lindex];
|
||||
// if the edge is cached, we can just reuse the edge
|
||||
if (!insubmodel) {
|
||||
if (sw32_r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) {
|
||||
if ((sw32_r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
|
||||
(unsigned int) r_framecount) {
|
||||
sw32_r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// it's cached if the cached edge is valid and is owned
|
||||
// by this medge_t
|
||||
if ((((uintptr_t) sw32_edge_p - (uintptr_t) sw32_r_edges) >
|
||||
sw32_r_pedge->cachededgeoffset) &&
|
||||
(((edge_t *) ((intptr_t) sw32_r_edges +
|
||||
sw32_r_pedge->cachededgeoffset))->owner ==
|
||||
sw32_r_pedge)) {
|
||||
R_EmitCachedEdge ();
|
||||
sw32_r_lastvertvalid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// assume it's cacheable
|
||||
cacheoffset = (byte *) sw32_edge_p - (byte *) sw32_r_edges;
|
||||
sw32_r_leftclipped = sw32_r_rightclipped = false;
|
||||
sw32_R_ClipEdge (&r_pcurrentvertbase[sw32_r_pedge->v[1]],
|
||||
&r_pcurrentvertbase[sw32_r_pedge->v[0]], pclip);
|
||||
sw32_r_pedge->cachededgeoffset = cacheoffset;
|
||||
|
||||
if (sw32_r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (sw32_r_rightclipped)
|
||||
makerightedge = true;
|
||||
sw32_r_lastvertvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if there was a clip off the left edge, add that edge too
|
||||
// FIXME: faster to do in screen space?
|
||||
// FIXME: share clipped edges?
|
||||
if (makeleftedge) {
|
||||
sw32_r_pedge = &tedge;
|
||||
sw32_r_lastvertvalid = false;
|
||||
sw32_R_ClipEdge (&sw32_r_leftexit, &sw32_r_leftenter, pclip->next);
|
||||
}
|
||||
// if there was a clip off the right edge, get the right sw32_r_nearzi
|
||||
if (makerightedge) {
|
||||
sw32_r_pedge = &tedge;
|
||||
sw32_r_lastvertvalid = false;
|
||||
sw32_r_nearzionly = true;
|
||||
sw32_R_ClipEdge (&sw32_r_rightexit, &sw32_r_rightenter, sw32_view_clipplanes[1].next);
|
||||
}
|
||||
// if no edges made it out, return without posting the surface
|
||||
if (!sw32_r_emitted)
|
||||
return;
|
||||
|
||||
sw32_r_polycount++;
|
||||
|
||||
sw32_surface_p->data = (void *) fa;
|
||||
sw32_surface_p->nearzi = sw32_r_nearzi;
|
||||
sw32_surface_p->flags = fa->flags;
|
||||
sw32_surface_p->insubmodel = insubmodel;
|
||||
sw32_surface_p->spanstate = 0;
|
||||
sw32_surface_p->entity = currententity;
|
||||
sw32_surface_p->key = sw32_r_currentkey++;
|
||||
sw32_surface_p->spans = NULL;
|
||||
|
||||
pplane = fa->plane;
|
||||
// FIXME: cache this?
|
||||
sw32_TransformVector (pplane->normal, p_normal);
|
||||
// FIXME: cache this?
|
||||
distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
|
||||
distinv = min (distinv, 1.0);
|
||||
|
||||
sw32_surface_p->d_zistepu = p_normal[0] * sw32_xscaleinv * distinv;
|
||||
sw32_surface_p->d_zistepv = -p_normal[1] * sw32_yscaleinv * distinv;
|
||||
sw32_surface_p->d_ziorigin = p_normal[2] * distinv -
|
||||
sw32_xcenter * sw32_surface_p->d_zistepu - sw32_ycenter * sw32_surface_p->d_zistepv;
|
||||
|
||||
//JDC VectorCopy (r_worldmodelorg, sw32_surface_p->modelorg);
|
||||
sw32_surface_p++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
|
||||
{
|
||||
int i;
|
||||
unsigned int mask;
|
||||
plane_t *pplane;
|
||||
float distinv;
|
||||
vec3_t p_normal;
|
||||
medge_t tedge;
|
||||
clipplane_t *pclip;
|
||||
|
||||
// skip out if no more surfs
|
||||
if (sw32_surface_p >= sw32_surf_max) {
|
||||
sw32_r_outofsurfaces++;
|
||||
return;
|
||||
}
|
||||
// ditto if not enough edges left, or switch to auxedges if possible
|
||||
if ((sw32_edge_p + psurf->numedges + 4) >= sw32_edge_max) {
|
||||
sw32_r_outofedges += psurf->numedges;
|
||||
return;
|
||||
}
|
||||
|
||||
sw32_c_faceclip++;
|
||||
|
||||
// this is a dummy to give the caching mechanism someplace to write to
|
||||
sw32_r_pedge = &tedge;
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1) {
|
||||
if (sw32_r_clipflags & mask) {
|
||||
sw32_view_clipplanes[i].next = pclip;
|
||||
pclip = &sw32_view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// push the edges through
|
||||
sw32_r_emitted = 0;
|
||||
sw32_r_nearzi = 0;
|
||||
sw32_r_nearzionly = false;
|
||||
makeleftedge = makerightedge = false;
|
||||
// FIXME: keep clipped bmodel edges in clockwise order so last vertex
|
||||
// caching can be used?
|
||||
sw32_r_lastvertvalid = false;
|
||||
|
||||
for (; pedges; pedges = pedges->pnext) {
|
||||
sw32_r_leftclipped = sw32_r_rightclipped = false;
|
||||
sw32_R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
|
||||
|
||||
if (sw32_r_leftclipped)
|
||||
makeleftedge = true;
|
||||
if (sw32_r_rightclipped)
|
||||
makerightedge = true;
|
||||
}
|
||||
|
||||
// if there was a clip off the left edge, add that edge too
|
||||
// FIXME: faster to do in screen space?
|
||||
// FIXME: share clipped edges?
|
||||
if (makeleftedge) {
|
||||
sw32_r_pedge = &tedge;
|
||||
sw32_R_ClipEdge (&sw32_r_leftexit, &sw32_r_leftenter, pclip->next);
|
||||
}
|
||||
// if there was a clip off the right edge, get the right sw32_r_nearzi
|
||||
if (makerightedge) {
|
||||
sw32_r_pedge = &tedge;
|
||||
sw32_r_nearzionly = true;
|
||||
sw32_R_ClipEdge (&sw32_r_rightexit, &sw32_r_rightenter, sw32_view_clipplanes[1].next);
|
||||
}
|
||||
// if no edges made it out, return without posting the surface
|
||||
if (!sw32_r_emitted)
|
||||
return;
|
||||
|
||||
sw32_r_polycount++;
|
||||
|
||||
sw32_surface_p->data = (void *) psurf;
|
||||
sw32_surface_p->nearzi = sw32_r_nearzi;
|
||||
sw32_surface_p->flags = psurf->flags;
|
||||
sw32_surface_p->insubmodel = true;
|
||||
sw32_surface_p->spanstate = 0;
|
||||
sw32_surface_p->entity = currententity;
|
||||
sw32_surface_p->key = sw32_r_currentbkey;
|
||||
sw32_surface_p->spans = NULL;
|
||||
|
||||
pplane = psurf->plane;
|
||||
// FIXME: cache this?
|
||||
sw32_TransformVector (pplane->normal, p_normal);
|
||||
// FIXME: cache this?
|
||||
distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
|
||||
distinv = min (distinv, 1.0);
|
||||
|
||||
sw32_surface_p->d_zistepu = p_normal[0] * sw32_xscaleinv * distinv;
|
||||
sw32_surface_p->d_zistepv = -p_normal[1] * sw32_yscaleinv * distinv;
|
||||
sw32_surface_p->d_ziorigin = p_normal[2] * distinv -
|
||||
sw32_xcenter * sw32_surface_p->d_zistepu - sw32_ycenter * sw32_surface_p->d_zistepv;
|
||||
|
||||
//JDC VectorCopy (r_worldmodelorg, sw32_surface_p->modelorg);
|
||||
sw32_surface_p++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_RenderPoly (msurface_t *fa, int clipflags)
|
||||
{
|
||||
int i, lindex, lnumverts, s_axis, t_axis;
|
||||
float dist, lastdist, lzi, scale, u, v, frac;
|
||||
unsigned int mask;
|
||||
vec3_t local, transformed;
|
||||
clipplane_t *pclip;
|
||||
medge_t *pedges;
|
||||
plane_t *pplane;
|
||||
mvertex_t verts[2][100]; // FIXME: do real number
|
||||
polyvert_t pverts[100]; // FIXME: do real number, safely
|
||||
int vertpage, newverts, newpage, lastvert;
|
||||
qboolean visible;
|
||||
mod_brush_t *brush = ¤tentity->renderer.model->brush;
|
||||
|
||||
// FIXME: clean this up and make it faster
|
||||
// FIXME: guard against running out of vertices
|
||||
|
||||
s_axis = t_axis = 0; // keep compiler happy
|
||||
|
||||
// set up clip planes
|
||||
pclip = NULL;
|
||||
|
||||
for (i = 3, mask = 0x08; i >= 0; i--, mask >>= 1) {
|
||||
if (clipflags & mask) {
|
||||
sw32_view_clipplanes[i].next = pclip;
|
||||
pclip = &sw32_view_clipplanes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// reconstruct the polygon
|
||||
// FIXME: these should be precalculated and loaded off disk
|
||||
pedges = brush->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
for (i = 0; i < lnumverts; i++) {
|
||||
lindex = brush->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0) {
|
||||
sw32_r_pedge = &pedges[lindex];
|
||||
verts[0][i] = r_pcurrentvertbase[sw32_r_pedge->v[0]];
|
||||
} else {
|
||||
sw32_r_pedge = &pedges[-lindex];
|
||||
verts[0][i] = r_pcurrentvertbase[sw32_r_pedge->v[1]];
|
||||
}
|
||||
}
|
||||
|
||||
// clip the polygon, done if not visible
|
||||
while (pclip) {
|
||||
lastvert = lnumverts - 1;
|
||||
lastdist = DotProduct (verts[vertpage][lastvert].position,
|
||||
pclip->normal) - pclip->dist;
|
||||
|
||||
visible = false;
|
||||
newverts = 0;
|
||||
newpage = vertpage ^ 1;
|
||||
|
||||
for (i = 0; i < lnumverts; i++) {
|
||||
dist = DotProduct (verts[vertpage][i].position, pclip->normal) -
|
||||
pclip->dist;
|
||||
|
||||
if ((lastdist > 0) != (dist > 0)) {
|
||||
frac = dist / (dist - lastdist);
|
||||
verts[newpage][newverts].position[0] =
|
||||
verts[vertpage][i].position[0] +
|
||||
((verts[vertpage][lastvert].position[0] -
|
||||
verts[vertpage][i].position[0]) * frac);
|
||||
verts[newpage][newverts].position[1] =
|
||||
verts[vertpage][i].position[1] +
|
||||
((verts[vertpage][lastvert].position[1] -
|
||||
verts[vertpage][i].position[1]) * frac);
|
||||
verts[newpage][newverts].position[2] =
|
||||
verts[vertpage][i].position[2] +
|
||||
((verts[vertpage][lastvert].position[2] -
|
||||
verts[vertpage][i].position[2]) * frac);
|
||||
newverts++;
|
||||
}
|
||||
|
||||
if (dist >= 0) {
|
||||
verts[newpage][newverts] = verts[vertpage][i];
|
||||
newverts++;
|
||||
visible = true;
|
||||
}
|
||||
|
||||
lastvert = i;
|
||||
lastdist = dist;
|
||||
}
|
||||
|
||||
if (!visible || (newverts < 3))
|
||||
return;
|
||||
|
||||
lnumverts = newverts;
|
||||
vertpage ^= 1;
|
||||
pclip = pclip->next;
|
||||
}
|
||||
|
||||
// transform and project, remembering the z values at the vertices and
|
||||
// sw32_r_nearzi, and extract the s and t coordinates at the vertices
|
||||
pplane = fa->plane;
|
||||
switch (pplane->type) {
|
||||
case PLANE_X:
|
||||
case PLANE_ANYX:
|
||||
s_axis = 1;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
case PLANE_ANYY:
|
||||
s_axis = 0;
|
||||
t_axis = 2;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
case PLANE_ANYZ:
|
||||
s_axis = 0;
|
||||
t_axis = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
sw32_r_nearzi = 0;
|
||||
|
||||
for (i = 0; i < lnumverts; i++) {
|
||||
// transform and project
|
||||
VectorSubtract (verts[vertpage][i].position, modelorg, local);
|
||||
sw32_TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
lzi = 1.0 / transformed[2];
|
||||
|
||||
if (lzi > sw32_r_nearzi) // for mipmap finding
|
||||
sw32_r_nearzi = lzi;
|
||||
|
||||
// FIXME: build x/sw32_yscale into transform?
|
||||
scale = sw32_xscale * lzi;
|
||||
u = (sw32_xcenter + scale * transformed[0]);
|
||||
if (u < r_refdef.fvrectx_adj)
|
||||
u = r_refdef.fvrectx_adj;
|
||||
if (u > r_refdef.fvrectright_adj)
|
||||
u = r_refdef.fvrectright_adj;
|
||||
|
||||
scale = sw32_yscale * lzi;
|
||||
v = (sw32_ycenter - scale * transformed[1]);
|
||||
if (v < r_refdef.fvrecty_adj)
|
||||
v = r_refdef.fvrecty_adj;
|
||||
if (v > r_refdef.fvrectbottom_adj)
|
||||
v = r_refdef.fvrectbottom_adj;
|
||||
|
||||
pverts[i].u = u;
|
||||
pverts[i].v = v;
|
||||
pverts[i].zi = lzi;
|
||||
pverts[i].s = verts[vertpage][i].position[s_axis];
|
||||
pverts[i].t = verts[vertpage][i].position[t_axis];
|
||||
}
|
||||
|
||||
// build the polygon descriptor, including fa, sw32_r_nearzi, and u, v, s, t,
|
||||
// and z for each vertex
|
||||
r_polydesc.numverts = lnumverts;
|
||||
r_polydesc.nearzi = sw32_r_nearzi;
|
||||
r_polydesc.pcurrentface = fa;
|
||||
r_polydesc.pverts = pverts;
|
||||
|
||||
// draw the polygon
|
||||
sw32_D_DrawPoly ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_ZDrawSubmodelPolys (model_t *model)
|
||||
{
|
||||
int i, numsurfaces;
|
||||
msurface_t *psurf;
|
||||
float dot;
|
||||
plane_t *pplane;
|
||||
mod_brush_t *brush = &model->brush;
|
||||
|
||||
psurf = &brush->surfaces[brush->firstmodelsurface];
|
||||
numsurfaces = brush->nummodelsurfaces;
|
||||
|
||||
for (i = 0; i < numsurfaces; i++, psurf++) {
|
||||
// find which side of the node we are on
|
||||
pplane = psurf->plane;
|
||||
|
||||
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
|
||||
|
||||
// draw the polygon
|
||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
|
||||
// FIXME: use bounding-box-based frustum clipping info?
|
||||
sw32_R_RenderPoly (psurf, 15);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,544 +0,0 @@
|
|||
/*
|
||||
sw32_redge.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sound.h"
|
||||
|
||||
#include "d_ifacea.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
||||
/*
|
||||
FIXME
|
||||
the complex cases add new polys on most lines, so dont optimize for
|
||||
keeping them the same have multiple free span lists to try to get better
|
||||
coherence ? low depth complexity-- 1 to 3 or so this breaks spans at every
|
||||
edge, even hidden ones (bad)
|
||||
|
||||
have a sentinal at both ends?
|
||||
*/
|
||||
|
||||
edge_t *sw32_auxedges;
|
||||
edge_t *sw32_r_edges, *sw32_edge_p, *sw32_edge_max;
|
||||
|
||||
surf_t *sw32_surfaces, *sw32_surface_p, *sw32_surf_max;
|
||||
|
||||
/*
|
||||
surfaces are generated in back to front order by the bsp, so if a surf
|
||||
pointer is greater than another one, it should be drawn in front
|
||||
sw32_surfaces[1] is the background, and is used as the active surface stack
|
||||
*/
|
||||
|
||||
edge_t *sw32_newedges[MAXHEIGHT];
|
||||
edge_t *sw32_removeedges[MAXHEIGHT];
|
||||
|
||||
static espan_t *span_p, *max_span_p;
|
||||
|
||||
int sw32_r_currentkey;
|
||||
|
||||
|
||||
static int current_iv;
|
||||
|
||||
static int edge_head_u_shift20, edge_tail_u_shift20;
|
||||
|
||||
static void (*pdrawfunc) (void);
|
||||
|
||||
static edge_t edge_head;
|
||||
static edge_t edge_tail;
|
||||
static edge_t edge_aftertail;
|
||||
static edge_t edge_sentinel;
|
||||
|
||||
static float fv;
|
||||
|
||||
static void
|
||||
R_DrawCulledPolys (void)
|
||||
{
|
||||
surf_t *s;
|
||||
msurface_t *pface;
|
||||
|
||||
currententity = &r_worldentity;
|
||||
|
||||
if (sw32_r_worldpolysbacktofront) {
|
||||
for (s = sw32_surface_p - 1; s > &sw32_surfaces[1]; s--) {
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
if (!(s->flags & SURF_DRAWBACKGROUND)) {
|
||||
pface = (msurface_t *) s->data;
|
||||
sw32_R_RenderPoly (pface, 15);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (s = &sw32_surfaces[1]; s < sw32_surface_p; s++) {
|
||||
if (!s->spans)
|
||||
continue;
|
||||
|
||||
if (!(s->flags & SURF_DRAWBACKGROUND)) {
|
||||
pface = (msurface_t *) s->data;
|
||||
sw32_R_RenderPoly (pface, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_BeginEdgeFrame (void)
|
||||
{
|
||||
int v;
|
||||
|
||||
sw32_edge_p = sw32_r_edges;
|
||||
sw32_edge_max = &sw32_r_edges[sw32_r_numallocatededges];
|
||||
|
||||
sw32_surface_p = &sw32_surfaces[2]; // background is surface 1,
|
||||
// surface 0 is a dummy
|
||||
sw32_surfaces[1].spans = NULL; // no background spans yet
|
||||
sw32_surfaces[1].flags = SURF_DRAWBACKGROUND;
|
||||
|
||||
// put the background behind everything in the world
|
||||
pdrawfunc = sw32_R_GenerateSpans;
|
||||
sw32_surfaces[1].key = 0x7FFFFFFF;
|
||||
sw32_r_currentkey = 0;
|
||||
|
||||
// FIXME: set with memset
|
||||
for (v = r_refdef.vrect.y; v < r_refdef.vrectbottom; v++) {
|
||||
sw32_newedges[v] = sw32_removeedges[v] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
sw32_R_InsertNewEdges
|
||||
|
||||
Adds the edges in the linked list edgestoadd, adding them to the edges
|
||||
in the linked list edgelist. edgestoadd is assumed to be sorted on u,
|
||||
and non-empty (this is actually sw32_newedges[v]). edgelist is assumed to
|
||||
be sorted on u, with a sentinel at the end (actually, this is the
|
||||
active edge table starting at edge_head.next).
|
||||
*/
|
||||
void
|
||||
sw32_R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
|
||||
{
|
||||
edge_t *next_edge;
|
||||
|
||||
do {
|
||||
next_edge = edgestoadd->next;
|
||||
edgesearch:
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist = edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist = edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist = edgelist->next;
|
||||
if (edgelist->u >= edgestoadd->u)
|
||||
goto addedge;
|
||||
edgelist = edgelist->next;
|
||||
goto edgesearch;
|
||||
|
||||
// insert edgestoadd before edgelist
|
||||
addedge:
|
||||
edgestoadd->next = edgelist;
|
||||
edgestoadd->prev = edgelist->prev;
|
||||
edgelist->prev->next = edgestoadd;
|
||||
edgelist->prev = edgestoadd;
|
||||
} while ((edgestoadd = next_edge) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_RemoveEdges (edge_t *pedge)
|
||||
{
|
||||
|
||||
do {
|
||||
pedge->next->prev = pedge->prev;
|
||||
pedge->prev->next = pedge->next;
|
||||
} while ((pedge = pedge->nextremove) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_StepActiveU (edge_t *pedge)
|
||||
{
|
||||
edge_t *pnext_edge, *pwedge;
|
||||
|
||||
while (1) {
|
||||
nextedge:
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
pedge->u += pedge->u_step;
|
||||
if (pedge->u < pedge->prev->u)
|
||||
goto pushback;
|
||||
pedge = pedge->next;
|
||||
|
||||
goto nextedge;
|
||||
|
||||
pushback:
|
||||
if (pedge == &edge_aftertail)
|
||||
return;
|
||||
|
||||
// push it back to keep it sorted
|
||||
pnext_edge = pedge->next;
|
||||
|
||||
// pull the edge out of the edge list
|
||||
pedge->next->prev = pedge->prev;
|
||||
pedge->prev->next = pedge->next;
|
||||
|
||||
// find out where the edge goes in the edge list
|
||||
pwedge = pedge->prev->prev;
|
||||
|
||||
while (pwedge->u > pedge->u) {
|
||||
pwedge = pwedge->prev;
|
||||
}
|
||||
|
||||
// put the edge back into the edge list
|
||||
pedge->next = pwedge->next;
|
||||
pedge->prev = pwedge;
|
||||
pedge->next->prev = pedge;
|
||||
pwedge->next = pedge;
|
||||
|
||||
pedge = pnext_edge;
|
||||
if (pedge == &edge_tail)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_CleanupSpan (void)
|
||||
{
|
||||
surf_t *surf;
|
||||
int iu;
|
||||
espan_t *span;
|
||||
|
||||
// now that we've reached the right edge of the screen, we're done with any
|
||||
// unfinished surfaces, so emit a span for whatever's on top
|
||||
surf = sw32_surfaces[1].next;
|
||||
iu = edge_tail_u_shift20;
|
||||
if (iu > surf->last_u) {
|
||||
span = span_p++;
|
||||
span->u = surf->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf->spans;
|
||||
surf->spans = span;
|
||||
}
|
||||
// reset spanstate for all surfaces in the surface stack
|
||||
do {
|
||||
surf->spanstate = 0;
|
||||
surf = surf->next;
|
||||
} while (surf != &sw32_surfaces[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
R_TrailingEdge (surf_t *surf, edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
int iu;
|
||||
|
||||
// don't generate a span if this is an inverted span, with the end edge
|
||||
// preceding the start edge (that is, we haven't seen the start edge yet)
|
||||
if (--surf->spanstate == 0) {
|
||||
if (surf == sw32_surfaces[1].next) {
|
||||
// emit a span (current top going away)
|
||||
iu = edge->u >> 20;
|
||||
if (iu > surf->last_u) {
|
||||
span = span_p++;
|
||||
span->u = surf->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf->spans;
|
||||
surf->spans = span;
|
||||
}
|
||||
// set last_u on the surface below
|
||||
surf->next->last_u = iu;
|
||||
}
|
||||
|
||||
surf->prev->next = surf->next;
|
||||
surf->next->prev = surf->prev;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_LeadingEdge (edge_t *edge)
|
||||
{
|
||||
espan_t *span;
|
||||
surf_t *surf, *surf2;
|
||||
int iu;
|
||||
double fu, newzi, testzi, newzitop, newzibottom;
|
||||
|
||||
if (edge->surfs[1]) {
|
||||
// it's adding a new surface in, so find the correct place
|
||||
surf = &sw32_surfaces[edge->surfs[1]];
|
||||
|
||||
// don't start a span if this is an inverted span, with the end edge
|
||||
// preceding the start edge (that is, we've already seen the end edge)
|
||||
if (++surf->spanstate == 1) {
|
||||
surf2 = sw32_surfaces[1].next;
|
||||
|
||||
if (surf->key < surf2->key)
|
||||
goto newtop;
|
||||
|
||||
// if it's two surfaces on the same plane, the one that's already
|
||||
// active is in front, so keep going unless it's a bmodel
|
||||
if (surf->insubmodel && (surf->key == surf2->key)) {
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float) (edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv * surf->d_zistepv +
|
||||
fu * surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv * surf2->d_zistepv +
|
||||
fu * surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi) {
|
||||
goto newtop;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi) {
|
||||
if (surf->d_zistepu >= surf2->d_zistepu) {
|
||||
goto newtop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue_search:
|
||||
|
||||
do {
|
||||
surf2 = surf2->next;
|
||||
} while (surf->key > surf2->key);
|
||||
|
||||
if (surf->key == surf2->key) {
|
||||
// if it's two surfaces on the same plane, the already active
|
||||
// one is in front, so keep going unless it's a bmodel
|
||||
if (!surf->insubmodel)
|
||||
goto continue_search;
|
||||
|
||||
// must be two bmodels in the same leaf; sort on 1/z
|
||||
fu = (float) (edge->u - 0xFFFFF) * (1.0 / 0x100000);
|
||||
newzi = surf->d_ziorigin + fv * surf->d_zistepv +
|
||||
fu * surf->d_zistepu;
|
||||
newzibottom = newzi * 0.99;
|
||||
|
||||
testzi = surf2->d_ziorigin + fv * surf2->d_zistepv +
|
||||
fu * surf2->d_zistepu;
|
||||
|
||||
if (newzibottom >= testzi) {
|
||||
goto gotposition;
|
||||
}
|
||||
|
||||
newzitop = newzi * 1.01;
|
||||
if (newzitop >= testzi) {
|
||||
if (surf->d_zistepu >= surf2->d_zistepu) {
|
||||
goto gotposition;
|
||||
}
|
||||
}
|
||||
|
||||
goto continue_search;
|
||||
}
|
||||
|
||||
goto gotposition;
|
||||
|
||||
newtop:
|
||||
// emit a span (obscures current top)
|
||||
iu = edge->u >> 20;
|
||||
|
||||
if (iu > surf2->last_u) {
|
||||
span = span_p++;
|
||||
span->u = surf2->last_u;
|
||||
span->count = iu - span->u;
|
||||
span->v = current_iv;
|
||||
span->pnext = surf2->spans;
|
||||
surf2->spans = span;
|
||||
}
|
||||
// set last_u on the new span
|
||||
surf->last_u = iu;
|
||||
|
||||
gotposition:
|
||||
// insert before surf2
|
||||
surf->next = surf2;
|
||||
surf->prev = surf2->prev;
|
||||
surf2->prev->next = surf;
|
||||
surf2->prev = surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_GenerateSpans (void)
|
||||
{
|
||||
edge_t *edge;
|
||||
surf_t *surf;
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
sw32_surfaces[1].next = sw32_surfaces[1].prev = &sw32_surfaces[1];
|
||||
sw32_surfaces[1].last_u = edge_head_u_shift20;
|
||||
|
||||
// generate spans
|
||||
for (edge = edge_head.next; edge != &edge_tail; edge = edge->next) {
|
||||
if (edge->surfs[0]) {
|
||||
// it has a left surface, so a surface is going away for this span
|
||||
surf = &sw32_surfaces[edge->surfs[0]];
|
||||
|
||||
R_TrailingEdge (surf, edge);
|
||||
|
||||
if (!edge->surfs[1])
|
||||
continue;
|
||||
}
|
||||
|
||||
R_LeadingEdge (edge);
|
||||
}
|
||||
|
||||
R_CleanupSpan ();
|
||||
}
|
||||
|
||||
/*
|
||||
R_ScanEdges
|
||||
|
||||
Input:
|
||||
sw32_newedges[] array
|
||||
this has links to edges, which have links to surfaces
|
||||
|
||||
Output:
|
||||
Each surface has a linked list of its visible spans
|
||||
*/
|
||||
void
|
||||
sw32_R_ScanEdges (void)
|
||||
{
|
||||
int iv, bottom;
|
||||
byte basespans[MAXSPANS * sizeof (espan_t) + CACHE_SIZE];
|
||||
espan_t *basespan_p;
|
||||
surf_t *s;
|
||||
|
||||
basespan_p = (espan_t *)
|
||||
((intptr_t) (basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
|
||||
|
||||
span_p = basespan_p;
|
||||
|
||||
// clear active edges to just the background edges around the whole screen
|
||||
// FIXME: most of this needs to be set up only once
|
||||
edge_head.u = r_refdef.vrect.x << 20;
|
||||
edge_head_u_shift20 = edge_head.u >> 20;
|
||||
edge_head.u_step = 0;
|
||||
edge_head.prev = NULL;
|
||||
edge_head.next = &edge_tail;
|
||||
edge_head.surfs[0] = 0;
|
||||
edge_head.surfs[1] = 1;
|
||||
|
||||
edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
|
||||
edge_tail_u_shift20 = edge_tail.u >> 20;
|
||||
edge_tail.u_step = 0;
|
||||
edge_tail.prev = &edge_head;
|
||||
edge_tail.next = &edge_aftertail;
|
||||
edge_tail.surfs[0] = 1;
|
||||
edge_tail.surfs[1] = 0;
|
||||
|
||||
edge_aftertail.u = -1; // force a move
|
||||
edge_aftertail.u_step = 0;
|
||||
edge_aftertail.next = &edge_sentinel;
|
||||
edge_aftertail.prev = &edge_tail;
|
||||
|
||||
// FIXME: do we need this now that we clamp x in r_draw.c?
|
||||
edge_sentinel.u = 32767 << 16; // make sure nothing sorts past this
|
||||
edge_sentinel.prev = &edge_aftertail;
|
||||
|
||||
// process all scan lines
|
||||
bottom = r_refdef.vrectbottom - 1;
|
||||
|
||||
for (iv = r_refdef.vrect.y; iv < bottom; iv++) {
|
||||
current_iv = iv;
|
||||
fv = (float) iv;
|
||||
|
||||
// mark that the head (background start) span is pre-included
|
||||
sw32_surfaces[1].spanstate = 1;
|
||||
|
||||
if (sw32_newedges[iv]) {
|
||||
sw32_R_InsertNewEdges (sw32_newedges[iv], edge_head.next);
|
||||
}
|
||||
|
||||
(*pdrawfunc) ();
|
||||
|
||||
// flush the span list if we can't be sure we have enough spans left
|
||||
// for the next scan
|
||||
if (span_p > max_span_p) {
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
|
||||
if (sw32_r_drawculledpolys)
|
||||
R_DrawCulledPolys ();
|
||||
else
|
||||
sw32_D_DrawSurfaces ();
|
||||
|
||||
// clear the surface span pointers
|
||||
for (s = &sw32_surfaces[1]; s < sw32_surface_p; s++)
|
||||
s->spans = NULL;
|
||||
|
||||
span_p = basespan_p;
|
||||
}
|
||||
|
||||
if (sw32_removeedges[iv])
|
||||
sw32_R_RemoveEdges (sw32_removeedges[iv]);
|
||||
|
||||
if (edge_head.next != &edge_tail)
|
||||
sw32_R_StepActiveU (edge_head.next);
|
||||
}
|
||||
|
||||
// do the last scan (no need to step or sort or remove on the last scan)
|
||||
current_iv = iv;
|
||||
fv = (float) iv;
|
||||
|
||||
// mark that the head (background start) span is pre-included
|
||||
sw32_surfaces[1].spanstate = 1;
|
||||
|
||||
if (sw32_newedges[iv])
|
||||
sw32_R_InsertNewEdges (sw32_newedges[iv], edge_head.next);
|
||||
|
||||
(*pdrawfunc) ();
|
||||
|
||||
// draw whatever's left in the span list
|
||||
if (sw32_r_drawculledpolys)
|
||||
R_DrawCulledPolys ();
|
||||
else
|
||||
sw32_D_DrawSurfaces ();
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
/*
|
||||
sw32_riqm.c
|
||||
|
||||
32bit SW IQM rendering
|
||||
|
||||
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2012/5/18
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#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>
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/image.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/skin.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "d_ifacea.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
#define LIGHT_MIN 5 // lowest light value we'll allow, to
|
||||
// avoid the need for inner-loop light
|
||||
// clamping
|
||||
|
||||
static vec3_t r_plightvec;
|
||||
static int r_ambientlight;
|
||||
static float r_shadelight;
|
||||
|
||||
static inline int
|
||||
calc_light (float *normal)
|
||||
{
|
||||
float lightcos = DotProduct (normal, r_plightvec);
|
||||
int temp = r_ambientlight;
|
||||
|
||||
if (lightcos < 0) {
|
||||
temp += (int) (r_shadelight * lightcos);
|
||||
|
||||
// clamp; because we limited the minimum ambient and shading
|
||||
// light, we don't have to clamp low light, just bright
|
||||
if (temp < 0)
|
||||
temp = 0;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void
|
||||
R_IQMTransformAndProjectFinalVerts (iqm_t *iqm, swiqm_t *sw, iqmframe_t *frame)
|
||||
{
|
||||
finalvert_t *fv = pfinalverts;
|
||||
float zi;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iqm->num_verts; i++, fv++) {
|
||||
byte *vert = iqm->vertices + i * iqm->stride;
|
||||
uint32_t bind = *(uint32_t *) (vert + sw->bindices->offset);
|
||||
vec_t *mat = (vec_t *) &frame[bind];
|
||||
float *position = (float *) (vert + sw->position->offset);
|
||||
float *normal = (float *) (vert + sw->normal->offset);
|
||||
int32_t *texcoord = (int32_t *) (vert + sw->texcoord->offset);
|
||||
vec3_t tv, tn;
|
||||
Mat4MultVec (mat, position, tv);
|
||||
Mat4as3MultVec (mat, normal, tn);
|
||||
zi = 1.0 / (DotProduct (tv, sw32_aliastransform[2])
|
||||
+ sw32_aliastransform[2][3]);
|
||||
fv->v[5] = zi;
|
||||
fv->v[0] = (DotProduct (tv, sw32_aliastransform[0])
|
||||
+ sw32_aliastransform[0][3]) * zi + aliasxcenter;
|
||||
fv->v[1] = (DotProduct (tv, sw32_aliastransform[1])
|
||||
+ sw32_aliastransform[1][3]) * zi + aliasxcenter;
|
||||
fv->v[2] = texcoord[0];
|
||||
fv->v[3] = texcoord[1];
|
||||
fv->v[4] = calc_light (tn);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iqm_setup_skin (swiqm_t *sw, int skinnum)
|
||||
{
|
||||
tex_t *skin = sw->skins[skinnum];
|
||||
|
||||
sw32_r_affinetridesc.pskin = skin->data;
|
||||
sw32_r_affinetridesc.skinwidth = skin->width;
|
||||
sw32_r_affinetridesc.skinheight = skin->height;
|
||||
sw32_r_affinetridesc.seamfixupX16 = (skin->width >> 1) << 16;
|
||||
}
|
||||
|
||||
static void
|
||||
R_IQMPrepareUnclippedPoints (iqm_t *iqm, swiqm_t *sw, iqmframe_t *frame)
|
||||
{
|
||||
int i;
|
||||
|
||||
R_IQMTransformAndProjectFinalVerts (iqm, sw, frame);
|
||||
|
||||
sw32_r_affinetridesc.pfinalverts = pfinalverts;
|
||||
for (i = 0; i < iqm->num_meshes; i++) {
|
||||
iqmmesh *mesh = &iqm->meshes[i];
|
||||
uint16_t *tris;
|
||||
|
||||
iqm_setup_skin (sw, i);
|
||||
|
||||
tris = iqm->elements + mesh->first_triangle;
|
||||
sw32_r_affinetridesc.ptriangles = (mtriangle_t *) tris;
|
||||
sw32_r_affinetridesc.numtriangles = mesh->num_triangles;
|
||||
sw32_D_PolysetDraw ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_IQMPreparePoints (iqm_t *iqm, swiqm_t *sw, iqmframe_t *frame)
|
||||
{
|
||||
finalvert_t *fv = pfinalverts;
|
||||
auxvert_t *av = pauxverts;
|
||||
int i;
|
||||
uint32_t j;
|
||||
finalvert_t *pfv[3];
|
||||
|
||||
for (i = 0; i < iqm->num_verts; i++, fv++, av++) {
|
||||
byte *vert = iqm->vertices + i * iqm->stride;
|
||||
uint32_t bind = *(uint32_t *) (vert + sw->bindices->offset);
|
||||
vec_t *mat = (vec_t *) &frame[bind];
|
||||
float *position = (float *) (vert + sw->position->offset);
|
||||
float *normal = (float *) (vert + sw->normal->offset);
|
||||
int32_t *texcoord = (int32_t *) (vert + sw->texcoord->offset);
|
||||
vec3_t tv, tn;
|
||||
Mat4MultVec (mat, position, tv);
|
||||
Mat4as3MultVec (mat, normal, tn);
|
||||
av->fv[0] = DotProduct (tv, sw32_aliastransform[0])
|
||||
+ sw32_aliastransform[0][3];
|
||||
av->fv[1] = DotProduct (tv, sw32_aliastransform[1])
|
||||
+ sw32_aliastransform[1][3];
|
||||
av->fv[2] = DotProduct (tv, sw32_aliastransform[2])
|
||||
+ sw32_aliastransform[2][3];
|
||||
fv->v[2] = texcoord[0];
|
||||
fv->v[3] = texcoord[1];
|
||||
fv->flags = 0;
|
||||
fv->v[4] = calc_light (tn);
|
||||
sw32_R_AliasClipAndProjectFinalVert (fv, av);
|
||||
}
|
||||
|
||||
for (i = 0; i < iqm->num_meshes; i++) {
|
||||
iqmmesh *mesh = &iqm->meshes[i];
|
||||
mtriangle_t *mtri;
|
||||
|
||||
iqm_setup_skin (sw, i);
|
||||
|
||||
mtri = (mtriangle_t *) iqm->elements + mesh->first_triangle;
|
||||
sw32_r_affinetridesc.numtriangles = 1;
|
||||
for (j = 0; j < mesh->num_triangles; j++, mtri++) {
|
||||
pfv[0] = &pfinalverts[mtri->vertindex[0]];
|
||||
pfv[1] = &pfinalverts[mtri->vertindex[1]];
|
||||
pfv[2] = &pfinalverts[mtri->vertindex[2]];
|
||||
|
||||
if (pfv[0]->flags & pfv[1]->flags & pfv[2]->flags
|
||||
& (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP))
|
||||
continue; // completely clipped
|
||||
|
||||
if (!((pfv[0]->flags | pfv[1]->flags | pfv[2]->flags)
|
||||
& (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP))) {// totally unclipped
|
||||
sw32_r_affinetridesc.pfinalverts = pfinalverts;
|
||||
sw32_r_affinetridesc.ptriangles = mtri;
|
||||
sw32_D_PolysetDraw ();
|
||||
} else { // partially clipped
|
||||
sw32_R_AliasClipTriangle (mtri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_IQMSetupLighting (entity_t *ent, alight_t *plighting)
|
||||
{
|
||||
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't
|
||||
// have to clamp off the bottom
|
||||
r_ambientlight = plighting->ambientlight;
|
||||
|
||||
if (r_ambientlight < LIGHT_MIN)
|
||||
r_ambientlight = LIGHT_MIN;
|
||||
|
||||
r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
|
||||
|
||||
if (r_ambientlight < LIGHT_MIN)
|
||||
r_ambientlight = LIGHT_MIN;
|
||||
|
||||
r_shadelight = plighting->shadelight;
|
||||
|
||||
if (r_shadelight < 0)
|
||||
r_shadelight = 0;
|
||||
|
||||
r_shadelight *= VID_GRADES;
|
||||
|
||||
// rotate the lighting vector into the model's frame of reference
|
||||
mat4f_t mat;
|
||||
Transform_GetWorldMatrix (ent->transform, mat);
|
||||
//FIXME vectorize
|
||||
r_plightvec[0] = DotProduct (plighting->plightvec, mat[0]);
|
||||
r_plightvec[1] = DotProduct (plighting->plightvec, mat[1]);
|
||||
r_plightvec[2] = DotProduct (plighting->plightvec, mat[2]);
|
||||
}
|
||||
|
||||
static void
|
||||
R_IQMSetUpTransform (int trivial_accept)
|
||||
{
|
||||
int i;
|
||||
float rotationmatrix[3][4];
|
||||
static float viewmatrix[3][4];
|
||||
vec3_t forward, left, up;
|
||||
|
||||
mat4f_t mat;
|
||||
Transform_GetWorldMatrix (currententity->transform, mat);
|
||||
VectorCopy (mat[0], forward);
|
||||
VectorCopy (mat[1], left);
|
||||
VectorCopy (mat[2], up);
|
||||
|
||||
// TODO: can do this with simple matrix rearrangement
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
rotationmatrix[i][0] = forward[i];
|
||||
rotationmatrix[i][1] = left[i];
|
||||
rotationmatrix[i][2] = up[i];
|
||||
}
|
||||
|
||||
rotationmatrix[0][3] = -modelorg[0];
|
||||
rotationmatrix[1][3] = -modelorg[1];
|
||||
rotationmatrix[2][3] = -modelorg[2];
|
||||
|
||||
// TODO: should be global, set when vright, etc., set
|
||||
VectorCopy (vright, viewmatrix[0]);
|
||||
VectorCopy (vup, viewmatrix[1]);
|
||||
VectorNegate (viewmatrix[1], viewmatrix[1]);
|
||||
VectorCopy (vpn, viewmatrix[2]);
|
||||
|
||||
// viewmatrix[0][3] = 0;
|
||||
// viewmatrix[1][3] = 0;
|
||||
// viewmatrix[2][3] = 0;
|
||||
|
||||
R_ConcatTransforms (viewmatrix, rotationmatrix, sw32_aliastransform);
|
||||
|
||||
// do the scaling up of x and y to screen coordinates as part of the transform
|
||||
// for the unclipped case (it would mess up clipping in the clipped case).
|
||||
// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y
|
||||
// correspondingly so the projected x and y come out right
|
||||
// FIXME: make this work for clipped case too?
|
||||
|
||||
if (trivial_accept) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
sw32_aliastransform[0][i] *= aliasxscale *
|
||||
(1.0 / ((float) 0x8000 * 0x10000));
|
||||
sw32_aliastransform[1][i] *= aliasyscale *
|
||||
(1.0 / ((float) 0x8000 * 0x10000));
|
||||
sw32_aliastransform[2][i] *= 1.0 / ((float) 0x8000 * 0x10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_IQMDrawModel (alight_t *plighting)
|
||||
{
|
||||
entity_t *ent = currententity;
|
||||
model_t *model = ent->renderer.model;
|
||||
iqm_t *iqm = (iqm_t *) model->aliashdr;
|
||||
swiqm_t *sw = (swiqm_t *) iqm->extra_data;
|
||||
int size;
|
||||
float blend;
|
||||
iqmframe_t *frame;
|
||||
|
||||
size = (CACHE_SIZE - 1)
|
||||
+ sizeof (finalvert_t) * (iqm->num_verts + 1)
|
||||
+ sizeof (auxvert_t) * iqm->num_verts;
|
||||
blend = R_IQMGetLerpedFrames (ent, iqm);
|
||||
frame = R_IQMBlendPalette (iqm, ent->animation.pose1, ent->animation.pose2,
|
||||
blend, size,
|
||||
sw->blend_palette, sw->palette_size);
|
||||
|
||||
pfinalverts = (finalvert_t *) &frame[sw->palette_size];
|
||||
pfinalverts = (finalvert_t *)
|
||||
(((intptr_t) &pfinalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
pauxverts = (auxvert_t *) &pfinalverts[iqm->num_verts + 1];
|
||||
|
||||
R_IQMSetUpTransform (ent->visibility.trivial_accept);
|
||||
|
||||
R_IQMSetupLighting (ent, plighting);
|
||||
|
||||
//if (!sw32_acolormap)
|
||||
sw32_acolormap = vid.colormap8;
|
||||
|
||||
if (ent != vr_data.view_model)
|
||||
sw32_ziscale = (float) 0x8000 *(float) 0x10000;
|
||||
else
|
||||
sw32_ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
|
||||
|
||||
if (ent->visibility.trivial_accept)
|
||||
R_IQMPrepareUnclippedPoints (iqm, sw, frame);
|
||||
else
|
||||
R_IQMPreparePoints (iqm, sw, frame);
|
||||
}
|
|
@ -1,877 +0,0 @@
|
|||
/*
|
||||
sw32_rmain.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/screen.h"
|
||||
#include "QF/sound.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
||||
//define PASSAGES
|
||||
|
||||
static vec3_t viewlightvec;
|
||||
static alight_t r_viewlighting = { 128, 192, viewlightvec };
|
||||
int sw32_r_numallocatededges;
|
||||
qboolean sw32_r_drawpolys;
|
||||
qboolean sw32_r_drawculledpolys;
|
||||
qboolean sw32_r_worldpolysbacktofront;
|
||||
float sw32_r_aliasuvscale = 1.0;
|
||||
int sw32_r_outofsurfaces;
|
||||
int sw32_r_outofedges;
|
||||
|
||||
qboolean sw32_r_dowarp, sw32_r_dowarpold, sw32_r_viewchanged;
|
||||
|
||||
int sw32_c_surf;
|
||||
int sw32_r_maxsurfsseen, sw32_r_maxedgesseen;
|
||||
static int r_cnumsurfs;
|
||||
static qboolean r_surfsonstack;
|
||||
int sw32_r_clipflags;
|
||||
|
||||
byte *sw32_r_warpbuffer;
|
||||
|
||||
static byte *r_stack_start;
|
||||
|
||||
// screen size info
|
||||
float sw32_xcenter, sw32_ycenter;
|
||||
float sw32_xscale, sw32_yscale;
|
||||
float sw32_xscaleinv, sw32_yscaleinv;
|
||||
float sw32_xscaleshrink, sw32_yscaleshrink;
|
||||
float sw32_aliasxscale, sw32_aliasyscale, sw32_aliasxcenter, sw32_aliasycenter;
|
||||
|
||||
int sw32_screenwidth;
|
||||
|
||||
float sw32_pixelAspect;
|
||||
static float screenAspect;
|
||||
static float verticalFieldOfView;
|
||||
static float xOrigin, yOrigin;
|
||||
|
||||
plane_t sw32_screenedge[4];
|
||||
|
||||
// refresh flags
|
||||
int sw32_r_polycount;
|
||||
int sw32_r_drawnpolycount;
|
||||
|
||||
int *sw32_pfrustum_indexes[4];
|
||||
int sw32_r_frustum_indexes[4 * 6];
|
||||
|
||||
float sw32_r_aliastransition, sw32_r_resfudge;
|
||||
|
||||
static float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
|
||||
static float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
|
||||
|
||||
void
|
||||
sw32_R_Textures_Init (void)
|
||||
{
|
||||
int x, y, m;
|
||||
byte *dest;
|
||||
|
||||
// create a simple checkerboard texture for the default
|
||||
r_notexture_mip =
|
||||
Hunk_AllocName (0, sizeof (texture_t) + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2,
|
||||
"notexture");
|
||||
|
||||
r_notexture_mip->width = r_notexture_mip->height = 16;
|
||||
r_notexture_mip->offsets[0] = sizeof (texture_t);
|
||||
|
||||
r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16 * 16;
|
||||
r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8 * 8;
|
||||
r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4 * 4;
|
||||
|
||||
for (m = 0; m < 4; m++) {
|
||||
dest = (byte *) r_notexture_mip + r_notexture_mip->offsets[m];
|
||||
for (y = 0; y < (16 >> m); y++)
|
||||
for (x = 0; x < (16 >> m); x++) {
|
||||
if ((y < (8 >> m)) ^ (x < (8 >> m)))
|
||||
*dest++ = 0;
|
||||
else
|
||||
*dest++ = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_Init (void)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
r_ent_queue = EntQueue_New (mod_num_types);
|
||||
|
||||
// get stack position so we can guess if we are going to overflow
|
||||
r_stack_start = (byte *) & dummy;
|
||||
|
||||
R_Init_Cvars ();
|
||||
sw32_R_Particles_Init_Cvars ();
|
||||
|
||||
sw32_Draw_Init ();
|
||||
SCR_Init ();
|
||||
sw32_R_InitTurb ();
|
||||
|
||||
Cmd_AddCommand ("timerefresh", sw32_R_TimeRefresh_f, "Tests the current "
|
||||
"refresh rate for the current location");
|
||||
Cmd_AddCommand ("loadsky", sw32_R_LoadSky_f, "Load a skybox");
|
||||
|
||||
Cvar_SetValue (r_maxedges, (float) NUMSTACKEDGES);
|
||||
Cvar_SetValue (r_maxsurfs, (float) NUMSTACKSURFACES);
|
||||
|
||||
sw32_view_clipplanes[0].leftedge = true;
|
||||
sw32_view_clipplanes[1].rightedge = true;
|
||||
sw32_view_clipplanes[1].leftedge = sw32_view_clipplanes[2].leftedge =
|
||||
sw32_view_clipplanes[3].leftedge = false;
|
||||
sw32_view_clipplanes[0].rightedge = sw32_view_clipplanes[2].rightedge =
|
||||
sw32_view_clipplanes[3].rightedge = false;
|
||||
|
||||
r_refdef.xOrigin = XCENTERING;
|
||||
r_refdef.yOrigin = YCENTERING;
|
||||
|
||||
sw32_D_Init ();
|
||||
|
||||
Skin_Init ();
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
||||
{
|
||||
mod_brush_t *brush = &worldmodel->brush;
|
||||
|
||||
memset (&r_worldentity, 0, sizeof (r_worldentity));
|
||||
r_worldentity.renderer.model = worldmodel;
|
||||
|
||||
// clear out efrags in case the level hasn't been reloaded
|
||||
for (unsigned i = 0; i < brush->modleafs; i++)
|
||||
brush->leafs[i].efrags = NULL;
|
||||
|
||||
if (brush->skytexture)
|
||||
sw32_R_InitSky (brush->skytexture);
|
||||
|
||||
// Force a vis update
|
||||
r_viewleaf = NULL;
|
||||
R_MarkLeaves ();
|
||||
|
||||
R_ClearParticles ();
|
||||
|
||||
r_cnumsurfs = r_maxsurfs->int_val;
|
||||
|
||||
if (r_cnumsurfs <= MINSURFACES)
|
||||
r_cnumsurfs = MINSURFACES;
|
||||
|
||||
if (r_cnumsurfs > NUMSTACKSURFACES) {
|
||||
sw32_surfaces = Hunk_AllocName (0, r_cnumsurfs * sizeof (surf_t),
|
||||
"surfaces");
|
||||
|
||||
sw32_surface_p = sw32_surfaces;
|
||||
sw32_surf_max = &sw32_surfaces[r_cnumsurfs];
|
||||
r_surfsonstack = false;
|
||||
// surface 0 doesn't really exist; it's just a dummy because index 0
|
||||
// is used to indicate no edge attached to surface
|
||||
sw32_surfaces--;
|
||||
} else {
|
||||
r_surfsonstack = true;
|
||||
}
|
||||
|
||||
sw32_r_maxedgesseen = 0;
|
||||
sw32_r_maxsurfsseen = 0;
|
||||
|
||||
sw32_r_numallocatededges = r_maxedges->int_val;
|
||||
|
||||
if (sw32_r_numallocatededges < MINEDGES)
|
||||
sw32_r_numallocatededges = MINEDGES;
|
||||
|
||||
if (sw32_r_numallocatededges <= NUMSTACKEDGES) {
|
||||
sw32_auxedges = NULL;
|
||||
} else {
|
||||
sw32_auxedges = Hunk_AllocName (0,
|
||||
sw32_r_numallocatededges * sizeof (edge_t),
|
||||
"edges");
|
||||
}
|
||||
|
||||
sw32_r_dowarpold = false;
|
||||
sw32_r_viewchanged = false;
|
||||
}
|
||||
|
||||
/*
|
||||
R_ViewChanged
|
||||
|
||||
Called every time the vid structure or r_refdef changes.
|
||||
Guaranteed to be called before the first refresh
|
||||
*/
|
||||
void
|
||||
sw32_R_ViewChanged (void)
|
||||
{
|
||||
int i;
|
||||
float res_scale;
|
||||
|
||||
sw32_r_viewchanged = true;
|
||||
|
||||
r_refdef.horizontalFieldOfView = 2.0 * tan (r_refdef.fov_x / 360 * M_PI);
|
||||
r_refdef.fvrectx = (float) r_refdef.vrect.x;
|
||||
r_refdef.fvrectx_adj = (float) r_refdef.vrect.x - 0.5;
|
||||
r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x << 20) + (1 << 19) - 1;
|
||||
r_refdef.fvrecty = (float) r_refdef.vrect.y;
|
||||
r_refdef.fvrecty_adj = (float) r_refdef.vrect.y - 0.5;
|
||||
r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
|
||||
r_refdef.vrectright_adj_shift20 =
|
||||
(r_refdef.vrectright << 20) + (1 << 19) - 1;
|
||||
r_refdef.fvrectright = (float) r_refdef.vrectright;
|
||||
r_refdef.fvrectright_adj = (float) r_refdef.vrectright - 0.5;
|
||||
r_refdef.vrectrightedge = (float) r_refdef.vrectright - 0.99;
|
||||
r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
|
||||
r_refdef.fvrectbottom = (float) r_refdef.vrectbottom;
|
||||
r_refdef.fvrectbottom_adj = (float) r_refdef.vrectbottom - 0.5;
|
||||
|
||||
r_refdef.aliasvrect.x = (int) (r_refdef.vrect.x * sw32_r_aliasuvscale);
|
||||
r_refdef.aliasvrect.y = (int) (r_refdef.vrect.y * sw32_r_aliasuvscale);
|
||||
r_refdef.aliasvrect.width = (int) (r_refdef.vrect.width * sw32_r_aliasuvscale);
|
||||
r_refdef.aliasvrect.height = (int) (r_refdef.vrect.height *
|
||||
sw32_r_aliasuvscale);
|
||||
r_refdef.aliasvrectright = r_refdef.aliasvrect.x +
|
||||
r_refdef.aliasvrect.width;
|
||||
r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y +
|
||||
r_refdef.aliasvrect.height;
|
||||
|
||||
sw32_pixelAspect = 1;//FIXME vid.aspect;
|
||||
xOrigin = r_refdef.xOrigin;
|
||||
yOrigin = r_refdef.yOrigin;
|
||||
|
||||
screenAspect = r_refdef.vrect.width * sw32_pixelAspect / r_refdef.vrect.height;
|
||||
// 320*200 1.0 sw32_pixelAspect = 1.6 screenAspect
|
||||
// 320*240 1.0 sw32_pixelAspect = 1.3333 screenAspect
|
||||
// proper 320*200 sw32_pixelAspect = 0.8333333
|
||||
|
||||
verticalFieldOfView = r_refdef.horizontalFieldOfView / screenAspect;
|
||||
|
||||
// values for perspective projection
|
||||
// if math were exact, the values would range from 0.5 to to range+0.5
|
||||
// hopefully they wll be in the 0.000001 to range+.999999 and truncate
|
||||
// the polygon rasterization will never render in the first row or column
|
||||
// but will definately render in the [range] row and column, so adjust the
|
||||
// buffer origin to get an exact edge to edge fill
|
||||
sw32_xcenter = ((float) r_refdef.vrect.width * XCENTERING) +
|
||||
r_refdef.vrect.x - 0.5;
|
||||
sw32_aliasxcenter = sw32_xcenter * sw32_r_aliasuvscale;
|
||||
sw32_ycenter = ((float) r_refdef.vrect.height * YCENTERING) +
|
||||
r_refdef.vrect.y - 0.5;
|
||||
sw32_aliasycenter = sw32_ycenter * sw32_r_aliasuvscale;
|
||||
|
||||
sw32_xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
|
||||
sw32_aliasxscale = sw32_xscale * sw32_r_aliasuvscale;
|
||||
sw32_xscaleinv = 1.0 / sw32_xscale;
|
||||
sw32_yscale = sw32_xscale * sw32_pixelAspect;
|
||||
sw32_aliasyscale = sw32_yscale * sw32_r_aliasuvscale;
|
||||
sw32_yscaleinv = 1.0 / sw32_yscale;
|
||||
sw32_xscaleshrink = (r_refdef.vrect.width - 6) / r_refdef.horizontalFieldOfView;
|
||||
sw32_yscaleshrink = sw32_xscaleshrink * sw32_pixelAspect;
|
||||
|
||||
// left side clip
|
||||
sw32_screenedge[0].normal[0] = -1.0 / (xOrigin *
|
||||
r_refdef.horizontalFieldOfView);
|
||||
sw32_screenedge[0].normal[1] = 0;
|
||||
sw32_screenedge[0].normal[2] = 1;
|
||||
sw32_screenedge[0].type = PLANE_ANYZ;
|
||||
|
||||
// right side clip
|
||||
sw32_screenedge[1].normal[0] = 1.0 / ((1.0 - xOrigin) *
|
||||
r_refdef.horizontalFieldOfView);
|
||||
sw32_screenedge[1].normal[1] = 0;
|
||||
sw32_screenedge[1].normal[2] = 1;
|
||||
sw32_screenedge[1].type = PLANE_ANYZ;
|
||||
|
||||
// top side clip
|
||||
sw32_screenedge[2].normal[0] = 0;
|
||||
sw32_screenedge[2].normal[1] = -1.0 / (yOrigin * verticalFieldOfView);
|
||||
sw32_screenedge[2].normal[2] = 1;
|
||||
sw32_screenedge[2].type = PLANE_ANYZ;
|
||||
|
||||
// bottom side clip
|
||||
sw32_screenedge[3].normal[0] = 0;
|
||||
sw32_screenedge[3].normal[1] = 1.0 / ((1.0 - yOrigin) * verticalFieldOfView);
|
||||
sw32_screenedge[3].normal[2] = 1;
|
||||
sw32_screenedge[3].type = PLANE_ANYZ;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
VectorNormalize (sw32_screenedge[i].normal);
|
||||
|
||||
res_scale = sqrt ((double) (r_refdef.vrect.width * r_refdef.vrect.height) /
|
||||
(320.0 * 152.0)) * (2.0 /
|
||||
r_refdef.horizontalFieldOfView);
|
||||
sw32_r_aliastransition = r_aliastransbase->value * res_scale;
|
||||
sw32_r_resfudge = r_aliastransadj->value * res_scale;
|
||||
|
||||
sw32_D_ViewChanged ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_sprite_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
sw32_R_DrawSprite ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
setup_lighting (alight_t *lighting)
|
||||
{
|
||||
float minlight = 0;
|
||||
int j;
|
||||
// FIXME: remove and do real lighting
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
|
||||
minlight = max (currententity->renderer.model->min_light,
|
||||
currententity->renderer.min_light);
|
||||
|
||||
// 128 instead of 255 due to clamping below
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush, r_entorigin),
|
||||
minlight * 128);
|
||||
|
||||
lighting->ambientlight = j;
|
||||
lighting->shadelight = j;
|
||||
|
||||
lighting->plightvec = lightvec;
|
||||
|
||||
for (unsigned lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (r_dlights[lnum].die >= vr_data.realtime) {
|
||||
VectorSubtract (r_entorigin, r_dlights[lnum].origin, dist);
|
||||
add = r_dlights[lnum].radius - VectorLength (dist);
|
||||
|
||||
if (add > 0)
|
||||
lighting->ambientlight += add;
|
||||
}
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (lighting->ambientlight > 128)
|
||||
lighting->ambientlight = 128;
|
||||
if (lighting->ambientlight + lighting->shadelight > 192)
|
||||
lighting->shadelight = 192 - lighting->ambientlight;
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_alias_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
if (R_AliasCheckBBox ()) {
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
sw32_R_AliasDrawModel (&lighting);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_iqm_entity (entity_t *ent)
|
||||
{
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
currententity->visibility.trivial_accept = 0; //FIXME
|
||||
|
||||
alight_t lighting;
|
||||
setup_lighting (&lighting);
|
||||
sw32_R_IQMDrawModel (&lighting);
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawEntitiesOnList (void)
|
||||
{
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
#define RE_LOOP(type_name) \
|
||||
do { \
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_##type_name].size; \
|
||||
i++) { \
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_##type_name].a[i]; \
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
||||
r_entorigin); \
|
||||
currententity = ent; \
|
||||
draw_##type_name##_entity (ent); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
RE_LOOP (alias);
|
||||
RE_LOOP (iqm);
|
||||
RE_LOOP (sprite);
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawViewModel (void)
|
||||
{
|
||||
// FIXME: remove and do real lighting
|
||||
float lightvec[3] = { -1, 0, 0 };
|
||||
int j;
|
||||
unsigned int lnum;
|
||||
vec3_t dist;
|
||||
float add;
|
||||
float minlight;
|
||||
dlight_t *dl;
|
||||
|
||||
if (vr_data.inhibit_viewmodel || !r_drawviewmodel->int_val
|
||||
|| !r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
currententity = vr_data.view_model;
|
||||
if (!currententity->renderer.model)
|
||||
return;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (currententity->transform),
|
||||
r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
VectorCopy (vup, viewlightvec);
|
||||
VectorNegate (viewlightvec, viewlightvec);
|
||||
|
||||
minlight = max (currententity->renderer.min_light,
|
||||
currententity->renderer.model->min_light);
|
||||
|
||||
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
|
||||
r_entorigin), minlight * 128);
|
||||
|
||||
r_viewlighting.ambientlight = j;
|
||||
r_viewlighting.shadelight = j;
|
||||
|
||||
// add dynamic lights
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
dl = &r_dlights[lnum];
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (!dl->radius)
|
||||
continue;
|
||||
if (dl->die < vr_data.realtime)
|
||||
continue;
|
||||
|
||||
VectorSubtract (r_entorigin, dl->origin, dist);
|
||||
add = dl->radius - VectorLength (dist);
|
||||
if (add > 0)
|
||||
r_viewlighting.ambientlight += add;
|
||||
}
|
||||
|
||||
// clamp lighting so it doesn't overbright as much
|
||||
if (r_viewlighting.ambientlight > 128)
|
||||
r_viewlighting.ambientlight = 128;
|
||||
if (r_viewlighting.ambientlight + r_viewlighting.shadelight > 192)
|
||||
r_viewlighting.shadelight = 192 - r_viewlighting.ambientlight;
|
||||
|
||||
r_viewlighting.plightvec = lightvec;
|
||||
|
||||
sw32_R_AliasDrawModel (&r_viewlighting);
|
||||
}
|
||||
|
||||
static int
|
||||
R_BmodelCheckBBox (model_t *clmodel, float *minmaxs)
|
||||
{
|
||||
int i, *pindex, clipflags;
|
||||
vec3_t acceptpt, rejectpt;
|
||||
double d;
|
||||
mat4f_t mat;
|
||||
|
||||
clipflags = 0;
|
||||
|
||||
Transform_GetWorldMatrix (currententity->transform, mat);
|
||||
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
d = DotProduct (mat[3], sw32_view_clipplanes[i].normal);
|
||||
d -= sw32_view_clipplanes[i].dist;
|
||||
|
||||
if (d <= -clmodel->radius)
|
||||
return BMODEL_FULLY_CLIPPED;
|
||||
|
||||
if (d <= clmodel->radius)
|
||||
clipflags |= (1 << i);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 4; i++) {
|
||||
// generate accept and reject points
|
||||
// FIXME: do with fast look-ups or integer tests based on the
|
||||
// sign bit of the floating point values
|
||||
|
||||
pindex = sw32_pfrustum_indexes[i];
|
||||
|
||||
rejectpt[0] = minmaxs[pindex[0]];
|
||||
rejectpt[1] = minmaxs[pindex[1]];
|
||||
rejectpt[2] = minmaxs[pindex[2]];
|
||||
|
||||
d = DotProduct (rejectpt, sw32_view_clipplanes[i].normal);
|
||||
d -= sw32_view_clipplanes[i].dist;
|
||||
|
||||
if (d <= 0)
|
||||
return BMODEL_FULLY_CLIPPED;
|
||||
|
||||
acceptpt[0] = minmaxs[pindex[3 + 0]];
|
||||
acceptpt[1] = minmaxs[pindex[3 + 1]];
|
||||
acceptpt[2] = minmaxs[pindex[3 + 2]];
|
||||
|
||||
d = DotProduct (acceptpt, sw32_view_clipplanes[i].normal);
|
||||
d -= sw32_view_clipplanes[i].dist;
|
||||
|
||||
if (d <= 0)
|
||||
clipflags |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
return clipflags;
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawBEntitiesOnList (void)
|
||||
{
|
||||
int j, clipflags;
|
||||
unsigned int k;
|
||||
vec3_t oldorigin;
|
||||
vec3_t origin;
|
||||
model_t *clmodel;
|
||||
float minmaxs[6];
|
||||
|
||||
if (!r_drawentities->int_val)
|
||||
return;
|
||||
|
||||
VectorCopy (modelorg, oldorigin);
|
||||
insubmodel = true;
|
||||
|
||||
for (size_t i = 0; i < r_ent_queue->ent_queues[mod_brush].size; i++) {
|
||||
entity_t *ent = r_ent_queue->ent_queues[mod_brush].a[i];
|
||||
currententity = ent;
|
||||
|
||||
VectorCopy (Transform_GetWorldPosition (ent->transform), origin);
|
||||
clmodel = ent->renderer.model;
|
||||
|
||||
// see if the bounding box lets us trivially reject, also
|
||||
// sets trivial accept status
|
||||
for (j = 0; j < 3; j++) {
|
||||
minmaxs[j] = origin[j] + clmodel->mins[j];
|
||||
minmaxs[3 + j] = origin[j] + clmodel->maxs[j];
|
||||
}
|
||||
|
||||
clipflags = R_BmodelCheckBBox (clmodel, minmaxs);
|
||||
|
||||
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
||||
mod_brush_t *brush = &clmodel->brush;
|
||||
VectorCopy (origin, r_entorigin);
|
||||
VectorSubtract (r_origin, r_entorigin, modelorg);
|
||||
|
||||
// FIXME: is this needed?
|
||||
VectorCopy (modelorg, sw32_r_worldmodelorg);
|
||||
r_pcurrentvertbase = brush->vertexes;
|
||||
|
||||
// FIXME: stop transforming twice
|
||||
sw32_R_RotateBmodel ();
|
||||
|
||||
// calculate dynamic lighting for bmodel if it's not an
|
||||
// instanced model
|
||||
if (brush->firstmodelsurface != 0) {
|
||||
vec3_t lightorigin;
|
||||
|
||||
for (k = 0; k < r_maxdlights; k++) {
|
||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||
(!r_dlights[k].radius)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
||||
R_RecursiveMarkLights (brush, lightorigin,
|
||||
&r_dlights[k], k,
|
||||
brush->nodes
|
||||
+ brush->hulls[0].firstclipnode);
|
||||
}
|
||||
}
|
||||
// if the driver wants polygons, deliver those.
|
||||
// Z-buffering is on at this point, so no clipping to the
|
||||
// world tree is needed, just frustum clipping
|
||||
if (sw32_r_drawpolys | sw32_r_drawculledpolys) {
|
||||
sw32_R_ZDrawSubmodelPolys (clmodel);
|
||||
} else {
|
||||
if (ent->visibility.topnode) {
|
||||
mnode_t *topnode = ent->visibility.topnode;
|
||||
|
||||
if (topnode->contents >= 0) {
|
||||
// not a leaf; has to be clipped to the world
|
||||
// BSP
|
||||
sw32_r_clipflags = clipflags;
|
||||
sw32_R_DrawSolidClippedSubmodelPolygons (clmodel);
|
||||
} else {
|
||||
// falls entirely in one leaf, so we just put
|
||||
// all the edges in the edge list and let 1/z
|
||||
// sorting handle drawing order
|
||||
sw32_R_DrawSubmodelPolygons (clmodel, clipflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// put back world rotation and frustum clipping
|
||||
// FIXME: sw32_R_RotateBmodel should just work off base_vxx
|
||||
VectorCopy (base_vpn, vpn);
|
||||
VectorCopy (base_vup, vup);
|
||||
VectorCopy (base_vright, vright);
|
||||
VectorCopy (base_modelorg, modelorg);
|
||||
VectorCopy (oldorigin, modelorg);
|
||||
sw32_R_TransformFrustum ();
|
||||
}
|
||||
}
|
||||
|
||||
insubmodel = false;
|
||||
}
|
||||
|
||||
static void
|
||||
R_PrintDSpeeds (void)
|
||||
{
|
||||
float ms, dp_time, r_time2, rw_time, db_time, se_time, de_time,
|
||||
|
||||
dv_time;
|
||||
|
||||
r_time2 = Sys_DoubleTime ();
|
||||
|
||||
dp_time = (dp_time2 - dp_time1) * 1000;
|
||||
rw_time = (rw_time2 - rw_time1) * 1000;
|
||||
db_time = (db_time2 - db_time1) * 1000;
|
||||
se_time = (se_time2 - se_time1) * 1000;
|
||||
de_time = (de_time2 - de_time1) * 1000;
|
||||
dv_time = (dv_time2 - dv_time1) * 1000;
|
||||
ms = (r_time2 - r_time1) * 1000;
|
||||
|
||||
Sys_Printf ("%3i %4.1fp %3iw %4.1fb %3is %4.1fe %4.1fv\n",
|
||||
(int) ms, dp_time, (int) rw_time, db_time, (int) se_time,
|
||||
de_time, dv_time);
|
||||
}
|
||||
|
||||
static void
|
||||
R_EdgeDrawing (void)
|
||||
{
|
||||
edge_t ledges[NUMSTACKEDGES +
|
||||
((CACHE_SIZE - 1) / sizeof (edge_t)) + 1];
|
||||
surf_t lsurfs[NUMSTACKSURFACES +
|
||||
((CACHE_SIZE - 1) / sizeof (surf_t)) + 1];
|
||||
|
||||
if (sw32_auxedges) {
|
||||
sw32_r_edges = sw32_auxedges;
|
||||
} else {
|
||||
sw32_r_edges = (edge_t *)
|
||||
(((intptr_t) &ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
}
|
||||
|
||||
if (r_surfsonstack) {
|
||||
sw32_surfaces = (surf_t *)
|
||||
(((intptr_t) &lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
||||
sw32_surf_max = &sw32_surfaces[r_cnumsurfs];
|
||||
// surface 0 doesn't really exist; it's just a dummy because index 0
|
||||
// is used to indicate no edge attached to surface
|
||||
sw32_surfaces--;
|
||||
}
|
||||
|
||||
sw32_R_BeginEdgeFrame ();
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
rw_time1 = Sys_DoubleTime ();
|
||||
}
|
||||
|
||||
sw32_R_RenderWorld ();
|
||||
|
||||
if (sw32_r_drawculledpolys)
|
||||
sw32_R_ScanEdges ();
|
||||
|
||||
// only the world can be drawn back to front with no z reads or compares,
|
||||
// just z writes, so have the driver turn z compares on now
|
||||
sw32_D_TurnZOn ();
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
rw_time2 = Sys_DoubleTime ();
|
||||
db_time1 = rw_time2;
|
||||
}
|
||||
|
||||
R_DrawBEntitiesOnList ();
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
db_time2 = Sys_DoubleTime ();
|
||||
se_time1 = db_time2;
|
||||
}
|
||||
|
||||
if (!r_dspeeds->int_val) {
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
}
|
||||
|
||||
if (!(sw32_r_drawpolys | sw32_r_drawculledpolys))
|
||||
sw32_R_ScanEdges ();
|
||||
}
|
||||
|
||||
// LordHavoc: took out of stack and made 4x size for 32bit capacity
|
||||
static byte warpbuffer[WARP_WIDTH * WARP_HEIGHT * 4];
|
||||
|
||||
/*
|
||||
R_RenderView
|
||||
|
||||
r_refdef must be set before the first call
|
||||
*/
|
||||
static void
|
||||
R_RenderView_ (void)
|
||||
{
|
||||
if (r_norefresh->int_val)
|
||||
return;
|
||||
if (!r_worldentity.renderer.model) {
|
||||
return;
|
||||
}
|
||||
|
||||
sw32_r_warpbuffer = warpbuffer;
|
||||
|
||||
if (r_timegraph->int_val || r_speeds->int_val || r_dspeeds->int_val)
|
||||
r_time1 = Sys_DoubleTime ();
|
||||
|
||||
sw32_R_SetupFrame ();
|
||||
|
||||
#ifdef PASSAGES
|
||||
SetVisibilityByPassages ();
|
||||
#else
|
||||
R_MarkLeaves (); // done here so we know if we're in water
|
||||
#endif
|
||||
R_PushDlights (vec3_origin);
|
||||
|
||||
if (!r_dspeeds->int_val) {
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
}
|
||||
|
||||
R_EdgeDrawing ();
|
||||
|
||||
if (!r_dspeeds->int_val) {
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
}
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
se_time2 = Sys_DoubleTime ();
|
||||
de_time1 = se_time2;
|
||||
}
|
||||
|
||||
R_DrawEntitiesOnList ();
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
de_time2 = Sys_DoubleTime ();
|
||||
dv_time1 = de_time2;
|
||||
}
|
||||
|
||||
R_DrawViewModel ();
|
||||
|
||||
if (r_dspeeds->int_val) {
|
||||
dv_time2 = Sys_DoubleTime ();
|
||||
dp_time1 = Sys_DoubleTime ();
|
||||
}
|
||||
|
||||
sw32_R_DrawParticles ();
|
||||
|
||||
if (r_dspeeds->int_val)
|
||||
dp_time2 = Sys_DoubleTime ();
|
||||
|
||||
if (sw32_r_dowarp)
|
||||
sw32_D_WarpScreen ();
|
||||
|
||||
if (r_timegraph->int_val)
|
||||
R_TimeGraph ();
|
||||
|
||||
if (r_zgraph->int_val)
|
||||
R_ZGraph ();
|
||||
|
||||
if (r_aliasstats->int_val)
|
||||
sw32_R_PrintAliasStats ();
|
||||
|
||||
if (r_speeds->int_val)
|
||||
sw32_R_PrintTimes ();
|
||||
|
||||
if (r_dspeeds->int_val)
|
||||
R_PrintDSpeeds ();
|
||||
|
||||
if (r_reportsurfout->int_val && sw32_r_outofsurfaces)
|
||||
Sys_Printf ("Short %d surfaces\n", sw32_r_outofsurfaces);
|
||||
|
||||
if (r_reportedgeout->int_val && sw32_r_outofedges)
|
||||
Sys_Printf ("Short roughly %d edges\n", sw32_r_outofedges * 2 / 3);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_RenderView (void)
|
||||
{
|
||||
int dummy;
|
||||
int delta;
|
||||
|
||||
delta = (byte *) & dummy - r_stack_start;
|
||||
if (delta < -10000 || delta > 10000)
|
||||
Sys_Error ("R_RenderView: called without enough stack");
|
||||
|
||||
if (Hunk_LowMark (0) & 3)
|
||||
Sys_Error ("Hunk is missaligned");
|
||||
|
||||
if ((intptr_t) (&dummy) & 3)
|
||||
Sys_Error ("Stack is missaligned");
|
||||
|
||||
if ((intptr_t) (&sw32_r_warpbuffer) & 3)
|
||||
Sys_Error ("Globals are missaligned");
|
||||
|
||||
R_RenderView_ ();
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_InitTurb (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXWIDTH; i++) {
|
||||
sw32_sintable[i] = AMP + sin (i * 3.14159 * 2 / CYCLE) * AMP;
|
||||
sw32_intsintable[i] = AMP2 + sin (i * 3.14159 * 2 / CYCLE) * AMP2;
|
||||
// AMP2 not 20
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_ClearState (void)
|
||||
{
|
||||
r_worldentity.renderer.model = 0;
|
||||
R_ClearEfrags ();
|
||||
R_ClearDlights ();
|
||||
R_ClearParticles ();
|
||||
}
|
|
@ -1,321 +0,0 @@
|
|||
/*
|
||||
sw32_rmisc.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/draw.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static void
|
||||
R_CheckVariables (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
R_TimeRefresh_f
|
||||
|
||||
For program optimization
|
||||
*/
|
||||
void
|
||||
sw32_R_TimeRefresh_f (void)
|
||||
{
|
||||
/* FIXME update for simd
|
||||
int i;
|
||||
float start, stop, time;
|
||||
int startangle;
|
||||
vrect_t vr;
|
||||
|
||||
startangle = r_refdef.viewangles[1];
|
||||
|
||||
start = Sys_DoubleTime ();
|
||||
for (i = 0; i < 128; i++) {
|
||||
r_refdef.viewangles[1] = i / 128.0 * 360.0;
|
||||
|
||||
sw32_R_RenderView ();
|
||||
|
||||
vr.x = r_refdef.vrect.x;
|
||||
vr.y = r_refdef.vrect.y;
|
||||
vr.width = r_refdef.vrect.width;
|
||||
vr.height = r_refdef.vrect.height;
|
||||
vr.next = NULL;
|
||||
sw32_ctx->update (&vr);
|
||||
}
|
||||
stop = Sys_DoubleTime ();
|
||||
time = stop - start;
|
||||
Sys_Printf ("%g seconds (%g fps)\n", time, 128 / time);
|
||||
|
||||
r_refdef.viewangles[1] = startangle;
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_LoadSky_f (void)
|
||||
{
|
||||
if (Cmd_Argc () != 2) {
|
||||
Sys_Printf ("loadsky <name> : load a skybox\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sw32_R_LoadSkys (Cmd_Argv (1));
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_PrintTimes (void)
|
||||
{
|
||||
float r_time2;
|
||||
float ms;
|
||||
|
||||
r_time2 = Sys_DoubleTime ();
|
||||
|
||||
ms = 1000 * (r_time2 - r_time1);
|
||||
|
||||
Sys_Printf ("%5.1f ms %3i/%3i/%3i poly %3i surf\n",
|
||||
ms, sw32_c_faceclip, sw32_r_polycount, sw32_r_drawnpolycount, sw32_c_surf);
|
||||
sw32_c_surf = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_PrintAliasStats (void)
|
||||
{
|
||||
Sys_Printf ("%3i polygon model drawn\n", sw32_r_amodels_drawn);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_TransformFrustum (void)
|
||||
{
|
||||
int i;
|
||||
vec3_t v, v2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
v[0] = sw32_screenedge[i].normal[2];
|
||||
v[1] = -sw32_screenedge[i].normal[0];
|
||||
v[2] = sw32_screenedge[i].normal[1];
|
||||
|
||||
v2[0] = v[1] * vright[0] + v[2] * vup[0] + v[0] * vpn[0];
|
||||
v2[1] = v[1] * vright[1] + v[2] * vup[1] + v[0] * vpn[1];
|
||||
v2[2] = v[1] * vright[2] + v[2] * vup[2] + v[0] * vpn[2];
|
||||
|
||||
VectorCopy (v2, sw32_view_clipplanes[i].normal);
|
||||
|
||||
sw32_view_clipplanes[i].dist = DotProduct (modelorg, v2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_TransformVector (const vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = DotProduct (in, vright);
|
||||
out[1] = DotProduct (in, vup);
|
||||
out[2] = DotProduct (in, vpn);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_TransformPlane (plane_t *p, float *normal, float *dist)
|
||||
{
|
||||
float d;
|
||||
|
||||
d = DotProduct (r_origin, p->normal);
|
||||
*dist = p->dist - d;
|
||||
// TODO: when we have rotating entities, this will need to use the view matrix
|
||||
sw32_TransformVector (p->normal, normal);
|
||||
}
|
||||
|
||||
static void
|
||||
R_SetUpFrustumIndexes (void)
|
||||
{
|
||||
int i, j, *pindex;
|
||||
|
||||
pindex = sw32_r_frustum_indexes;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (sw32_view_clipplanes[i].normal[j] < 0) {
|
||||
pindex[j] = j;
|
||||
pindex[j + 3] = j + 3;
|
||||
} else {
|
||||
pindex[j] = j + 3;
|
||||
pindex[j + 3] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do just once at start
|
||||
sw32_pfrustum_indexes[i] = pindex;
|
||||
pindex += 6;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_SetupFrame (void)
|
||||
{
|
||||
int edgecount;
|
||||
vrect_t vrect;
|
||||
float w, h;
|
||||
|
||||
// don't allow cheats in multiplayer
|
||||
Cvar_SetValue (r_ambient, 0);
|
||||
Cvar_SetValue (r_drawflat, 0);
|
||||
|
||||
if (r_numsurfs->int_val) {
|
||||
if ((sw32_surface_p - sw32_surfaces) > sw32_r_maxsurfsseen)
|
||||
sw32_r_maxsurfsseen = sw32_surface_p - sw32_surfaces;
|
||||
|
||||
Sys_Printf ("Used %ld of %ld surfs; %d max\n",
|
||||
(long) (sw32_surface_p - sw32_surfaces),
|
||||
(long) (sw32_surf_max - sw32_surfaces), sw32_r_maxsurfsseen);
|
||||
}
|
||||
|
||||
if (r_numedges->int_val) {
|
||||
edgecount = sw32_edge_p - sw32_r_edges;
|
||||
|
||||
if (edgecount > sw32_r_maxedgesseen)
|
||||
sw32_r_maxedgesseen = edgecount;
|
||||
|
||||
Sys_Printf ("Used %d of %d edges; %d max\n", edgecount,
|
||||
sw32_r_numallocatededges, sw32_r_maxedgesseen);
|
||||
}
|
||||
|
||||
r_refdef.ambientlight = max (r_ambient->value, 0);
|
||||
|
||||
R_CheckVariables ();
|
||||
|
||||
R_AnimateLight ();
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
sw32_numbtofpolys = 0;
|
||||
|
||||
// debugging
|
||||
#if 0
|
||||
r_refdef.vieworg[0] = 80;
|
||||
r_refdef.vieworg[1] = 64;
|
||||
r_refdef.vieworg[2] = 40;
|
||||
r_refdef.viewangles[0] = 0;
|
||||
r_refdef.viewangles[1] = 46.763641357;
|
||||
r_refdef.viewangles[2] = 0;
|
||||
#endif
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
VectorCopy (r_refdef.viewposition, modelorg);
|
||||
VectorCopy (r_refdef.viewposition, r_origin);
|
||||
|
||||
VectorCopy (qvmulf (r_refdef.viewrotation, (vec4f_t) { 1, 0, 0, 0 }), vpn);
|
||||
VectorCopy (qvmulf (r_refdef.viewrotation, (vec4f_t) { 0, -1, 0, 0 }), vright);
|
||||
VectorCopy (qvmulf (r_refdef.viewrotation, (vec4f_t) { 0, 0, 1, 0 }), vup);
|
||||
R_SetFrustum ();
|
||||
|
||||
// current viewleaf
|
||||
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
|
||||
|
||||
sw32_r_dowarpold = sw32_r_dowarp;
|
||||
sw32_r_dowarp = r_waterwarp->int_val && (r_viewleaf->contents <=
|
||||
CONTENTS_WATER);
|
||||
|
||||
if ((sw32_r_dowarp != sw32_r_dowarpold) || sw32_r_viewchanged) {
|
||||
if (sw32_r_dowarp) {
|
||||
if ((vid.width <= WARP_WIDTH)
|
||||
&& (vid.height <= WARP_HEIGHT)) {
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
|
||||
R_SetVrect (&vrect, &r_refdef.vrect, vr_data.lineadj);
|
||||
sw32_R_ViewChanged ();
|
||||
} else {
|
||||
w = vid.width;
|
||||
h = vid.height;
|
||||
|
||||
if (w > WARP_WIDTH) {
|
||||
h *= (float) WARP_WIDTH / w;
|
||||
w = WARP_WIDTH;
|
||||
}
|
||||
|
||||
if (h > WARP_HEIGHT) {
|
||||
h = WARP_HEIGHT;
|
||||
w *= (float) WARP_HEIGHT / h;
|
||||
}
|
||||
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = (int) w;
|
||||
vrect.height = (int) h;
|
||||
|
||||
R_SetVrect (&vrect, &r_refdef.vrect,
|
||||
(int) ((float) vr_data.lineadj *
|
||||
(h / (float) vid.height)));
|
||||
sw32_R_ViewChanged ();
|
||||
}
|
||||
} else {
|
||||
r_refdef.vrect.x = vr_data.scr_view->xpos;
|
||||
r_refdef.vrect.y = vr_data.scr_view->ypos;
|
||||
r_refdef.vrect.width = vr_data.scr_view->xlen;
|
||||
r_refdef.vrect.height = vr_data.scr_view->ylen;
|
||||
sw32_R_ViewChanged ();
|
||||
}
|
||||
|
||||
sw32_r_viewchanged = false;
|
||||
}
|
||||
// start off with just the four screen edge clip planes
|
||||
sw32_R_TransformFrustum ();
|
||||
|
||||
// save base values
|
||||
VectorCopy (vpn, base_vpn);
|
||||
VectorCopy (vright, base_vright);
|
||||
VectorCopy (vup, base_vup);
|
||||
VectorCopy (modelorg, base_modelorg);
|
||||
|
||||
sw32_R_SetSkyFrame ();
|
||||
|
||||
R_SetUpFrustumIndexes ();
|
||||
|
||||
r_cache_thrash = false;
|
||||
|
||||
// clear frame counts
|
||||
sw32_c_faceclip = 0;
|
||||
sw32_r_polycount = 0;
|
||||
sw32_r_drawnpolycount = 0;
|
||||
sw32_r_amodels_drawn = 0;
|
||||
sw32_r_outofsurfaces = 0;
|
||||
sw32_r_outofedges = 0;
|
||||
|
||||
sw32_D_SetupFrame ();
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
sw32_rpart.c
|
||||
|
||||
24 bit color software renderer particle effects.
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/mersenne.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
|
||||
void
|
||||
sw32_R_DrawParticles (void)
|
||||
{
|
||||
VectorScale (vright, xscaleshrink, r_pright);
|
||||
VectorScale (vup, yscaleshrink, r_pup);
|
||||
VectorCopy (vpn, r_ppn);
|
||||
|
||||
R_RunParticles (vr_data.frametime);
|
||||
|
||||
for (unsigned i = 0; i < r_psystem.numparticles; i++) {
|
||||
particle_t *p = &r_psystem.particles[i];
|
||||
sw32_D_DrawParticle (p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
r_particles_nearclip_f (cvar_t *var)
|
||||
{
|
||||
Cvar_SetValue (r_particles_nearclip, bound (r_nearclip->value, var->value,
|
||||
r_farclip->value));
|
||||
}
|
||||
|
||||
static void
|
||||
r_particles_f (cvar_t *var)
|
||||
{
|
||||
R_MaxParticlesCheck (var, r_particles_max);
|
||||
}
|
||||
|
||||
static void
|
||||
r_particles_max_f (cvar_t *var)
|
||||
{
|
||||
R_MaxParticlesCheck (r_particles, var);
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_Particles_Init_Cvars (void)
|
||||
{
|
||||
r_particles = Cvar_Get ("r_particles", "1", CVAR_ARCHIVE, r_particles_f,
|
||||
"Toggles drawing of particles.");
|
||||
r_particles_max = Cvar_Get ("r_particles_max", "2048", CVAR_ARCHIVE,
|
||||
r_particles_max_f, "Maximum amount of "
|
||||
"particles to display. No maximum, minimum "
|
||||
"is 0.");
|
||||
r_particles_nearclip = Cvar_Get ("r_particles_nearclip", "32",
|
||||
CVAR_ARCHIVE, r_particles_nearclip_f,
|
||||
"Distance of the particle near clipping "
|
||||
"plane from the player.");
|
||||
}
|
||||
|
||||
psystem_t * __attribute__((const))//FIXME
|
||||
sw32_ParticleSystem (void)
|
||||
{
|
||||
return &r_psystem;
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
r_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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include "string.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include "strings.h"
|
||||
#endif
|
||||
|
||||
#include "QF/sys.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
|
||||
static int iskyspeed = 8;
|
||||
static int iskyspeed2 = 2;
|
||||
float sw32_r_skyspeed;
|
||||
|
||||
float sw32_r_skytime;
|
||||
|
||||
byte *sw32_r_skysource;
|
||||
|
||||
int sw32_r_skymade;
|
||||
|
||||
// TODO: clean up these routines
|
||||
|
||||
/*
|
||||
byte bottomsky[128 * 131];
|
||||
byte bottommask[128 * 131];
|
||||
byte newsky[128 * 256]; // newsky and topsky both pack in here,
|
||||
// 128 bytes of newsky on the left of
|
||||
// each scan, 128 bytes of topsky on
|
||||
// the right, because the low-level
|
||||
// drawers need 256-byte scan widths
|
||||
*/
|
||||
static byte skydata[128*256]; // sky layers for making skytex
|
||||
static byte skytex[128*256*4]; // current sky texture
|
||||
|
||||
|
||||
/*
|
||||
R_InitSky
|
||||
|
||||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
*/
|
||||
void
|
||||
sw32_R_InitSky (texture_t *mt)
|
||||
{
|
||||
/*
|
||||
int i, j;
|
||||
byte *src;
|
||||
|
||||
src = (byte *) mt + mt->offsets[0];
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
for (j = 0; j < 128; j++) {
|
||||
newsky[(i * 256) + j + 128] = src[i * 256 + j + 128];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
for (j = 0; j < 131; j++) {
|
||||
if (src[i * 256 + (j & 0x7F)]) {
|
||||
bottomsky[(i * 131) + j] = src[i * 256 + (j & 0x7F)];
|
||||
bottommask[(i * 131) + j] = 0;
|
||||
} else {
|
||||
bottomsky[(i * 131) + j] = 0;
|
||||
bottommask[(i * 131) + j] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sw32_r_skysource = newsky;
|
||||
*/
|
||||
|
||||
// LordHavoc: save sky for use
|
||||
memcpy(skydata, (byte *) mt + mt->offsets[0], 128*256);
|
||||
sw32_r_skysource = skytex;
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_MakeSky (void)
|
||||
{
|
||||
int x, y, xshift1, yshift1, xshift2, yshift2;
|
||||
byte *base1, *base2;
|
||||
static int xlast = -1, ylast = -1;
|
||||
|
||||
xshift2 = sw32_r_skytime * sw32_r_skyspeed * 2.0f;
|
||||
yshift2 = sw32_r_skytime * sw32_r_skyspeed * 2.0f;
|
||||
|
||||
if ((xshift2 == xlast) && (yshift2 == ylast))
|
||||
return;
|
||||
|
||||
xlast = xshift2;
|
||||
ylast = yshift2;
|
||||
xshift1 = xshift2 >> 1;
|
||||
yshift1 = yshift2 >> 1;
|
||||
|
||||
switch(sw32_ctx->pixbytes)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
byte *out = (byte *) skytex;
|
||||
for (y = 0;y < 128;y++)
|
||||
{
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++)
|
||||
{
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = base1[(x + xshift1) & 127];
|
||||
else
|
||||
*out = base2[(x + xshift2) & 127];
|
||||
out++;
|
||||
}
|
||||
out += 128;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
unsigned short *out = (unsigned short *) skytex;
|
||||
for (y = 0;y < 128;y++)
|
||||
{
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++)
|
||||
{
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = sw32_8to16table[base1[(x + xshift1) & 127]];
|
||||
else
|
||||
*out = sw32_8to16table[base2[(x + xshift2) & 127]];
|
||||
out++;
|
||||
}
|
||||
out += 128;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
unsigned int *out = (unsigned int *) skytex;
|
||||
for (y = 0;y < 128;y++)
|
||||
{
|
||||
base1 = &skydata[((y + yshift1) & 127) * 256];
|
||||
base2 = &skydata[((y + yshift2) & 127) * 256 + 128];
|
||||
for (x = 0;x < 128;x++)
|
||||
{
|
||||
if (base1[(x + xshift1) & 127])
|
||||
*out = d_8to24table[base1[(x + xshift1) & 127]];
|
||||
else
|
||||
*out = d_8to24table[base2[(x + xshift2) & 127]];
|
||||
out++;
|
||||
}
|
||||
out += 128;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Sys_Error("R_MakeSky: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
}
|
||||
sw32_r_skymade = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_SetSkyFrame (void)
|
||||
{
|
||||
int g, s1, s2;
|
||||
float temp;
|
||||
|
||||
sw32_r_skyspeed = iskyspeed;
|
||||
|
||||
g = GreatestCommonDivisor (iskyspeed, iskyspeed2);
|
||||
s1 = iskyspeed / g;
|
||||
s2 = iskyspeed2 / g;
|
||||
temp = SKYSIZE * s1 * s2;
|
||||
|
||||
sw32_r_skytime = vr_data.realtime - ((int) (vr_data.realtime / temp) * temp);
|
||||
|
||||
sw32_r_skymade = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Stub function for loading a skybox. Currently we have support for
|
||||
skyboxes only in GL targets, so we just do nothing here. --KB
|
||||
*/
|
||||
void
|
||||
sw32_R_LoadSkys (const char *name)
|
||||
{
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
/*
|
||||
sw32_rsprite.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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "r_internal.h"
|
||||
|
||||
static int clip_current;
|
||||
static vec5_t clip_verts[2][MAXWORKINGVERTS];
|
||||
static int sprite_width, sprite_height;
|
||||
|
||||
spritedesc_t sw32_r_spritedesc;
|
||||
|
||||
|
||||
static void
|
||||
R_RotateSprite (float beamlength)
|
||||
{
|
||||
vec3_t vec;
|
||||
|
||||
if (beamlength == 0.0)
|
||||
return;
|
||||
|
||||
VectorScale (sw32_r_spritedesc.vpn, -beamlength, vec);
|
||||
VectorAdd (r_entorigin, vec, r_entorigin);
|
||||
VectorSubtract (modelorg, vec, modelorg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_ClipSpriteFace
|
||||
|
||||
Clips the winding at clip_verts[clip_current] and changes clip_current
|
||||
Throws out the back side
|
||||
*/
|
||||
static int
|
||||
R_ClipSpriteFace (int nump, clipplane_t *pclipplane)
|
||||
{
|
||||
int i, outcount;
|
||||
float dists[MAXWORKINGVERTS + 1];
|
||||
float frac, clipdist, *pclipnormal;
|
||||
float *in, *instep, *outstep, *vert2;
|
||||
|
||||
clipdist = pclipplane->dist;
|
||||
pclipnormal = pclipplane->normal;
|
||||
|
||||
// calc dists
|
||||
if (clip_current) {
|
||||
in = clip_verts[1][0];
|
||||
outstep = clip_verts[0][0];
|
||||
clip_current = 0;
|
||||
} else {
|
||||
in = clip_verts[0][0];
|
||||
outstep = clip_verts[1][0];
|
||||
clip_current = 1;
|
||||
}
|
||||
|
||||
instep = in;
|
||||
for (i = 0; i < nump; i++, instep += sizeof (vec5_t) / sizeof (float)) {
|
||||
dists[i] = DotProduct (instep, pclipnormal) - clipdist;
|
||||
}
|
||||
|
||||
// handle wraparound case
|
||||
dists[nump] = dists[0];
|
||||
memcpy (instep, in, sizeof (vec5_t));
|
||||
|
||||
// clip the winding
|
||||
instep = in;
|
||||
outcount = 0;
|
||||
|
||||
for (i = 0; i < nump; i++, instep += sizeof (vec5_t) / sizeof (float)) {
|
||||
if (dists[i] >= 0) {
|
||||
memcpy (outstep, instep, sizeof (vec5_t));
|
||||
outstep += sizeof (vec5_t) / sizeof (float);
|
||||
outcount++;
|
||||
}
|
||||
|
||||
if (dists[i] == 0 || dists[i + 1] == 0)
|
||||
continue;
|
||||
|
||||
if ((dists[i] > 0) == (dists[i + 1] > 0))
|
||||
continue;
|
||||
|
||||
// split it into a new vertex
|
||||
frac = dists[i] / (dists[i] - dists[i + 1]);
|
||||
|
||||
vert2 = instep + sizeof (vec5_t) / sizeof (float);
|
||||
|
||||
outstep[0] = instep[0] + frac * (vert2[0] - instep[0]);
|
||||
outstep[1] = instep[1] + frac * (vert2[1] - instep[1]);
|
||||
outstep[2] = instep[2] + frac * (vert2[2] - instep[2]);
|
||||
outstep[3] = instep[3] + frac * (vert2[3] - instep[3]);
|
||||
outstep[4] = instep[4] + frac * (vert2[4] - instep[4]);
|
||||
|
||||
outstep += sizeof (vec5_t) / sizeof (float);
|
||||
|
||||
outcount++;
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
R_SetupAndDrawSprite (void)
|
||||
{
|
||||
int i, nump;
|
||||
float dot, scale, *pv;
|
||||
vec5_t *pverts;
|
||||
vec3_t left, up, right, down, transformed, local;
|
||||
emitpoint_t outverts[MAXWORKINGVERTS + 1], *pout;
|
||||
|
||||
dot = DotProduct (sw32_r_spritedesc.vpn, modelorg);
|
||||
|
||||
// backface cull
|
||||
if (dot >= 0)
|
||||
return;
|
||||
|
||||
// build the sprite poster in worldspace
|
||||
VectorScale (sw32_r_spritedesc.vright, sw32_r_spritedesc.pspriteframe->right, right);
|
||||
VectorScale (sw32_r_spritedesc.vup, sw32_r_spritedesc.pspriteframe->up, up);
|
||||
VectorScale (sw32_r_spritedesc.vright, sw32_r_spritedesc.pspriteframe->left, left);
|
||||
VectorScale (sw32_r_spritedesc.vup, sw32_r_spritedesc.pspriteframe->down, down);
|
||||
|
||||
pverts = clip_verts[0];
|
||||
|
||||
pverts[0][0] = r_entorigin[0] + up[0] + left[0];
|
||||
pverts[0][1] = r_entorigin[1] + up[1] + left[1];
|
||||
pverts[0][2] = r_entorigin[2] + up[2] + left[2];
|
||||
pverts[0][3] = 0;
|
||||
pverts[0][4] = 0;
|
||||
|
||||
pverts[1][0] = r_entorigin[0] + up[0] + right[0];
|
||||
pverts[1][1] = r_entorigin[1] + up[1] + right[1];
|
||||
pverts[1][2] = r_entorigin[2] + up[2] + right[2];
|
||||
pverts[1][3] = sprite_width;
|
||||
pverts[1][4] = 0;
|
||||
|
||||
pverts[2][0] = r_entorigin[0] + down[0] + right[0];
|
||||
pverts[2][1] = r_entorigin[1] + down[1] + right[1];
|
||||
pverts[2][2] = r_entorigin[2] + down[2] + right[2];
|
||||
pverts[2][3] = sprite_width;
|
||||
pverts[2][4] = sprite_height;
|
||||
|
||||
pverts[3][0] = r_entorigin[0] + down[0] + left[0];
|
||||
pverts[3][1] = r_entorigin[1] + down[1] + left[1];
|
||||
pverts[3][2] = r_entorigin[2] + down[2] + left[2];
|
||||
pverts[3][3] = 0;
|
||||
pverts[3][4] = sprite_height;
|
||||
|
||||
// clip to the frustum in worldspace
|
||||
nump = 4;
|
||||
clip_current = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
nump = R_ClipSpriteFace (nump, &sw32_view_clipplanes[i]);
|
||||
if (nump < 3)
|
||||
return;
|
||||
if (nump >= MAXWORKINGVERTS)
|
||||
Sys_Error ("R_SetupAndDrawSprite: too many points");
|
||||
}
|
||||
|
||||
// transform vertices into viewspace and project
|
||||
pv = &clip_verts[clip_current][0][0];
|
||||
sw32_r_spritedesc.nearzi = -999999;
|
||||
|
||||
for (i = 0; i < nump; i++) {
|
||||
VectorSubtract (pv, r_origin, local);
|
||||
sw32_TransformVector (local, transformed);
|
||||
|
||||
if (transformed[2] < NEAR_CLIP)
|
||||
transformed[2] = NEAR_CLIP;
|
||||
|
||||
pout = &outverts[i];
|
||||
pout->zi = 1.0 / transformed[2];
|
||||
if (pout->zi > sw32_r_spritedesc.nearzi)
|
||||
sw32_r_spritedesc.nearzi = pout->zi;
|
||||
|
||||
pout->s = pv[3];
|
||||
pout->t = pv[4];
|
||||
|
||||
scale = sw32_xscale * pout->zi;
|
||||
pout->u = (sw32_xcenter + scale * transformed[0]);
|
||||
|
||||
scale = sw32_yscale * pout->zi;
|
||||
pout->v = (sw32_ycenter - scale * transformed[1]);
|
||||
|
||||
pv += sizeof (vec5_t) / sizeof (*pv);
|
||||
}
|
||||
|
||||
// draw it
|
||||
sw32_r_spritedesc.nump = nump;
|
||||
sw32_r_spritedesc.pverts = outverts;
|
||||
sw32_D_DrawSprite ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sw32_R_DrawSprite (void)
|
||||
{
|
||||
msprite_t *sprite = currententity->renderer.model->cache.data;
|
||||
|
||||
sw32_r_spritedesc.pspriteframe = R_GetSpriteFrame (sprite,
|
||||
¤tentity->animation);
|
||||
|
||||
sprite_width = sw32_r_spritedesc.pspriteframe->width;
|
||||
sprite_height = sw32_r_spritedesc.pspriteframe->height;
|
||||
|
||||
if (!R_BillboardFrame (currententity, sprite->type, modelorg,
|
||||
r_spritedesc.vup,
|
||||
r_spritedesc.vright,
|
||||
r_spritedesc.vpn)) {
|
||||
// the orientation is undefined so can't draw the sprite
|
||||
return;
|
||||
}
|
||||
|
||||
R_RotateSprite (sprite->beamlength);
|
||||
|
||||
R_SetupAndDrawSprite ();
|
||||
}
|
|
@ -1,898 +0,0 @@
|
|||
/*
|
||||
sw32_rsurf.c
|
||||
|
||||
surface-related refresh 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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "namehack.h"
|
||||
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
drawsurf_t sw32_r_drawsurf;
|
||||
|
||||
static int lightleft, blocksize, sourcetstep;
|
||||
static int lightright, lightleftstep, lightrightstep, blockdivshift;
|
||||
static unsigned int blockdivmask;
|
||||
static byte *prowdestbase;
|
||||
static byte *psource;
|
||||
static int surfrowbytes;
|
||||
static int *r_lightptr;
|
||||
static int r_stepback;
|
||||
static int r_lightwidth;
|
||||
static int r_numhblocks, r_numvblocks;
|
||||
static byte *r_source, *r_sourcemax;
|
||||
|
||||
static void R_DrawSurfaceBlock8_mip0 (void);
|
||||
static void R_DrawSurfaceBlock8_mip1 (void);
|
||||
static void R_DrawSurfaceBlock8_mip2 (void);
|
||||
static void R_DrawSurfaceBlock8_mip3 (void);
|
||||
static void R_DrawSurfaceBlock16_mip0 (void);
|
||||
static void R_DrawSurfaceBlock16_mip1 (void);
|
||||
static void R_DrawSurfaceBlock16_mip2 (void);
|
||||
static void R_DrawSurfaceBlock16_mip3 (void);
|
||||
static void R_DrawSurfaceBlock32_mip0 (void);
|
||||
static void R_DrawSurfaceBlock32_mip1 (void);
|
||||
static void R_DrawSurfaceBlock32_mip2 (void);
|
||||
static void R_DrawSurfaceBlock32_mip3 (void);
|
||||
|
||||
static void (*surfmiptable8[4]) (void) = {
|
||||
R_DrawSurfaceBlock8_mip0,
|
||||
R_DrawSurfaceBlock8_mip1,
|
||||
R_DrawSurfaceBlock8_mip2,
|
||||
R_DrawSurfaceBlock8_mip3
|
||||
};
|
||||
|
||||
static void (*surfmiptable16[4]) (void) = {
|
||||
R_DrawSurfaceBlock16_mip0,
|
||||
R_DrawSurfaceBlock16_mip1,
|
||||
R_DrawSurfaceBlock16_mip2,
|
||||
R_DrawSurfaceBlock16_mip3
|
||||
};
|
||||
|
||||
static void (*surfmiptable32[4]) (void) = {
|
||||
R_DrawSurfaceBlock32_mip0,
|
||||
R_DrawSurfaceBlock32_mip1,
|
||||
R_DrawSurfaceBlock32_mip2,
|
||||
R_DrawSurfaceBlock32_mip3
|
||||
};
|
||||
|
||||
static int blocklights[34 * 34]; //FIXME make dynamic
|
||||
|
||||
|
||||
static void
|
||||
R_AddDynamicLights (void)
|
||||
{
|
||||
msurface_t *surf;
|
||||
unsigned int lnum;
|
||||
int sd, td;
|
||||
float dist, rad, minlight;
|
||||
vec3_t impact, local, lightorigin;
|
||||
vec4f_t entorigin = { 0, 0, 0, 1 };
|
||||
int s, t;
|
||||
int i;
|
||||
int smax, tmax;
|
||||
mtexinfo_t *tex;
|
||||
|
||||
surf = sw32_r_drawsurf.surf;
|
||||
smax = (surf->extents[0] >> 4) + 1;
|
||||
tmax = (surf->extents[1] >> 4) + 1;
|
||||
tex = surf->texinfo;
|
||||
|
||||
if (currententity->transform) {
|
||||
//FIXME give world entity a transform
|
||||
entorigin = Transform_GetWorldPosition (currententity->transform);
|
||||
}
|
||||
|
||||
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
||||
if (!(surf->dlightbits[lnum / 32] & (1 << (lnum % 32))))
|
||||
continue; // not lit by this light
|
||||
|
||||
VectorSubtract (r_dlights[lnum].origin, entorigin, lightorigin);
|
||||
rad = r_dlights[lnum].radius;
|
||||
dist = DotProduct (lightorigin, surf->plane->normal) -
|
||||
surf->plane->dist;
|
||||
rad -= fabs (dist);
|
||||
minlight = r_dlights[lnum].minlight;
|
||||
if (rad < minlight)
|
||||
continue;
|
||||
minlight = rad - minlight;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
impact[i] = lightorigin[i] - surf->plane->normal[i] * dist;
|
||||
|
||||
local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
|
||||
local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
|
||||
|
||||
local[0] -= surf->texturemins[0];
|
||||
local[1] -= surf->texturemins[1];
|
||||
|
||||
for (t = 0; t < tmax; t++) {
|
||||
td = local[1] - t * 16;
|
||||
if (td < 0)
|
||||
td = -td;
|
||||
for (s = 0; s < smax; s++) {
|
||||
sd = local[0] - s * 16;
|
||||
if (sd < 0)
|
||||
sd = -sd;
|
||||
if (sd > td)
|
||||
dist = sd + (td >> 1);
|
||||
else
|
||||
dist = td + (sd >> 1);
|
||||
if (dist < minlight)
|
||||
blocklights[t * smax + s] += (rad - dist) * 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
R_BuildLightMap
|
||||
|
||||
Combine and scale multiple lightmaps into the 8.8 format in blocklights
|
||||
*/
|
||||
static void
|
||||
R_BuildLightMap (void)
|
||||
{
|
||||
int smax, tmax;
|
||||
int t;
|
||||
int i, size;
|
||||
byte *lightmap;
|
||||
unsigned int scale;
|
||||
int maps;
|
||||
msurface_t *surf;
|
||||
|
||||
surf = sw32_r_drawsurf.surf;
|
||||
|
||||
smax = (surf->extents[0] >> 4) + 1;
|
||||
tmax = (surf->extents[1] >> 4) + 1;
|
||||
size = smax * tmax;
|
||||
lightmap = surf->samples;
|
||||
|
||||
if (!r_worldentity.renderer.model->brush.lightdata) {
|
||||
for (i = 0; i < size; i++)
|
||||
blocklights[i] = 0;
|
||||
return;
|
||||
}
|
||||
// clear to ambient
|
||||
for (i = 0; i < size; i++)
|
||||
blocklights[i] = r_refdef.ambientlight << 8;
|
||||
|
||||
// add all the lightmaps
|
||||
if (lightmap)
|
||||
for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++) {
|
||||
scale = sw32_r_drawsurf.lightadj[maps]; // 8.8 fraction
|
||||
for (i = 0; i < size; i++)
|
||||
blocklights[i] += lightmap[i] * scale;
|
||||
lightmap += size; // skip to next lightmap
|
||||
}
|
||||
// add all the dynamic lights
|
||||
if (surf->dlightframe == r_framecount)
|
||||
R_AddDynamicLights ();
|
||||
|
||||
/*
|
||||
* JohnnyonFlame:
|
||||
* 32 and 16bpp modes uses the positive lighting, unlike 8bpp
|
||||
*/
|
||||
switch (sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
// bound, invert, and shift
|
||||
for (i = 0; i < size; i++) {
|
||||
t = (255 * 256 - blocklights[i]) >> (8 - VID_CBITS);
|
||||
|
||||
if (t < (1 << 6))
|
||||
t = (1 << 6);
|
||||
|
||||
blocklights[i] = t;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// LordHavoc: changed to positive (not inverse) lighting
|
||||
for (i = 0; i < size; i++) {
|
||||
t = bound(256, blocklights[i] >> (8 - VID_CBITS),
|
||||
256 * (VID_GRADES - 1));
|
||||
blocklights[i] = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sw32_R_DrawSurface (void)
|
||||
{
|
||||
byte *basetptr;
|
||||
int smax, tmax, twidth;
|
||||
int u;
|
||||
int soffset, basetoffset, texwidth;
|
||||
int horzblockstep;
|
||||
byte *pcolumndest;
|
||||
void (*pblockdrawer) (void);
|
||||
texture_t *mt;
|
||||
|
||||
// calculate the lightings
|
||||
R_BuildLightMap ();
|
||||
|
||||
surfrowbytes = sw32_r_drawsurf.rowbytes;
|
||||
|
||||
mt = sw32_r_drawsurf.texture;
|
||||
|
||||
r_source = (byte *) mt + mt->offsets[sw32_r_drawsurf.surfmip];
|
||||
|
||||
// the fractional light values should range from 0 to
|
||||
// (VID_GRADES - 1) << 16 from a source range of 0 - 255
|
||||
|
||||
texwidth = mt->width >> sw32_r_drawsurf.surfmip;
|
||||
|
||||
blocksize = 16 >> sw32_r_drawsurf.surfmip;
|
||||
blockdivshift = 4 - sw32_r_drawsurf.surfmip;
|
||||
blockdivmask = (1 << blockdivshift) - 1;
|
||||
|
||||
r_lightwidth = (sw32_r_drawsurf.surf->extents[0] >> 4) + 1;
|
||||
|
||||
r_numhblocks = sw32_r_drawsurf.surfwidth >> blockdivshift;
|
||||
r_numvblocks = sw32_r_drawsurf.surfheight >> blockdivshift;
|
||||
|
||||
//==============================
|
||||
|
||||
smax = mt->width >> sw32_r_drawsurf.surfmip;
|
||||
twidth = texwidth;
|
||||
tmax = mt->height >> sw32_r_drawsurf.surfmip;
|
||||
sourcetstep = texwidth;
|
||||
r_stepback = tmax * twidth;
|
||||
|
||||
soffset = sw32_r_drawsurf.surf->texturemins[0];
|
||||
basetoffset = sw32_r_drawsurf.surf->texturemins[1];
|
||||
|
||||
switch (sw32_ctx->pixbytes) {
|
||||
case 1:
|
||||
pblockdrawer = surfmiptable8[sw32_r_drawsurf.surfmip];
|
||||
break;
|
||||
case 2:
|
||||
pblockdrawer = surfmiptable16[sw32_r_drawsurf.surfmip];
|
||||
break;
|
||||
case 4:
|
||||
pblockdrawer = surfmiptable32[sw32_r_drawsurf.surfmip];
|
||||
break;
|
||||
default:
|
||||
Sys_Error("R_DrawSurface: unsupported r_pixbytes %i", sw32_ctx->pixbytes);
|
||||
pblockdrawer = NULL;
|
||||
}
|
||||
|
||||
horzblockstep = blocksize * sw32_ctx->pixbytes;
|
||||
|
||||
r_sourcemax = r_source + (tmax * smax);
|
||||
|
||||
// << 16 components are to guarantee positive values for %
|
||||
basetptr = r_source + (((basetoffset >> sw32_r_drawsurf.surfmip) +
|
||||
(tmax << 16)) % tmax) * twidth;
|
||||
soffset = (((soffset >> sw32_r_drawsurf.surfmip) + (smax << 16)) % smax);
|
||||
|
||||
pcolumndest = (byte *) sw32_r_drawsurf.surfdat;
|
||||
|
||||
for (u = 0; u < r_numhblocks; u++) {
|
||||
r_lightptr = blocklights + u;
|
||||
|
||||
prowdestbase = pcolumndest;
|
||||
|
||||
psource = basetptr + soffset;
|
||||
|
||||
(*pblockdrawer) ();
|
||||
|
||||
soffset = soffset + blocksize;
|
||||
if (soffset >= smax)
|
||||
soffset = 0;
|
||||
|
||||
pcolumndest += horzblockstep;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock8_mip0 (void)
|
||||
{
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
lightstep = (lightleft - lightright) >> 4;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 15; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock8_mip1 (void)
|
||||
{
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
lightstep = (lightleft - lightright) >> 3;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 7; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock8_mip2 (void)
|
||||
{
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
lightstep = (lightleft - lightright) >> 2;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 3; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock8_mip3 (void)
|
||||
{
|
||||
int v, i, b, lightstep, light;
|
||||
unsigned char pix, *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
// FIXME: make these locals?
|
||||
// FIXME: use delta rather than both right and left, like ASM?
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
lightstep = (lightleft - lightright) >> 1;
|
||||
|
||||
light = lightright;
|
||||
|
||||
for (b = 1; b >= 0; b--) {
|
||||
pix = psource[b];
|
||||
prowdest[b] = vid.colormap8[(light & 0xFF00) + pix];
|
||||
light += lightstep;
|
||||
}
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += surfrowbytes;
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip0 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (k = 0; k < 16; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 4;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
|
||||
light += lightstep;
|
||||
prowdest[8] = vid.colormap16[(light & 0xFF00) + psource[8]];
|
||||
light += lightstep;
|
||||
prowdest[9] = vid.colormap16[(light & 0xFF00) + psource[9]];
|
||||
light += lightstep;
|
||||
prowdest[10] = vid.colormap16[(light & 0xFF00) + psource[10]];
|
||||
light += lightstep;
|
||||
prowdest[11] = vid.colormap16[(light & 0xFF00) + psource[11]];
|
||||
light += lightstep;
|
||||
prowdest[12] = vid.colormap16[(light & 0xFF00) + psource[12]];
|
||||
light += lightstep;
|
||||
prowdest[13] = vid.colormap16[(light & 0xFF00) + psource[13]];
|
||||
light += lightstep;
|
||||
prowdest[14] = vid.colormap16[(light & 0xFF00) + psource[14]];
|
||||
light += lightstep;
|
||||
prowdest[15] = vid.colormap16[(light & 0xFF00) + psource[15]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip1 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 3;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap16[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap16[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap16[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap16[(light & 0xFF00) + psource[7]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip2 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 2;
|
||||
|
||||
prowdest[0] = vid.colormap16[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap16[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap16[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap16[(light & 0xFF00) + psource[3]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock16_mip3 (void)
|
||||
{
|
||||
int v;
|
||||
unsigned short *prowdest;
|
||||
|
||||
prowdest = (unsigned short *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
|
||||
prowdest[0] = vid.colormap16[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap16[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
prowdest += (surfrowbytes >> 1);
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip0 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 4;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 4;
|
||||
|
||||
for (k = 0; k < 16; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 4;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
|
||||
light += lightstep;
|
||||
prowdest[8] = vid.colormap32[(light & 0xFF00) + psource[8]];
|
||||
light += lightstep;
|
||||
prowdest[9] = vid.colormap32[(light & 0xFF00) + psource[9]];
|
||||
light += lightstep;
|
||||
prowdest[10] = vid.colormap32[(light & 0xFF00) + psource[10]];
|
||||
light += lightstep;
|
||||
prowdest[11] = vid.colormap32[(light & 0xFF00) + psource[11]];
|
||||
light += lightstep;
|
||||
prowdest[12] = vid.colormap32[(light & 0xFF00) + psource[12]];
|
||||
light += lightstep;
|
||||
prowdest[13] = vid.colormap32[(light & 0xFF00) + psource[13]];
|
||||
light += lightstep;
|
||||
prowdest[14] = vid.colormap32[(light & 0xFF00) + psource[14]];
|
||||
light += lightstep;
|
||||
prowdest[15] = vid.colormap32[(light & 0xFF00) + psource[15]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip1 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 3;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 3;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 3;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
light += lightstep;
|
||||
prowdest[4] = vid.colormap32[(light & 0xFF00) + psource[4]];
|
||||
light += lightstep;
|
||||
prowdest[5] = vid.colormap32[(light & 0xFF00) + psource[5]];
|
||||
light += lightstep;
|
||||
prowdest[6] = vid.colormap32[(light & 0xFF00) + psource[6]];
|
||||
light += lightstep;
|
||||
prowdest[7] = vid.colormap32[(light & 0xFF00) + psource[7]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip2 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 2;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 2;
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
light = lightleft;
|
||||
lightstep = (lightright - lightleft) >> 2;
|
||||
|
||||
prowdest[0] = vid.colormap32[(light & 0xFF00) + psource[0]];
|
||||
light += lightstep;
|
||||
prowdest[1] = vid.colormap32[(light & 0xFF00) + psource[1]];
|
||||
light += lightstep;
|
||||
prowdest[2] = vid.colormap32[(light & 0xFF00) + psource[2]];
|
||||
light += lightstep;
|
||||
prowdest[3] = vid.colormap32[(light & 0xFF00) + psource[3]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_DrawSurfaceBlock32_mip3 (void)
|
||||
{
|
||||
int v;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = (unsigned int *) prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++)
|
||||
{
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> 1;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> 1;
|
||||
|
||||
prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
|
||||
prowdest[0] = vid.colormap32[(lightleft & 0xFF00) + psource[0]];
|
||||
prowdest[1] = vid.colormap32[(((lightleft + lightright) >> 1) &
|
||||
0xFF00) + psource[1]];
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
R_DrawSurfaceBlock32 (void)
|
||||
{
|
||||
int k, v;
|
||||
int lightstep, light;
|
||||
unsigned int *prowdest;
|
||||
|
||||
prowdest = prowdestbase;
|
||||
|
||||
for (v = 0; v < r_numvblocks; v++) {
|
||||
|
||||
lightleft = r_lightptr[0];
|
||||
lightright = r_lightptr[1];
|
||||
r_lightptr += r_lightwidth;
|
||||
lightleftstep = (r_lightptr[0] - lightleft) >> blockdivshift;
|
||||
lightrightstep = (r_lightptr[1] - lightright) >> blockdivshift;
|
||||
|
||||
for (k = 0; k < blocksize; k++) {
|
||||
int b;
|
||||
|
||||
lightstep = (lightright - lightleft) >> blockdivshift;
|
||||
|
||||
light = lightleft;
|
||||
|
||||
for (b = 0;b < blocksize;b++, light += lightstep)
|
||||
prowdest[b] = vid.colormap32[(light & 0xFF00) + psource[b]];
|
||||
|
||||
psource += sourcetstep;
|
||||
lightright += lightrightstep;
|
||||
lightleft += lightleftstep;
|
||||
prowdest += (surfrowbytes >> 2);
|
||||
}
|
||||
|
||||
if (psource >= r_sourcemax)
|
||||
psource -= r_stepback;
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
vid_common_sw32.c
|
||||
|
||||
general video driver functions
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/vid.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
|
||||
unsigned short sw32_8to16table[256];
|
||||
|
||||
|
||||
/*
|
||||
VID_MakeColormap32
|
||||
|
||||
LordHavoc: makes a 32bit color*light table, RGBA order, no endian,
|
||||
may need to be re-ordered to hardware at display time
|
||||
*/
|
||||
static void
|
||||
VID_MakeColormap32 (void *outcolormap, byte *pal)
|
||||
{
|
||||
int c, l;
|
||||
byte *out;
|
||||
out = (byte *)&d_8to24table;
|
||||
|
||||
/*
|
||||
* Generates colors not affected by lighting, such as
|
||||
* HUD pieces and general sprites (such as explosions)
|
||||
*/
|
||||
for (c = 0; c < 256; c++) {
|
||||
*out++ = pal[c*3+2];
|
||||
*out++ = pal[c*3+1];
|
||||
*out++ = pal[c*3+0];
|
||||
*out++ = 255;
|
||||
}
|
||||
d_8to24table[255] = 0; // 255 is transparent
|
||||
out = (byte *) outcolormap;
|
||||
|
||||
/*
|
||||
* Generates colors affected by lighting, such as the
|
||||
* world and other models that give it life, like foes and pickups.
|
||||
*/
|
||||
for (l = 0;l < VID_GRADES;l++)
|
||||
{
|
||||
for (c = 0;c < vid.fullbright;c++)
|
||||
{
|
||||
out[(l*256+c)*4+0] = bound(0, (pal[c*3+2] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+1] = bound(0, (pal[c*3+1] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+2] = bound(0, (pal[c*3+0] * l) >> (VID_CBITS - 1),
|
||||
255);
|
||||
out[(l*256+c)*4+3] = 255;
|
||||
}
|
||||
for (;c < 255;c++)
|
||||
{
|
||||
out[(l*256+c)*4+0] = pal[c*3+2];
|
||||
out[(l*256+c)*4+1] = pal[c*3+1];
|
||||
out[(l*256+c)*4+2] = pal[c*3+0];
|
||||
out[(l*256+c)*4+3] = 255;
|
||||
}
|
||||
out[(l*256+255)*4+0] = 0;
|
||||
out[(l*256+255)*4+1] = 0;
|
||||
out[(l*256+255)*4+2] = 0;
|
||||
out[(l*256+255)*4+3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
lh24to16bit (int red, int green, int blue)
|
||||
{
|
||||
red = bound(0, red, 255);
|
||||
green = bound(0, green, 255);
|
||||
blue = bound(0, blue, 255);
|
||||
red >>= 3;
|
||||
green >>= 2;
|
||||
blue >>= 3;
|
||||
red <<= 11;
|
||||
green <<= 5;
|
||||
return (unsigned short) (red | green | blue);
|
||||
}
|
||||
|
||||
/*
|
||||
VID_MakeColormap16
|
||||
|
||||
LordHavoc: makes a 16bit color*light table, RGB order, native endian,
|
||||
may need to be translated to hardware order at display time
|
||||
*/
|
||||
static void
|
||||
VID_MakeColormap16 (void *outcolormap, byte *pal)
|
||||
{
|
||||
int c, l;
|
||||
unsigned short *out;
|
||||
out = (unsigned short *)&sw32_8to16table;
|
||||
for (c = 0; c < 256; c++)
|
||||
*out++ = lh24to16bit(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
|
||||
sw32_8to16table[255] = 0; // 255 is transparent
|
||||
out = (unsigned short *) outcolormap;
|
||||
for (l = 0;l < VID_GRADES;l++)
|
||||
{
|
||||
for (c = 0;c < vid.fullbright;c++)
|
||||
out[l*256+c] = lh24to16bit(
|
||||
(pal[c*3+0] * l) >> (VID_CBITS - 1),
|
||||
(pal[c*3+1] * l) >> (VID_CBITS - 1),
|
||||
(pal[c*3+2] * l) >> (VID_CBITS - 1));
|
||||
for (;c < 255;c++)
|
||||
out[l*256+c] = lh24to16bit(pal[c*3+0], pal[c*3+1], pal[c*3+2]);
|
||||
out[l*256+255] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
VID_MakeColormaps
|
||||
|
||||
LordHavoc: makes 8bit, 16bit, and 32bit colormaps and palettes
|
||||
*/
|
||||
void
|
||||
VID_MakeColormaps (void)
|
||||
{
|
||||
vid.colormap16 = malloc (256*VID_GRADES * sizeof (unsigned short));
|
||||
vid.colormap32 = malloc (256*VID_GRADES * sizeof (unsigned int));
|
||||
SYS_CHECKMEM (vid.colormap16 && vid.colormap32);
|
||||
VID_MakeColormap16(vid.colormap16, vid.palette);
|
||||
VID_MakeColormap32(vid.colormap32, vid.palette);
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
vid_render_gl.c
|
||||
|
||||
SW32 version of the renderer
|
||||
|
||||
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define NH_DEFINE
|
||||
#include "sw32/namehack.h"
|
||||
|
||||
#include "QF/plugin/general.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "mod_internal.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
#include "sw32/namehack.h"
|
||||
|
||||
sw_ctx_t *sw32_ctx;
|
||||
|
||||
static void
|
||||
sw32_vid_render_choose_visual (void *data)
|
||||
{
|
||||
sw32_ctx->choose_visual (sw32_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_vid_render_create_context (void *data)
|
||||
{
|
||||
sw32_ctx->create_context (sw32_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_vid_render_set_palette (void *data, const byte *palette)
|
||||
{
|
||||
sw32_ctx->set_palette (sw32_ctx, palette);
|
||||
}
|
||||
|
||||
static vid_model_funcs_t model_funcs = {
|
||||
0,
|
||||
sw_Mod_LoadLighting,
|
||||
0,//Mod_SubdivideSurface,
|
||||
0,//Mod_ProcessTexture,
|
||||
|
||||
Mod_LoadIQM,
|
||||
Mod_LoadAliasModel,
|
||||
Mod_LoadSpriteModel,
|
||||
|
||||
sw_Mod_MakeAliasModelDisplayLists,
|
||||
sw_Mod_LoadSkin,
|
||||
0,
|
||||
0,
|
||||
sw_Mod_IQMFinish,
|
||||
1,
|
||||
sw_Mod_SpriteLoadFrames,
|
||||
|
||||
Skin_SetColormap,
|
||||
Skin_SetSkin,
|
||||
sw_Skin_SetupSkin,
|
||||
Skin_SetTranslation,
|
||||
sw_Skin_ProcessTranslation,
|
||||
sw_Skin_InitTranslations,
|
||||
};
|
||||
|
||||
static void
|
||||
sw32_vid_render_init (void)
|
||||
{
|
||||
if (!vr_data.vid->vid_internal->sw_context) {
|
||||
Sys_Error ("Sorry, software rendering not supported by this program.");
|
||||
}
|
||||
sw32_ctx = vr_data.vid->vid_internal->sw32_context ();
|
||||
|
||||
vr_data.vid->vid_internal->data = sw32_ctx;
|
||||
vr_data.vid->vid_internal->set_palette = sw32_vid_render_set_palette;
|
||||
vr_data.vid->vid_internal->choose_visual = sw32_vid_render_choose_visual;
|
||||
vr_data.vid->vid_internal->create_context = sw32_vid_render_create_context;
|
||||
|
||||
vr_funcs = &sw32_vid_render_funcs;
|
||||
m_funcs = &model_funcs;
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_vid_render_shutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_begin_frame (void)
|
||||
{
|
||||
if (vr_data.scr_fullupdate++ < vid.numpages) { // clear the entire screen
|
||||
vr_data.scr_copyeverything = 1;
|
||||
sw32_Draw_TileClear (0, 0, vid.width, vid.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_render_view (void)
|
||||
{
|
||||
sw32_R_RenderView ();
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_set_2d (void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
sw32_end_frame (void)
|
||||
{
|
||||
// update one of three areas
|
||||
vrect_t vrect;
|
||||
if (vr_data.scr_copyeverything) {
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height;
|
||||
vrect.next = 0;
|
||||
} else if (scr_copytop) {
|
||||
vrect.x = 0;
|
||||
vrect.y = 0;
|
||||
vrect.width = vid.width;
|
||||
vrect.height = vid.height - vr_data.lineadj;
|
||||
vrect.next = 0;
|
||||
} else {
|
||||
vrect.x = vr_data.scr_view->xpos;
|
||||
vrect.y = vr_data.scr_view->ypos;
|
||||
vrect.width = vr_data.scr_view->xlen;
|
||||
vrect.height = vr_data.scr_view->ylen;
|
||||
vrect.next = 0;
|
||||
}
|
||||
sw32_ctx->update (sw32_ctx, &vrect);
|
||||
}
|
||||
|
||||
vid_render_funcs_t sw32_vid_render_funcs = {
|
||||
sw32_vid_render_init,
|
||||
sw32_Draw_Character,
|
||||
sw32_Draw_String,
|
||||
sw32_Draw_nString,
|
||||
sw32_Draw_AltString,
|
||||
sw32_Draw_ConsoleBackground,
|
||||
sw32_Draw_Crosshair,
|
||||
sw32_Draw_CrosshairAt,
|
||||
sw32_Draw_TileClear,
|
||||
sw32_Draw_Fill,
|
||||
sw32_Draw_TextBox,
|
||||
sw32_Draw_FadeScreen,
|
||||
sw32_Draw_BlendScreen,
|
||||
sw32_Draw_CachePic,
|
||||
sw32_Draw_UncachePic,
|
||||
sw32_Draw_MakePic,
|
||||
sw32_Draw_DestroyPic,
|
||||
sw32_Draw_PicFromWad,
|
||||
sw32_Draw_Pic,
|
||||
sw32_Draw_Picf,
|
||||
sw32_Draw_SubPic,
|
||||
|
||||
sw32_SCR_CaptureBGR,
|
||||
|
||||
sw32_ParticleSystem,
|
||||
sw32_R_Init,
|
||||
sw32_R_ClearState,
|
||||
sw32_R_LoadSkys,
|
||||
sw32_R_NewMap,
|
||||
sw32_R_LineGraph,
|
||||
sw32_R_ViewChanged,
|
||||
sw32_begin_frame,
|
||||
sw32_render_view,
|
||||
sw32_set_2d,
|
||||
sw32_end_frame,
|
||||
&model_funcs
|
||||
};
|
||||
|
||||
static general_funcs_t plugin_info_general_funcs = {
|
||||
.shutdown = sw32_vid_render_shutdown,
|
||||
};
|
||||
|
||||
static general_data_t plugin_info_general_data;
|
||||
|
||||
static plugin_funcs_t plugin_info_funcs = {
|
||||
.general = &plugin_info_general_funcs,
|
||||
.vid_render = &sw32_vid_render_funcs,
|
||||
};
|
||||
|
||||
static plugin_data_t plugin_info_data = {
|
||||
.general = &plugin_info_general_data,
|
||||
.vid_render = &vid_render_data,
|
||||
};
|
||||
|
||||
static plugin_t plugin_info = {
|
||||
qfp_vid_render,
|
||||
0,
|
||||
QFPLUGIN_VERSION,
|
||||
"0.1",
|
||||
"SW32 Renderer",
|
||||
"Copyright (C) 1996-1997 Id Software, Inc.\n"
|
||||
"Copyright (C) 1999-2012 contributors of the QuakeForge project\n"
|
||||
"Please see the file \"AUTHORS\" for a list of contributors",
|
||||
&plugin_info_funcs,
|
||||
&plugin_info_data,
|
||||
};
|
||||
|
||||
PLUGIN_INFO(vid_render, sw32)
|
||||
{
|
||||
return &plugin_info;
|
||||
}
|
|
@ -110,8 +110,6 @@ modestate_t modestate = MS_UNINIT;
|
|||
|
||||
byte vid_curpal[256 * 3];
|
||||
|
||||
unsigned short d_8to16table[256];
|
||||
|
||||
int mode;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -101,7 +101,6 @@ VID_Init (byte *palette, byte *colormap)
|
|||
|
||||
vid_internal.gl_context = X11_GL_Context;
|
||||
vid_internal.sw_context = X11_SW_Context;
|
||||
vid_internal.sw32_context = X11_SW32_Context;
|
||||
#ifdef HAVE_VULKAN
|
||||
vid_internal.vulkan_context = X11_Vulkan_Context;
|
||||
#endif
|
||||
|
|
|
@ -642,18 +642,6 @@ x11_create_context (sw_ctx_t *ctx)
|
|||
|
||||
sw_ctx_t *
|
||||
X11_SW_Context (void)
|
||||
{
|
||||
sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t));
|
||||
ctx->pixbytes = 1;
|
||||
ctx->set_palette = x11_set_palette;
|
||||
ctx->choose_visual = x11_choose_visual;
|
||||
ctx->create_context = x11_create_context;
|
||||
ctx->update = x11_sw8_update;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
sw_ctx_t *
|
||||
X11_SW32_Context (void)
|
||||
{
|
||||
sw_ctx_t *ctx = calloc (1, sizeof (sw_ctx_t));
|
||||
ctx->pixbytes = 1;
|
||||
|
|
Loading…
Reference in a new issue