mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-24 21:31:46 +00:00
Software multithread
This commit is contained in:
parent
06dfd360ee
commit
3a9987e390
49 changed files with 3969 additions and 8332 deletions
|
@ -8,8 +8,6 @@ target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in)
|
||||||
|
|
||||||
set(SRB2_ASM_SOURCES vid_copy.s)
|
set(SRB2_ASM_SOURCES vid_copy.s)
|
||||||
|
|
||||||
set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas)
|
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL
|
set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL
|
||||||
"Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.")
|
"Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.")
|
||||||
|
@ -213,8 +211,7 @@ if(${SRB2_CONFIG_USEASM})
|
||||||
target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM)
|
target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse")
|
||||||
|
|
||||||
target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES}
|
target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES})
|
||||||
${SRB2_NASM_SOURCES})
|
|
||||||
else()
|
else()
|
||||||
set(SRB2_USEASM OFF)
|
set(SRB2_USEASM OFF)
|
||||||
target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM)
|
target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM)
|
||||||
|
|
|
@ -210,7 +210,7 @@ sources+=\
|
||||||
$(call List,blua/Sourcefile)\
|
$(call List,blua/Sourcefile)\
|
||||||
|
|
||||||
depends:=$(basename $(filter %.c %.s,$(sources)))
|
depends:=$(basename $(filter %.c %.s,$(sources)))
|
||||||
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
|
objects:=$(basename $(filter %.c %.s,$(sources)))
|
||||||
|
|
||||||
depends:=$(depends:%=$(depdir)/%.d)
|
depends:=$(depends:%=$(depdir)/%.d)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ endif
|
||||||
|
|
||||||
ifndef NOASM
|
ifndef NOASM
|
||||||
ifndef NONX86
|
ifndef NONX86
|
||||||
sources+=tmap.nas tmap_mmx.nas
|
|
||||||
opts+=-DUSEASM
|
opts+=-DUSEASM
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -511,8 +511,10 @@ static void D_Display(void)
|
||||||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime;
|
||||||
|
|
||||||
// Image postprocessing effect
|
// Image postprocessing effect
|
||||||
|
ps_postprocesstime = I_GetPreciseTime();
|
||||||
if (rendermode == render_soft)
|
if (rendermode == render_soft)
|
||||||
{
|
{
|
||||||
if (!splitscreen)
|
if (!splitscreen)
|
||||||
|
@ -523,7 +525,7 @@ static void D_Display(void)
|
||||||
if (postimgtype2)
|
if (postimgtype2)
|
||||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||||
}
|
}
|
||||||
ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime;
|
ps_postprocesstime = I_GetPreciseTime() - ps_postprocesstime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastdraw)
|
if (lastdraw)
|
||||||
|
|
|
@ -537,6 +537,9 @@ INT32 I_GetKey(void);
|
||||||
// Max gamepad/joysticks that can be detected/used.
|
// Max gamepad/joysticks that can be detected/used.
|
||||||
#define MAX_JOYSTICKS 4
|
#define MAX_JOYSTICKS 4
|
||||||
|
|
||||||
|
// Software multithreading
|
||||||
|
#define MAX_RENDER_THREADS 8
|
||||||
|
|
||||||
#ifndef M_PIl
|
#ifndef M_PIl
|
||||||
#define M_PIl 3.1415926535897932384626433832795029L
|
#define M_PIl 3.1415926535897932384626433832795029L
|
||||||
#endif
|
#endif
|
||||||
|
@ -608,13 +611,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
|
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
|
||||||
//#define PAPER_COLLISIONCORRECTION
|
//#define PAPER_COLLISIONCORRECTION
|
||||||
|
|
||||||
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
|
|
||||||
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
|
|
||||||
/// on the bright side it fixes some weird issues with translucent walls
|
|
||||||
/// \note SRB2CB port.
|
|
||||||
/// SRB2CB itself ported this from PrBoom+
|
|
||||||
#define NEWCLIP
|
|
||||||
|
|
||||||
/// OpenGL shaders
|
/// OpenGL shaders
|
||||||
#define GL_SHADERS
|
#define GL_SHADERS
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,6 @@ void HWR_ClearSkyDome(void);
|
||||||
void HWR_BuildSkyDome(void);
|
void HWR_BuildSkyDome(void);
|
||||||
void HWR_DrawViewBorder(INT32 clearlines);
|
void HWR_DrawViewBorder(INT32 clearlines);
|
||||||
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
|
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
|
||||||
void HWR_InitTextureMapping(void);
|
|
||||||
void HWR_SetViewSize(void);
|
void HWR_SetViewSize(void);
|
||||||
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
|
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
|
||||||
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
|
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
|
||||||
|
|
|
@ -15,6 +15,17 @@
|
||||||
#define I_THREADS_H
|
#define I_THREADS_H
|
||||||
|
|
||||||
typedef void (*I_thread_fn)(void *userdata);
|
typedef void (*I_thread_fn)(void *userdata);
|
||||||
|
typedef void * I_thread_handle;
|
||||||
|
|
||||||
|
#ifdef HAVE_SDL
|
||||||
|
#include <SDL.h>
|
||||||
|
#define ATOMIC_TYPE SDL_atomic_t
|
||||||
|
#else
|
||||||
|
#define ATOMIC_TYPE UINT32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef ATOMIC_TYPE I_Atomicval_t;
|
||||||
|
typedef I_Atomicval_t * I_Atomicptr_t;
|
||||||
|
|
||||||
typedef void * I_mutex;
|
typedef void * I_mutex;
|
||||||
typedef void * I_cond;
|
typedef void * I_cond;
|
||||||
|
@ -22,7 +33,7 @@ typedef void * I_cond;
|
||||||
void I_start_threads (void);
|
void I_start_threads (void);
|
||||||
void I_stop_threads (void);
|
void I_stop_threads (void);
|
||||||
|
|
||||||
void I_spawn_thread (const char *name, I_thread_fn, void *userdata);
|
I_thread_handle I_spawn_thread (const char *name, I_thread_fn, void *userdata);
|
||||||
|
|
||||||
/* check in your thread whether to return early */
|
/* check in your thread whether to return early */
|
||||||
int I_thread_is_stopped (void);
|
int I_thread_is_stopped (void);
|
||||||
|
@ -35,5 +46,8 @@ void I_hold_cond (I_cond *, I_mutex);
|
||||||
void I_wake_one_cond (I_cond *);
|
void I_wake_one_cond (I_cond *);
|
||||||
void I_wake_all_cond (I_cond *);
|
void I_wake_all_cond (I_cond *);
|
||||||
|
|
||||||
|
INT32 I_atomic_load (I_Atomicptr_t atomic);
|
||||||
|
INT32 I_atomic_exchange (I_Atomicptr_t atomic, INT32 val);
|
||||||
|
|
||||||
#endif/*I_THREADS_H*/
|
#endif/*I_THREADS_H*/
|
||||||
#endif/*HAVE_THREADS*/
|
#endif/*HAVE_THREADS*/
|
||||||
|
|
|
@ -100,7 +100,30 @@ enum {
|
||||||
PERF_COUNT,
|
PERF_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void M_DrawPerfString(perfstatcol_t *col, int type)
|
static void M_DrawPerfString(const char *string, INT32 lores_x, INT32 hires_x, INT32 flags)
|
||||||
|
{
|
||||||
|
const boolean hires = M_HighResolution();
|
||||||
|
|
||||||
|
INT32 draw_flags = V_MONOSPACE | flags;
|
||||||
|
|
||||||
|
if (hires)
|
||||||
|
draw_flags |= V_ALLOWLOWERCASE;
|
||||||
|
|
||||||
|
if (hires)
|
||||||
|
{
|
||||||
|
V_DrawFillConsoleMap(hires_x, draw_row, V_SmallStringWidth(string, draw_flags), 5, 0);
|
||||||
|
V_DrawSmallString(hires_x, draw_row, draw_flags, string);
|
||||||
|
draw_row += 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
V_DrawFillConsoleMap(lores_x, draw_row, V_ThinStringWidth(string, draw_flags), 8, 0);
|
||||||
|
V_DrawThinString(lores_x, draw_row, draw_flags, string);
|
||||||
|
draw_row += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M_DrawPerfMeasurement(perfstatcol_t *col, int type)
|
||||||
{
|
{
|
||||||
const boolean hires = M_HighResolution();
|
const boolean hires = M_HighResolution();
|
||||||
|
|
||||||
|
@ -122,15 +145,19 @@ static void M_DrawPerfString(perfstatcol_t *col, int type)
|
||||||
|
|
||||||
if (hires)
|
if (hires)
|
||||||
{
|
{
|
||||||
V_DrawSmallString(col->hires_x, draw_row, draw_flags,
|
const char *string = va("%s %d", row->hires_label, value);
|
||||||
va("%s %d", row->hires_label, value));
|
|
||||||
|
V_DrawFillConsoleMap(col->hires_x, draw_row, V_SmallStringWidth(string, draw_flags), 5, 0);
|
||||||
|
V_DrawSmallString(col->hires_x, draw_row, draw_flags, string);
|
||||||
|
|
||||||
draw_row += 5;
|
draw_row += 5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
V_DrawThinString(col->lores_x, draw_row, draw_flags,
|
const char *string = va("%s %d", row->lores_label, value);
|
||||||
va("%s %d", row->lores_label, value));
|
|
||||||
|
V_DrawFillConsoleMap(col->lores_x, draw_row, V_SmallStringWidth(string, draw_flags), 8, 0);
|
||||||
|
V_DrawThinString(col->lores_x, draw_row, draw_flags, string);
|
||||||
|
|
||||||
draw_row += 8;
|
draw_row += 8;
|
||||||
}
|
}
|
||||||
|
@ -139,12 +166,12 @@ static void M_DrawPerfString(perfstatcol_t *col, int type)
|
||||||
|
|
||||||
static void M_DrawPerfTiming(perfstatcol_t *col)
|
static void M_DrawPerfTiming(perfstatcol_t *col)
|
||||||
{
|
{
|
||||||
M_DrawPerfString(col, PERF_TIME);
|
M_DrawPerfMeasurement(col, PERF_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DrawPerfCount(perfstatcol_t *col)
|
static void M_DrawPerfCount(perfstatcol_t *col)
|
||||||
{
|
{
|
||||||
M_DrawPerfString(col, PERF_COUNT);
|
M_DrawPerfMeasurement(col, PERF_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DrawRenderStats(void)
|
static void M_DrawRenderStats(void)
|
||||||
|
@ -161,7 +188,7 @@ static void M_DrawRenderStats(void)
|
||||||
};
|
};
|
||||||
|
|
||||||
perfstatrow_t rendercalltime_row[] = {
|
perfstatrow_t rendercalltime_row[] = {
|
||||||
{"drwtime", "3d rendering: ", &ps_rendercalltime},
|
{"drwtime", "3D rendering: ", &ps_rendercalltime},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,16 +203,6 @@ static void M_DrawRenderStats(void)
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
perfstatrow_t softwaretime_row[] = {
|
|
||||||
{"bsptime", "RenderBSPNode: ", &ps_bsptime},
|
|
||||||
{"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime},
|
|
||||||
{"portals", "Portals+Skybox:", &ps_sw_portaltime},
|
|
||||||
{"planes ", "R_DrawPlanes: ", &ps_sw_planetime},
|
|
||||||
{"masked ", "R_DrawMasked: ", &ps_sw_maskedtime},
|
|
||||||
{"other ", "Other: ", &extrarendertime},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
perfstatrow_t uiswaptime_row[] = {
|
perfstatrow_t uiswaptime_row[] = {
|
||||||
{"ui ", "UI render: ", &ps_uitime},
|
{"ui ", "UI render: ", &ps_uitime},
|
||||||
{"finupdt", "I_FinishUpdate:", &ps_swaptime},
|
{"finupdt", "I_FinishUpdate:", &ps_swaptime},
|
||||||
|
@ -197,14 +214,6 @@ static void M_DrawRenderStats(void)
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
perfstatrow_t rendercalls_row[] = {
|
|
||||||
{"bspcall", "BSP calls: ", &ps_numbspcalls},
|
|
||||||
{"sprites", "Sprites: ", &ps_numsprites},
|
|
||||||
{"drwnode", "Drawnodes: ", &ps_numdrawnodes},
|
|
||||||
{"plyobjs", "Polyobjects: ", &ps_numpolyobjects},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
perfstatrow_t batchtime_row[] = {
|
perfstatrow_t batchtime_row[] = {
|
||||||
{"batsort", "Batch sort: ", &ps_hw_batchsorttime},
|
{"batsort", "Batch sort: ", &ps_hw_batchsorttime},
|
||||||
{"batdraw", "Batch render:", &ps_hw_batchdrawtime},
|
{"batdraw", "Batch render:", &ps_hw_batchdrawtime},
|
||||||
|
@ -230,13 +239,10 @@ static void M_DrawRenderStats(void)
|
||||||
perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row};
|
perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row};
|
||||||
|
|
||||||
perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row};
|
perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row};
|
||||||
perfstatcol_t softwaretime_col = {24, 24, V_YELLOWMAP, softwaretime_row};
|
|
||||||
|
|
||||||
perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row};
|
perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row};
|
||||||
perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row};
|
perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row};
|
||||||
|
|
||||||
perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row};
|
|
||||||
|
|
||||||
perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row};
|
perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row};
|
||||||
|
|
||||||
perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row};
|
perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row};
|
||||||
|
@ -256,12 +262,13 @@ static void M_DrawRenderStats(void)
|
||||||
M_DrawPerfTiming(&rendercalltime_col);
|
M_DrawPerfTiming(&rendercalltime_col);
|
||||||
|
|
||||||
// Remember to update this calculation when adding more 3d rendering stats!
|
// Remember to update this calculation when adding more 3d rendering stats!
|
||||||
extrarendertime = ps_rendercalltime - ps_bsptime;
|
extrarendertime = ps_rendercalltime;
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
if (rendermode == render_opengl)
|
if (rendermode == render_opengl)
|
||||||
{
|
{
|
||||||
extrarendertime -=
|
extrarendertime =
|
||||||
|
ps_bsptime[0] +
|
||||||
ps_hw_skyboxtime +
|
ps_hw_skyboxtime +
|
||||||
ps_hw_nodesorttime +
|
ps_hw_nodesorttime +
|
||||||
ps_hw_nodedrawtime +
|
ps_hw_nodedrawtime +
|
||||||
|
@ -280,14 +287,33 @@ static void M_DrawRenderStats(void)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
extrarendertime -=
|
INT32 i = 0;
|
||||||
ps_sw_spritecliptime +
|
|
||||||
ps_sw_portaltime +
|
|
||||||
ps_sw_planetime +
|
|
||||||
ps_sw_maskedtime;
|
|
||||||
|
|
||||||
|
perfstatrow_t other_row[] = {
|
||||||
|
{"postprc", "Postprocessing:", &ps_postprocesstime},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
perfstatcol_t other_col = {24, 24, V_YELLOWMAP, other_row};
|
||||||
|
|
||||||
|
for (i = 0; i < numusablerendercontexts; i++) {
|
||||||
|
perfstatrow_t softwaretime_row[] = {
|
||||||
|
{"bsptime", "RenderBSPNode: ", &ps_bsptime[i]},
|
||||||
|
{"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime[i]},
|
||||||
|
{"portals", "Portals+Skybox:", &ps_sw_portaltime[i]},
|
||||||
|
{"planes ", "R_DrawPlanes: ", &ps_sw_planetime[i]},
|
||||||
|
{"masked ", "R_DrawMasked: ", &ps_sw_maskedtime[i]},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
perfstatcol_t softwaretime_col = {28, 28, V_YELLOWMAP, softwaretime_row};
|
||||||
|
|
||||||
|
M_DrawPerfString(va("Thread %d:", i+1), 24, 24, V_REDMAP);
|
||||||
M_DrawPerfTiming(&softwaretime_col);
|
M_DrawPerfTiming(&softwaretime_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_DrawPerfTiming(&other_col);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
M_DrawPerfTiming(&uiswaptime_col);
|
M_DrawPerfTiming(&uiswaptime_col);
|
||||||
|
@ -298,7 +324,40 @@ static void M_DrawRenderStats(void)
|
||||||
if (rendering)
|
if (rendering)
|
||||||
{
|
{
|
||||||
draw_row = 10;
|
draw_row = 10;
|
||||||
|
|
||||||
|
#ifdef HWRENDER
|
||||||
|
if (rendermode == render_opengl) {
|
||||||
|
perfstatrow_t rendercalls_row[] = {
|
||||||
|
{"bspcall", "BSP calls: ", &ps_numbspcalls},
|
||||||
|
{"sprites", "Sprites: ", &ps_numsprites},
|
||||||
|
{"drwnode", "Drawnodes: ", &ps_numdrawnodes},
|
||||||
|
{"plyobjs", "Polyobjects: ", &ps_numpolyobjects},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row};
|
||||||
|
|
||||||
M_DrawPerfCount(&rendercalls_col);
|
M_DrawPerfCount(&rendercalls_col);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < numusablerendercontexts; i++) {
|
||||||
|
perfstatrow_t rendercalls_row[] = {
|
||||||
|
{"bspcall", "BSP calls: ", &ps_numbspcalls[i]},
|
||||||
|
{"sprites", "Sprites: ", &ps_numsprites[i]},
|
||||||
|
{"drwnode", "Drawnodes: ", &ps_numdrawnodes[i]},
|
||||||
|
{"plyobjs", "Polyobjects: ", &ps_numpolyobjects[i]},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
perfstatcol_t rendercalls_col = {94, 120, V_BLUEMAP, rendercalls_row};
|
||||||
|
|
||||||
|
M_DrawPerfString(va("Thread %d:", i+1), 90, 115, V_REDMAP);
|
||||||
|
M_DrawPerfCount(&rendercalls_col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
if (rendermode == render_opengl && cv_glbatching.value)
|
if (rendermode == render_opengl && cv_glbatching.value)
|
||||||
|
|
388
src/r_bsp.c
388
src/r_bsp.c
|
@ -23,50 +23,37 @@
|
||||||
#include "z_zone.h" // Check R_Prep3DFloors
|
#include "z_zone.h" // Check R_Prep3DFloors
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
|
|
||||||
seg_t *curline;
|
#ifdef HAVE_THREADS
|
||||||
side_t *sidedef;
|
static I_mutex R_BSP_mutex;
|
||||||
line_t *linedef;
|
# define Lock_state() I_lock_mutex(&R_BSP_mutex)
|
||||||
sector_t *frontsector;
|
# define Unlock_state() I_unlock_mutex(R_BSP_mutex)
|
||||||
sector_t *backsector;
|
#else
|
||||||
|
# define Lock_state()
|
||||||
// very ugly realloc() of drawsegs at run-time, I upped it to 512
|
# define Unlock_state()
|
||||||
// instead of 256.. and someone managed to send me a level with
|
#endif
|
||||||
// 896 drawsegs! So too bad here's a limit removal a-la-Boom
|
|
||||||
drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for masked drawsegs. */
|
|
||||||
drawseg_t *drawsegs = NULL;
|
|
||||||
drawseg_t *ds_p = NULL;
|
|
||||||
|
|
||||||
// indicates doors closed wrt automap bugfix:
|
|
||||||
INT32 doorclosed;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ClearDrawSegs
|
// R_ClearDrawSegs
|
||||||
//
|
//
|
||||||
void R_ClearDrawSegs(void)
|
void R_ClearDrawSegs(bspcontext_t *context)
|
||||||
{
|
{
|
||||||
ds_p = drawsegs;
|
context->ds_p = context->drawsegs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix from boom.
|
|
||||||
#define MAXSEGS (MAXVIDWIDTH/2+1)
|
|
||||||
|
|
||||||
// newend is one past the last valid seg
|
|
||||||
static cliprange_t *newend;
|
|
||||||
static cliprange_t solidsegs[MAXSEGS];
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ClipSolidWallSegment
|
// R_ClipSolidWallSegment
|
||||||
// Does handle solid walls,
|
// Does handle solid walls,
|
||||||
// e.g. single sided LineDefs (middle texture)
|
// e.g. single sided LineDefs (middle texture)
|
||||||
// that entirely block the view.
|
// that entirely block the view.
|
||||||
//
|
//
|
||||||
static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
static void R_ClipSolidWallSegment(rendercontext_t *context, wallcontext_t *wallcontext, INT32 first, INT32 last)
|
||||||
{
|
{
|
||||||
|
bspcontext_t *bspcontext = &context->bspcontext;
|
||||||
cliprange_t *next;
|
cliprange_t *next;
|
||||||
cliprange_t *start;
|
cliprange_t *start;
|
||||||
|
|
||||||
// Find the first range that touches the range (adjacent pixels are touching).
|
// Find the first range that touches the range (adjacent pixels are touching).
|
||||||
start = solidsegs;
|
start = bspcontext->solidsegs;
|
||||||
while (start->last < first - 1)
|
while (start->last < first - 1)
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
|
@ -75,11 +62,11 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
if (last < start->first - 1)
|
if (last < start->first - 1)
|
||||||
{
|
{
|
||||||
// Post is entirely visible (above start), so insert a new clippost.
|
// Post is entirely visible (above start), so insert a new clippost.
|
||||||
R_StoreWallRange(first, last);
|
R_StoreWallRange(context, wallcontext, first, last);
|
||||||
next = newend;
|
next = bspcontext->newend;
|
||||||
newend++;
|
bspcontext->newend++;
|
||||||
// NO MORE CRASHING!
|
// NO MORE CRASHING!
|
||||||
if (newend - solidsegs > MAXSEGS)
|
if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS)
|
||||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||||
|
|
||||||
while (next != start)
|
while (next != start)
|
||||||
|
@ -93,7 +80,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment above *start.
|
// There is a fragment above *start.
|
||||||
R_StoreWallRange(first, start->first - 1);
|
R_StoreWallRange(context, wallcontext, first, start->first - 1);
|
||||||
// Now adjust the clip size.
|
// Now adjust the clip size.
|
||||||
start->first = first;
|
start->first = first;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +93,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
while (last >= (next+1)->first - 1)
|
while (last >= (next+1)->first - 1)
|
||||||
{
|
{
|
||||||
// There is a fragment between two posts.
|
// There is a fragment between two posts.
|
||||||
R_StoreWallRange(next->last + 1, (next+1)->first - 1);
|
R_StoreWallRange(context, wallcontext, next->last + 1, (next+1)->first - 1);
|
||||||
next++;
|
next++;
|
||||||
|
|
||||||
if (last <= next->last)
|
if (last <= next->last)
|
||||||
|
@ -119,7 +106,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment after *next.
|
// There is a fragment after *next.
|
||||||
R_StoreWallRange(next->last + 1, last);
|
R_StoreWallRange(context, wallcontext, next->last + 1, last);
|
||||||
// Adjust the clip size.
|
// Adjust the clip size.
|
||||||
start->last = last;
|
start->last = last;
|
||||||
|
|
||||||
|
@ -128,13 +115,13 @@ crunch:
|
||||||
if (next == start)
|
if (next == start)
|
||||||
return; // Post just extended past the bottom of one post.
|
return; // Post just extended past the bottom of one post.
|
||||||
|
|
||||||
while (next++ != newend)
|
while (next++ != bspcontext->newend)
|
||||||
*++start = *next; // Remove a post.
|
*++start = *next; // Remove a post.
|
||||||
|
|
||||||
newend = start + 1;
|
bspcontext->newend = start + 1;
|
||||||
|
|
||||||
// NO MORE CRASHING!
|
// NO MORE CRASHING!
|
||||||
if (newend - solidsegs > MAXSEGS)
|
if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS)
|
||||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,13 +130,13 @@ crunch:
|
||||||
// Clips the given range of columns, but does not include it in the clip list.
|
// Clips the given range of columns, but does not include it in the clip list.
|
||||||
// Does handle windows, e.g. LineDefs with upper and lower texture.
|
// Does handle windows, e.g. LineDefs with upper and lower texture.
|
||||||
//
|
//
|
||||||
static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
static inline void R_ClipPassWallSegment(rendercontext_t *context, wallcontext_t *wallcontext, INT32 first, INT32 last)
|
||||||
{
|
{
|
||||||
cliprange_t *start;
|
cliprange_t *start;
|
||||||
|
|
||||||
// Find the first range that touches the range
|
// Find the first range that touches the range
|
||||||
// (adjacent pixels are touching).
|
// (adjacent pixels are touching).
|
||||||
start = solidsegs;
|
start = context->bspcontext.solidsegs;
|
||||||
while (start->last < first - 1)
|
while (start->last < first - 1)
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
|
@ -158,12 +145,12 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
if (last < start->first - 1)
|
if (last < start->first - 1)
|
||||||
{
|
{
|
||||||
// Post is entirely visible (above start).
|
// Post is entirely visible (above start).
|
||||||
R_StoreWallRange(first, last);
|
R_StoreWallRange(context, wallcontext, first, last);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment above *start.
|
// There is a fragment above *start.
|
||||||
R_StoreWallRange(first, start->first - 1);
|
R_StoreWallRange(context, wallcontext, first, start->first - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom contained in start?
|
// Bottom contained in start?
|
||||||
|
@ -173,7 +160,7 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
while (last >= (start+1)->first - 1)
|
while (last >= (start+1)->first - 1)
|
||||||
{
|
{
|
||||||
// There is a fragment between two posts.
|
// There is a fragment between two posts.
|
||||||
R_StoreWallRange(start->last + 1, (start+1)->first - 1);
|
R_StoreWallRange(context, wallcontext, start->last + 1, (start+1)->first - 1);
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
if (last <= start->last)
|
if (last <= start->last)
|
||||||
|
@ -181,27 +168,19 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment after *next.
|
// There is a fragment after *next.
|
||||||
R_StoreWallRange(start->last + 1, last);
|
R_StoreWallRange(context, wallcontext, start->last + 1, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ClearClipSegs
|
// R_ClearClipSegs
|
||||||
//
|
//
|
||||||
void R_ClearClipSegs(void)
|
void R_ClearClipSegs(bspcontext_t *context, INT32 start, INT32 end)
|
||||||
{
|
{
|
||||||
solidsegs[0].first = -0x7fffffff;
|
context->solidsegs[0].first = -0x7fffffff;
|
||||||
solidsegs[0].last = -1;
|
context->solidsegs[0].last = start-1;
|
||||||
solidsegs[1].first = viewwidth;
|
context->solidsegs[1].first = end;
|
||||||
solidsegs[1].last = 0x7fffffff;
|
context->solidsegs[1].last = 0x7fffffff;
|
||||||
newend = solidsegs + 2;
|
context->newend = context->solidsegs + 2;
|
||||||
}
|
|
||||||
void R_PortalClearClipSegs(INT32 start, INT32 end)
|
|
||||||
{
|
|
||||||
solidsegs[0].first = -0x7fffffff;
|
|
||||||
solidsegs[0].last = start-1;
|
|
||||||
solidsegs[1].first = end;
|
|
||||||
solidsegs[1].last = 0x7fffffff;
|
|
||||||
newend = solidsegs + 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,17 +191,17 @@ void R_PortalClearClipSegs(INT32 start, INT32 end)
|
||||||
//
|
//
|
||||||
// It assumes that Doom has already ruled out a door being closed because
|
// It assumes that Doom has already ruled out a door being closed because
|
||||||
// of front-back closure (e.g. front floor is taller than back ceiling).
|
// of front-back closure (e.g. front floor is taller than back ceiling).
|
||||||
static INT32 R_DoorClosed(void)
|
static INT32 R_DoorClosed(bspcontext_t *bspcontext)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
||||||
// if door is closed because back is shut:
|
// if door is closed because back is shut:
|
||||||
backsector->ceilingheight <= backsector->floorheight
|
bspcontext->backsector->ceilingheight <= bspcontext->backsector->floorheight
|
||||||
|
|
||||||
// preserve a kind of transparent door/lift special effect:
|
// preserve a kind of transparent door/lift special effect:
|
||||||
&& (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture)
|
&& (bspcontext->backsector->ceilingheight >= bspcontext->frontsector->ceilingheight || bspcontext->curline->sidedef->toptexture)
|
||||||
|
|
||||||
&& (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture);
|
&& (bspcontext->backsector->floorheight <= bspcontext->frontsector->floorheight || bspcontext->curline->sidedef->bottomtexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -233,8 +212,8 @@ static INT32 R_DoorClosed(void)
|
||||||
//
|
//
|
||||||
// Similar for ceiling, only reflected.
|
// Similar for ceiling, only reflected.
|
||||||
//
|
//
|
||||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
sector_t *R_FakeFlat(viewcontext_t *viewcontext, sector_t *sec, sector_t *tempsec,
|
||||||
INT32 *ceilinglightlevel, boolean back)
|
INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back)
|
||||||
{
|
{
|
||||||
if (floorlightlevel)
|
if (floorlightlevel)
|
||||||
*floorlightlevel = sec->floorlightsec == -1 ?
|
*floorlightlevel = sec->floorlightsec == -1 ?
|
||||||
|
@ -250,19 +229,19 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
if (!sec->extra_colormap && sec->heightsec != -1)
|
if (!sec->extra_colormap && sec->heightsec != -1)
|
||||||
{
|
{
|
||||||
const sector_t *s = §ors[sec->heightsec];
|
const sector_t *s = §ors[sec->heightsec];
|
||||||
mobj_t *viewmobj = viewplayer->mo;
|
mobj_t *viewmobj = viewcontext->player->mo;
|
||||||
INT32 heightsec;
|
INT32 heightsec;
|
||||||
boolean underwater;
|
boolean underwater;
|
||||||
|
|
||||||
if (splitscreen && viewplayer == &players[secondarydisplayplayer] && camera2.chase)
|
if (splitscreen && viewcontext->player == &players[secondarydisplayplayer] && camera2.chase)
|
||||||
heightsec = R_PointInSubsector(camera2.x, camera2.y)->sector->heightsec;
|
heightsec = R_PointInSubsector(camera2.x, camera2.y)->sector->heightsec;
|
||||||
else if (camera.chase && viewplayer == &players[displayplayer])
|
else if (camera.chase && viewcontext->player == &players[displayplayer])
|
||||||
heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec;
|
heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec;
|
||||||
else if (viewmobj)
|
else if (viewmobj)
|
||||||
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
|
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
|
||||||
else
|
else
|
||||||
return sec;
|
return sec;
|
||||||
underwater = heightsec != -1 && viewz <= sectors[heightsec].floorheight;
|
underwater = heightsec != -1 && viewcontext->z <= sectors[heightsec].floorheight;
|
||||||
|
|
||||||
// Replace sector being drawn, with a copy to be hacked
|
// Replace sector being drawn, with a copy to be hacked
|
||||||
*tempsec = *sec;
|
*tempsec = *sec;
|
||||||
|
@ -272,7 +251,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
tempsec->ceilingheight = s->ceilingheight;
|
tempsec->ceilingheight = s->ceilingheight;
|
||||||
|
|
||||||
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
||||||
tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight)
|
tempsec->ceilingheight = s->floorheight - 1, !back)) || viewcontext->z <= s->floorheight)
|
||||||
{ // head-below-floor hack
|
{ // head-below-floor hack
|
||||||
tempsec->floorpic = s->floorpic;
|
tempsec->floorpic = s->floorpic;
|
||||||
tempsec->floor_xoffs = s->floor_xoffs;
|
tempsec->floor_xoffs = s->floor_xoffs;
|
||||||
|
@ -308,7 +287,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel
|
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel
|
||||||
: sectors[s->ceilinglightsec].lightlevel;
|
: sectors[s->ceilinglightsec].lightlevel;
|
||||||
}
|
}
|
||||||
else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight
|
else if (heightsec != -1 && viewcontext->z >= sectors[heightsec].ceilingheight
|
||||||
&& sec->ceilingheight > s->ceilingheight)
|
&& sec->ceilingheight > s->ceilingheight)
|
||||||
{ // Above-ceiling hack
|
{ // Above-ceiling hack
|
||||||
tempsec->ceilingheight = s->ceilingheight;
|
tempsec->ceilingheight = s->ceilingheight;
|
||||||
|
@ -382,22 +361,25 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
|
||||||
// R_AddLine
|
// R_AddLine
|
||||||
// Clips the given segment and adds any visible pieces to the line list.
|
// Clips the given segment and adds any visible pieces to the line list.
|
||||||
//
|
//
|
||||||
static void R_AddLine(seg_t *line)
|
static void R_AddLine(rendercontext_t *rendercontext, seg_t *line)
|
||||||
{
|
{
|
||||||
INT32 x1, x2;
|
INT32 x1, x2;
|
||||||
angle_t angle1, angle2, span, tspan;
|
angle_t angle1, angle2, span, tspan;
|
||||||
static sector_t tempsec;
|
|
||||||
boolean bothceilingssky = false, bothfloorssky = false;
|
boolean bothceilingssky = false, bothfloorssky = false;
|
||||||
|
|
||||||
portalline = false;
|
bspcontext_t *bspcontext = &rendercontext->bspcontext;
|
||||||
|
viewcontext_t *viewcontext = &rendercontext->viewcontext;
|
||||||
|
wallcontext_t wallcontext;
|
||||||
|
|
||||||
|
bspcontext->portalline = false;
|
||||||
|
|
||||||
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// big room fix
|
// big room fix
|
||||||
angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
|
angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v1->x, line->v1->y);
|
||||||
angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
|
angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v2->x, line->v2->y);
|
||||||
curline = line;
|
bspcontext->curline = line;
|
||||||
|
|
||||||
// Clip to view edges.
|
// Clip to view edges.
|
||||||
span = angle1 - angle2;
|
span = angle1 - angle2;
|
||||||
|
@ -407,9 +389,9 @@ static void R_AddLine(seg_t *line)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Global angle needed by segcalc.
|
// Global angle needed by segcalc.
|
||||||
rw_angle1 = angle1;
|
wallcontext.angle1 = angle1;
|
||||||
angle1 -= viewangle;
|
angle1 -= viewcontext->angle;
|
||||||
angle2 -= viewangle;
|
angle2 -= viewcontext->angle;
|
||||||
|
|
||||||
tspan = angle1 + clipangle;
|
tspan = angle1 + clipangle;
|
||||||
if (tspan > doubleclipangle)
|
if (tspan > doubleclipangle)
|
||||||
|
@ -440,18 +422,21 @@ static void R_AddLine(seg_t *line)
|
||||||
x1 = viewangletox[angle1];
|
x1 = viewangletox[angle1];
|
||||||
x2 = viewangletox[angle2];
|
x2 = viewangletox[angle2];
|
||||||
|
|
||||||
|
x1 = max(rendercontext->begincolumn, x1);
|
||||||
|
x2 = min(rendercontext->endcolumn, x2);
|
||||||
|
|
||||||
// Does not cross a pixel?
|
// Does not cross a pixel?
|
||||||
if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness
|
if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness
|
||||||
return;
|
return;
|
||||||
|
|
||||||
backsector = line->backsector;
|
bspcontext->backsector = line->backsector;
|
||||||
|
|
||||||
// Portal line
|
// Portal line
|
||||||
if (line->linedef->special == 40 && line->side == 0)
|
if (line->linedef->special == 40 && line->side == 0)
|
||||||
{
|
{
|
||||||
// Render portal if recursiveness limit hasn't been reached.
|
// Render portal if recursiveness limit hasn't been reached.
|
||||||
// Otherwise, render the wall normally.
|
// Otherwise, render the wall normally.
|
||||||
if (portalrender < cv_maxportals.value)
|
if (bspcontext->portalrender < cv_maxportals.value)
|
||||||
{
|
{
|
||||||
size_t p;
|
size_t p;
|
||||||
mtag_t tag = Tag_FGet(&line->linedef->tags);
|
mtag_t tag = Tag_FGet(&line->linedef->tags);
|
||||||
|
@ -464,38 +449,40 @@ static void R_AddLine(seg_t *line)
|
||||||
if ((tag != Tag_FGet(&lines[li2].tags)) || (lines[li1].special != lines[li2].special) || (li1 == li2))
|
if ((tag != Tag_FGet(&lines[li2].tags)) || (lines[li1].special != lines[li2].special) || (li1 == li2))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Portal_Add2Lines(li1, li2, x1, x2);
|
Portal_Add2Lines(rendercontext, li1, li2, x1, x2);
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single sided line?
|
// Single sided line?
|
||||||
if (!backsector)
|
if (!bspcontext->backsector)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
|
|
||||||
backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);
|
bspcontext->backsector = R_FakeFlat(viewcontext, bspcontext->backsector, &bspcontext->btempsec, NULL, NULL, true);
|
||||||
|
|
||||||
doorclosed = 0;
|
// indicates doors closed wrt automap bugfix:
|
||||||
|
bspcontext->doorclosed = 0;
|
||||||
|
|
||||||
if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum)
|
if (bspcontext->backsector->ceilingpic == skyflatnum && bspcontext->frontsector->ceilingpic == skyflatnum)
|
||||||
bothceilingssky = true;
|
bothceilingssky = true;
|
||||||
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum)
|
if (bspcontext->backsector->floorpic == skyflatnum && bspcontext->frontsector->floorpic == skyflatnum)
|
||||||
bothfloorssky = true;
|
bothfloorssky = true;
|
||||||
|
|
||||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||||
{
|
{
|
||||||
if (!line->polyseg &&
|
if (!line->polyseg &&
|
||||||
!line->sidedef->midtexture
|
!line->sidedef->midtexture
|
||||||
&& ((!frontsector->ffloors && !backsector->ffloors)
|
&& ((!bspcontext->frontsector->ffloors && !bspcontext->backsector->ffloors)
|
||||||
|| Tag_Compare(&frontsector->tags, &backsector->tags)))
|
|| Tag_Compare(&bspcontext->frontsector->tags, &bspcontext->backsector->tags)))
|
||||||
return; // line is empty, don't even bother
|
return; // line is empty, don't even bother
|
||||||
|
|
||||||
goto clippass; // treat like wide open window instead
|
goto clippass; // treat like wide open window instead
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closed door.
|
// Closed door.
|
||||||
if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)
|
if (bspcontext->frontsector->f_slope || bspcontext->frontsector->c_slope
|
||||||
|
|| bspcontext->backsector->f_slope || bspcontext->backsector->c_slope)
|
||||||
{
|
{
|
||||||
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
|
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
|
||||||
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
|
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
|
||||||
|
@ -503,10 +490,10 @@ static void R_AddLine(seg_t *line)
|
||||||
end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \
|
end1 = P_GetZAt(slope, line->v1->x, line->v1->y, normalheight); \
|
||||||
end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight);
|
end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight);
|
||||||
|
|
||||||
SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight)
|
SLOPEPARAMS(bspcontext->frontsector->f_slope, frontf1, frontf2, bspcontext->frontsector-> floorheight)
|
||||||
SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
|
SLOPEPARAMS(bspcontext->frontsector->c_slope, frontc1, frontc2, bspcontext->frontsector->ceilingheight)
|
||||||
SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight)
|
SLOPEPARAMS( bspcontext->backsector->f_slope, backf1, backf2, bspcontext->backsector-> floorheight)
|
||||||
SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight)
|
SLOPEPARAMS( bspcontext->backsector->c_slope, backc1, backc2, bspcontext->backsector->ceilingheight)
|
||||||
#undef SLOPEPARAMS
|
#undef SLOPEPARAMS
|
||||||
// if both ceilings are skies, consider it always "open"
|
// if both ceilings are skies, consider it always "open"
|
||||||
// same for floors
|
// same for floors
|
||||||
|
@ -519,11 +506,11 @@ static void R_AddLine(seg_t *line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for automap fix. Store in doorclosed for r_segs.c
|
// Check for automap fix. Store in doorclosed for r_segs.c
|
||||||
doorclosed = (backc1 <= backf1 && backc2 <= backf2
|
bspcontext->doorclosed = (backc1 <= backf1 && backc2 <= backf2
|
||||||
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
|
&& ((backc1 >= frontc1 && backc2 >= frontc2) || bspcontext->curline->sidedef->toptexture)
|
||||||
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture));
|
&& ((backf1 <= frontf1 && backf2 >= frontf2) || bspcontext->curline->sidedef->bottomtexture));
|
||||||
|
|
||||||
if (doorclosed)
|
if (bspcontext->doorclosed)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,40 +528,39 @@ static void R_AddLine(seg_t *line)
|
||||||
// same for floors
|
// same for floors
|
||||||
if (!bothceilingssky && !bothfloorssky)
|
if (!bothceilingssky && !bothfloorssky)
|
||||||
{
|
{
|
||||||
if (backsector->ceilingheight <= frontsector->floorheight
|
if (bspcontext->backsector->ceilingheight <= bspcontext->frontsector->floorheight
|
||||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
|| bspcontext->backsector->floorheight >= bspcontext->frontsector->ceilingheight)
|
||||||
{
|
{
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for automap fix. Store in doorclosed for r_segs.c
|
// Check for automap fix. Store in doorclosed for r_segs.c
|
||||||
doorclosed = R_DoorClosed();
|
bspcontext->doorclosed = R_DoorClosed(bspcontext);
|
||||||
if (doorclosed)
|
if (bspcontext->doorclosed)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window.
|
// Window.
|
||||||
if (!bothceilingssky) // ceilings are always the "same" when sky
|
if (!bothceilingssky) // ceilings are always the "same" when sky
|
||||||
if (backsector->ceilingheight != frontsector->ceilingheight)
|
if (bspcontext->backsector->ceilingheight != bspcontext->frontsector->ceilingheight)
|
||||||
goto clippass;
|
goto clippass;
|
||||||
if (!bothfloorssky) // floors are always the "same" when sky
|
if (!bothfloorssky) // floors are always the "same" when sky
|
||||||
if (backsector->floorheight != frontsector->floorheight)
|
if (bspcontext->backsector->floorheight != bspcontext->frontsector->floorheight)
|
||||||
goto clippass;
|
goto clippass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject empty lines used for triggers and special events.
|
// Reject empty lines used for triggers and special events.
|
||||||
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
||||||
// and no middle texture.
|
// and no middle texture.
|
||||||
|
if (R_IsEmptyLine(line, bspcontext->frontsector, bspcontext->backsector))
|
||||||
if (R_IsEmptyLine(line, frontsector, backsector))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clippass:
|
clippass:
|
||||||
R_ClipPassWallSegment(x1, x2 - 1);
|
R_ClipPassWallSegment(rendercontext, &wallcontext, x1, x2 - 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clipsolid:
|
clipsolid:
|
||||||
R_ClipSolidWallSegment(x1, x2 - 1);
|
R_ClipSolidWallSegment(rendercontext, &wallcontext, x1, x2 - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -602,22 +588,24 @@ INT32 checkcoord[12][4] =
|
||||||
{2, 1, 3, 0}
|
{2, 1, 3, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static boolean R_CheckBBox(const fixed_t *bspcoord)
|
static boolean R_CheckBBox(rendercontext_t *context, const fixed_t *bspcoord)
|
||||||
{
|
{
|
||||||
angle_t angle1, angle2;
|
angle_t angle1, angle2;
|
||||||
INT32 sx1, sx2, boxpos;
|
INT32 sx1, sx2, boxpos;
|
||||||
const INT32* check;
|
const INT32* check;
|
||||||
cliprange_t *start;
|
cliprange_t *start;
|
||||||
|
viewcontext_t *viewcontext = &context->viewcontext;
|
||||||
|
|
||||||
// Find the corners of the box that define the edges from current viewpoint.
|
// Find the corners of the box that define the edges from current viewpoint.
|
||||||
if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5)
|
if ((boxpos = (viewcontext->x <= bspcoord[BOXLEFT] ? 0 : viewcontext->x < bspcoord[BOXRIGHT] ? 1 : 2)
|
||||||
|
+ (viewcontext->y >= bspcoord[BOXTOP] ? 0 : viewcontext->y > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
check = checkcoord[boxpos];
|
check = checkcoord[boxpos];
|
||||||
|
|
||||||
// big room fix
|
// big room fix
|
||||||
angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[0]], bspcoord[check[1]]) - viewcontext->angle;
|
||||||
angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[2]], bspcoord[check[3]]) - viewcontext->angle;
|
||||||
|
|
||||||
if ((signed)angle1 < (signed)angle2)
|
if ((signed)angle1 < (signed)angle2)
|
||||||
{
|
{
|
||||||
|
@ -641,7 +629,7 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
|
||||||
// Does not cross a pixel.
|
// Does not cross a pixel.
|
||||||
if (sx1 >= sx2) return false;
|
if (sx1 >= sx2) return false;
|
||||||
|
|
||||||
start = solidsegs;
|
start = context->bspcontext.solidsegs;
|
||||||
while (start->last < sx2)
|
while (start->last < sx2)
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
|
@ -789,7 +777,7 @@ static int R_PolysegCompare(const void *p1, const void *p2)
|
||||||
// haleyjd 02/19/06
|
// haleyjd 02/19/06
|
||||||
// Adds all segs in all polyobjects in the given subsector.
|
// Adds all segs in all polyobjects in the given subsector.
|
||||||
//
|
//
|
||||||
static void R_AddPolyObjects(subsector_t *sub)
|
static void R_AddPolyObjects(rendercontext_t *context, subsector_t *sub)
|
||||||
{
|
{
|
||||||
polyobj_t *po = sub->polyList;
|
polyobj_t *po = sub->polyList;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
@ -804,7 +792,7 @@ static void R_AddPolyObjects(subsector_t *sub)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for render stats
|
// for render stats
|
||||||
ps_numpolyobjects += numpolys;
|
ps_numpolyobjects[context->num] += numpolys;
|
||||||
|
|
||||||
// sort polyobjects
|
// sort polyobjects
|
||||||
R_SortPolyObjects(sub);
|
R_SortPolyObjects(sub);
|
||||||
|
@ -814,7 +802,7 @@ static void R_AddPolyObjects(subsector_t *sub)
|
||||||
{
|
{
|
||||||
qsort(po_ptrs[i]->segs, po_ptrs[i]->segCount, sizeof(seg_t *), R_PolysegCompare);
|
qsort(po_ptrs[i]->segs, po_ptrs[i]->segCount, sizeof(seg_t *), R_PolysegCompare);
|
||||||
for (j = 0; j < po_ptrs[i]->segCount; ++j)
|
for (j = 0; j < po_ptrs[i]->segCount; ++j)
|
||||||
R_AddLine(po_ptrs[i]->segs[j]);
|
R_AddLine(context, po_ptrs[i]->segs[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,17 +813,19 @@ static void R_AddPolyObjects(subsector_t *sub)
|
||||||
// Draw one or more line segments.
|
// Draw one or more line segments.
|
||||||
//
|
//
|
||||||
|
|
||||||
drawseg_t *firstseg;
|
static void R_Subsector(rendercontext_t *context, size_t num)
|
||||||
|
|
||||||
static void R_Subsector(size_t num)
|
|
||||||
{
|
{
|
||||||
INT32 count, floorlightlevel, ceilinglightlevel, light;
|
INT32 count, floorlightlevel, ceilinglightlevel, light;
|
||||||
seg_t *line;
|
seg_t *line;
|
||||||
subsector_t *sub;
|
subsector_t *sub;
|
||||||
static sector_t tempsec; // Deep water hack
|
|
||||||
extracolormap_t *floorcolormap;
|
extracolormap_t *floorcolormap;
|
||||||
extracolormap_t *ceilingcolormap;
|
extracolormap_t *ceilingcolormap;
|
||||||
fixed_t floorcenterz, ceilingcenterz;
|
fixed_t floorcenterz, ceilingcenterz;
|
||||||
|
sector_t *frontsector;
|
||||||
|
|
||||||
|
bspcontext_t *bspcontext = &context->bspcontext;
|
||||||
|
planecontext_t *planecontext = &context->planecontext;
|
||||||
|
viewcontext_t *viewcontext = &context->viewcontext;
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
#ifdef RANGECHECK
|
||||||
if (num >= numsubsectors)
|
if (num >= numsubsectors)
|
||||||
|
@ -847,12 +837,11 @@ static void R_Subsector(size_t num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sub = &subsectors[num];
|
sub = &subsectors[num];
|
||||||
frontsector = sub->sector;
|
|
||||||
count = sub->numlines;
|
count = sub->numlines;
|
||||||
line = &segs[sub->firstline];
|
line = &segs[sub->firstline];
|
||||||
|
|
||||||
// Deep water/fake ceiling effect.
|
// Deep water/fake ceiling effect.
|
||||||
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);
|
frontsector = R_FakeFlat(viewcontext, sub->sector, &bspcontext->ftempsec, &floorlightlevel, &ceilinglightlevel, false);
|
||||||
|
|
||||||
floorcolormap = ceilingcolormap = frontsector->extra_colormap;
|
floorcolormap = ceilingcolormap = frontsector->extra_colormap;
|
||||||
|
|
||||||
|
@ -866,9 +855,12 @@ static void R_Subsector(size_t num)
|
||||||
{
|
{
|
||||||
frontsector->numlights = sub->sector->numlights = 0;
|
frontsector->numlights = sub->sector->numlights = 0;
|
||||||
R_Prep3DFloors(frontsector);
|
R_Prep3DFloors(frontsector);
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
sub->sector->lightlist = frontsector->lightlist;
|
sub->sector->lightlist = frontsector->lightlist;
|
||||||
sub->sector->numlights = frontsector->numlights;
|
sub->sector->numlights = frontsector->numlights;
|
||||||
sub->sector->moved = frontsector->moved = false;
|
sub->sector->moved = frontsector->moved = false;
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
||||||
|
@ -883,106 +875,109 @@ static void R_Subsector(size_t num)
|
||||||
|
|
||||||
sub->sector->extra_colormap = frontsector->extra_colormap;
|
sub->sector->extra_colormap = frontsector->extra_colormap;
|
||||||
|
|
||||||
if (P_GetSectorFloorZAt(frontsector, viewx, viewy) < viewz
|
if (P_GetSectorFloorZAt(frontsector, viewcontext->x, viewcontext->y) < viewcontext->z
|
||||||
|| frontsector->floorpic == skyflatnum
|
|| frontsector->floorpic == skyflatnum
|
||||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
|
||||||
{
|
{
|
||||||
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
planecontext->floorplane = R_FindPlane(planecontext, viewcontext, frontsector->floorheight, frontsector->floorpic, floorlightlevel,
|
||||||
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope);
|
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
floorplane = NULL;
|
planecontext->floorplane = NULL;
|
||||||
|
|
||||||
if (P_GetSectorCeilingZAt(frontsector, viewx, viewy) > viewz
|
if (P_GetSectorCeilingZAt(frontsector, viewcontext->x, viewcontext->y) > viewcontext->z
|
||||||
|| frontsector->ceilingpic == skyflatnum
|
|| frontsector->ceilingpic == skyflatnum
|
||||||
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
|
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))
|
||||||
{
|
{
|
||||||
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
|
planecontext->ceilingplane = R_FindPlane(planecontext, viewcontext, frontsector->ceilingheight, frontsector->ceilingpic,
|
||||||
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
|
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
|
||||||
ceilingcolormap, NULL, NULL, frontsector->c_slope);
|
ceilingcolormap, NULL, NULL, frontsector->c_slope);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ceilingplane = NULL;
|
planecontext->ceilingplane = NULL;
|
||||||
|
|
||||||
|
planecontext->numffloors = 0;
|
||||||
|
planecontext->ffloor[0].slope = NULL;
|
||||||
|
planecontext->ffloor[0].plane = NULL;
|
||||||
|
planecontext->ffloor[0].polyobj = NULL;
|
||||||
|
|
||||||
numffloors = 0;
|
|
||||||
ffloor[numffloors].slope = NULL;
|
|
||||||
ffloor[numffloors].plane = NULL;
|
|
||||||
ffloor[numffloors].polyobj = NULL;
|
|
||||||
if (frontsector->ffloors)
|
if (frontsector->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
fixed_t heightcheck, planecenterz;
|
fixed_t heightcheck, planecenterz;
|
||||||
|
|
||||||
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
|
for (rover = frontsector->ffloors; rover && planecontext->numffloors < MAXFFLOORS; rover = rover->next)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
|
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (frontsector->cullheight)
|
if (frontsector->cullheight)
|
||||||
{
|
{
|
||||||
if (R_DoCulling(frontsector->cullheight, viewsector->cullheight, viewz, *rover->bottomheight, *rover->topheight))
|
if (R_DoCulling(frontsector->cullheight, viewcontext->sector->cullheight, viewcontext->z, *rover->bottomheight, *rover->topheight))
|
||||||
{
|
{
|
||||||
rover->norender = leveltime;
|
rover->norender = leveltime;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ffloor[numffloors].plane = NULL;
|
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||||
ffloor[numffloors].polyobj = NULL;
|
planecontext->ffloor[planecontext->numffloors].polyobj = NULL;
|
||||||
|
|
||||||
heightcheck = P_GetFFloorBottomZAt(rover, viewx, viewy);
|
heightcheck = P_GetFFloorBottomZAt(rover, viewcontext->x, viewcontext->y);
|
||||||
|
|
||||||
planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
|
planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
|
||||||
if (planecenterz <= ceilingcenterz
|
if (planecenterz <= ceilingcenterz
|
||||||
&& planecenterz >= floorcenterz
|
&& planecenterz >= floorcenterz
|
||||||
&& ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|
&& ((viewcontext->z < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|
||||||
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
|
|| (viewcontext->z > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
|
||||||
{
|
{
|
||||||
light = R_GetPlaneLight(frontsector, planecenterz,
|
light = R_GetPlaneLight(frontsector, planecenterz,
|
||||||
viewz < heightcheck);
|
viewcontext->z < heightcheck);
|
||||||
|
|
||||||
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
|
planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext,
|
||||||
|
*rover->bottomheight, *rover->bottompic,
|
||||||
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
|
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
|
||||||
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
|
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
|
||||||
|
|
||||||
ffloor[numffloors].slope = *rover->b_slope;
|
planecontext->ffloor[planecontext->numffloors].slope = *rover->b_slope;
|
||||||
|
|
||||||
// Tell the renderer this sector has slopes in it.
|
// Tell the renderer this sector has slopes in it.
|
||||||
if (ffloor[numffloors].slope)
|
if (planecontext->ffloor[planecontext->numffloors].slope)
|
||||||
frontsector->hasslope = true;
|
frontsector->hasslope = true;
|
||||||
|
|
||||||
ffloor[numffloors].height = heightcheck;
|
planecontext->ffloor[planecontext->numffloors].height = heightcheck;
|
||||||
ffloor[numffloors].ffloor = rover;
|
planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||||
numffloors++;
|
planecontext->numffloors++;
|
||||||
}
|
}
|
||||||
if (numffloors >= MAXFFLOORS)
|
if (planecontext->numffloors >= MAXFFLOORS)
|
||||||
break;
|
break;
|
||||||
ffloor[numffloors].plane = NULL;
|
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||||
ffloor[numffloors].polyobj = NULL;
|
planecontext->ffloor[planecontext->numffloors].polyobj = NULL;
|
||||||
|
|
||||||
heightcheck = P_GetFFloorTopZAt(rover, viewx, viewy);
|
heightcheck = P_GetFFloorTopZAt(rover, viewcontext->x, viewcontext->y);
|
||||||
|
|
||||||
planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
|
planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
|
||||||
if (planecenterz >= floorcenterz
|
if (planecenterz >= floorcenterz
|
||||||
&& planecenterz <= ceilingcenterz
|
&& planecenterz <= ceilingcenterz
|
||||||
&& ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|
&& ((viewcontext->z > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|
||||||
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
|
|| (viewcontext->z < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
|
||||||
{
|
{
|
||||||
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
|
light = R_GetPlaneLight(frontsector, planecenterz, viewcontext->z < heightcheck);
|
||||||
|
|
||||||
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
|
planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext,
|
||||||
|
*rover->topheight, *rover->toppic,
|
||||||
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
|
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
|
||||||
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope);
|
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope);
|
||||||
|
|
||||||
ffloor[numffloors].slope = *rover->t_slope;
|
planecontext->ffloor[planecontext->numffloors].slope = *rover->t_slope;
|
||||||
|
|
||||||
// Tell the renderer this sector has slopes in it.
|
// Tell the renderer this sector has slopes in it.
|
||||||
if (ffloor[numffloors].slope)
|
if (planecontext->ffloor[planecontext->numffloors].slope)
|
||||||
frontsector->hasslope = true;
|
frontsector->hasslope = true;
|
||||||
|
|
||||||
ffloor[numffloors].height = heightcheck;
|
planecontext->ffloor[planecontext->numffloors].height = heightcheck;
|
||||||
ffloor[numffloors].ffloor = rover;
|
planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||||
numffloors++;
|
planecontext->numffloors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -995,7 +990,7 @@ static void R_Subsector(size_t num)
|
||||||
|
|
||||||
while (po)
|
while (po)
|
||||||
{
|
{
|
||||||
if (numffloors >= MAXFFLOORS)
|
if (planecontext->numffloors >= MAXFFLOORS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!(po->flags & POF_RENDERPLANES)) // Don't draw planes
|
if (!(po->flags & POF_RENDERPLANES)) // Don't draw planes
|
||||||
|
@ -1005,54 +1000,58 @@ static void R_Subsector(size_t num)
|
||||||
}
|
}
|
||||||
|
|
||||||
polysec = po->lines[0]->backsector;
|
polysec = po->lines[0]->backsector;
|
||||||
ffloor[numffloors].plane = NULL;
|
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||||
|
|
||||||
if (polysec->floorheight <= ceilingcenterz
|
if (polysec->floorheight <= ceilingcenterz
|
||||||
&& polysec->floorheight >= floorcenterz
|
&& polysec->floorheight >= floorcenterz
|
||||||
&& (viewz < polysec->floorheight))
|
&& (viewcontext->z < polysec->floorheight))
|
||||||
{
|
{
|
||||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight);
|
||||||
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
|
planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext,
|
||||||
|
polysec->floorheight, polysec->floorpic,
|
||||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs,
|
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs,
|
||||||
polysec->floorpic_angle-po->angle,
|
polysec->floorpic_angle-po->angle,
|
||||||
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
||||||
NULL); // will ffloors be slopable eventually?
|
NULL); // will ffloors be slopable eventually?
|
||||||
|
|
||||||
ffloor[numffloors].height = polysec->floorheight;
|
planecontext->ffloor[planecontext->numffloors].height = polysec->floorheight;
|
||||||
ffloor[numffloors].polyobj = po;
|
planecontext->ffloor[planecontext->numffloors].polyobj = po;
|
||||||
ffloor[numffloors].slope = NULL;
|
planecontext->ffloor[planecontext->numffloors].slope = NULL;
|
||||||
//ffloor[numffloors].ffloor = rover;
|
//planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||||
po->visplane = ffloor[numffloors].plane;
|
po->visplane = planecontext->ffloor[planecontext->numffloors].plane;
|
||||||
numffloors++;
|
planecontext->numffloors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numffloors >= MAXFFLOORS)
|
if (planecontext->numffloors >= MAXFFLOORS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ffloor[numffloors].plane = NULL;
|
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||||
|
|
||||||
if (polysec->ceilingheight >= floorcenterz
|
if (polysec->ceilingheight >= floorcenterz
|
||||||
&& polysec->ceilingheight <= ceilingcenterz
|
&& polysec->ceilingheight <= ceilingcenterz
|
||||||
&& (viewz > polysec->ceilingheight))
|
&& (viewcontext->z > polysec->ceilingheight))
|
||||||
{
|
{
|
||||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight);
|
||||||
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
|
planecontext->ffloor[planecontext->numffloors].plane = R_FindPlane(planecontext, viewcontext,
|
||||||
|
polysec->ceilingheight, polysec->ceilingpic,
|
||||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
|
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
|
||||||
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
||||||
NULL); // will ffloors be slopable eventually?
|
NULL); // will ffloors be slopable eventually?
|
||||||
|
|
||||||
ffloor[numffloors].polyobj = po;
|
planecontext->ffloor[planecontext->numffloors].polyobj = po;
|
||||||
ffloor[numffloors].height = polysec->ceilingheight;
|
planecontext->ffloor[planecontext->numffloors].height = polysec->ceilingheight;
|
||||||
ffloor[numffloors].slope = NULL;
|
planecontext->ffloor[planecontext->numffloors].slope = NULL;
|
||||||
//ffloor[numffloors].ffloor = rover;
|
//planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||||
po->visplane = ffloor[numffloors].plane;
|
po->visplane = planecontext->ffloor[planecontext->numffloors].plane;
|
||||||
numffloors++;
|
planecontext->numffloors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
po = (polyobj_t *)(po->link.next);
|
po = (polyobj_t *)(po->link.next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bspcontext->frontsector = frontsector;
|
||||||
|
|
||||||
// killough 9/18/98: Fix underwater slowdown, by passing real sector
|
// killough 9/18/98: Fix underwater slowdown, by passing real sector
|
||||||
// instead of fake one. Improve sprite lighting by basing sprite
|
// instead of fake one. Improve sprite lighting by basing sprite
|
||||||
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
||||||
|
@ -1065,21 +1064,20 @@ static void R_Subsector(size_t num)
|
||||||
// Either you must pass the fake sector and handle validcount here, on the
|
// Either you must pass the fake sector and handle validcount here, on the
|
||||||
// real sector, or you must account for the lighting in some other way,
|
// real sector, or you must account for the lighting in some other way,
|
||||||
// like passing it as an argument.
|
// like passing it as an argument.
|
||||||
R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2);
|
R_AddSprites(context, sub->sector, (floorlightlevel+ceilinglightlevel)/2);
|
||||||
|
|
||||||
firstseg = NULL;
|
bspcontext->firstseg = NULL;
|
||||||
|
|
||||||
// haleyjd 02/19/06: draw polyobjects before static lines
|
// haleyjd 02/19/06: draw polyobjects before static lines
|
||||||
if (sub->polyList)
|
if (sub->polyList)
|
||||||
R_AddPolyObjects(sub);
|
R_AddPolyObjects(context, sub);
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
|
||||||
if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
|
if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
|
||||||
R_AddLine(line);
|
R_AddLine(context, line);
|
||||||
line++;
|
line++;
|
||||||
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
bspcontext->curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1234,37 +1232,37 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside)
|
||||||
//
|
//
|
||||||
// killough 5/2/98: reformatted, removed tail recursion
|
// killough 5/2/98: reformatted, removed tail recursion
|
||||||
|
|
||||||
void R_RenderBSPNode(INT32 bspnum)
|
void R_RenderBSPNode(rendercontext_t *context, INT32 bspnum)
|
||||||
{
|
{
|
||||||
node_t *bsp;
|
node_t *bsp;
|
||||||
INT32 side;
|
INT32 side;
|
||||||
|
|
||||||
ps_numbspcalls++;
|
ps_numbspcalls[context->num]++;
|
||||||
|
|
||||||
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
|
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
|
||||||
{
|
{
|
||||||
bsp = &nodes[bspnum];
|
bsp = &nodes[bspnum];
|
||||||
|
|
||||||
// Decide which side the view point is on.
|
// Decide which side the view point is on.
|
||||||
side = R_PointOnSide(viewx, viewy, bsp);
|
side = R_PointOnSide(context->viewcontext.x, context->viewcontext.y, bsp);
|
||||||
|
|
||||||
// Recursively divide front space.
|
// Recursively divide front space.
|
||||||
R_RenderBSPNode(bsp->children[side]);
|
R_RenderBSPNode(context, bsp->children[side]);
|
||||||
|
|
||||||
// Possibly divide back space.
|
// Possibly divide back space.
|
||||||
|
if (!R_CheckBBox(context, bsp->bbox[side^1]))
|
||||||
if (!R_CheckBBox(bsp->bbox[side^1]))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bspnum = bsp->children[side^1];
|
bspnum = bsp->children[side^1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// PORTAL CULLING
|
// PORTAL CULLING
|
||||||
if (portalcullsector) {
|
if (context->bspcontext.portalcullsector) {
|
||||||
sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector;
|
sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector;
|
||||||
if (sect != portalcullsector)
|
if (sect != context->bspcontext.portalcullsector)
|
||||||
return;
|
return;
|
||||||
portalcullsector = NULL;
|
context->bspcontext.portalcullsector = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
R_Subsector(context, bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
||||||
}
|
}
|
||||||
|
|
27
src/r_bsp.h
27
src/r_bsp.h
|
@ -18,27 +18,16 @@
|
||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern seg_t *curline;
|
|
||||||
extern side_t *sidedef;
|
|
||||||
extern line_t *linedef;
|
|
||||||
extern sector_t *frontsector;
|
|
||||||
extern sector_t *backsector;
|
|
||||||
extern boolean portalline; // is curline a portal seg?
|
|
||||||
|
|
||||||
// drawsegs are allocated on the fly... see r_segs.c
|
|
||||||
|
|
||||||
extern INT32 checkcoord[12][4];
|
extern INT32 checkcoord[12][4];
|
||||||
|
|
||||||
extern drawseg_t *curdrawsegs;
|
struct bspcontext_s;
|
||||||
extern drawseg_t *drawsegs;
|
struct rendercontext_s;
|
||||||
extern drawseg_t *ds_p;
|
struct viewcontext_s;
|
||||||
extern INT32 doorclosed;
|
|
||||||
|
|
||||||
// BSP?
|
// BSP?
|
||||||
void R_ClearClipSegs(void);
|
void R_ClearClipSegs(struct bspcontext_s *context, INT32 start, INT32 end);
|
||||||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
void R_ClearDrawSegs(struct bspcontext_s *context);
|
||||||
void R_ClearDrawSegs(void);
|
void R_RenderBSPNode(struct rendercontext_s *context, INT32 bspnum);
|
||||||
void R_RenderBSPNode(INT32 bspnum);
|
|
||||||
|
|
||||||
void R_SortPolyObjects(subsector_t *sub);
|
void R_SortPolyObjects(subsector_t *sub);
|
||||||
|
|
||||||
|
@ -46,8 +35,8 @@ extern size_t numpolys; // number of polyobjects in current subsector
|
||||||
extern size_t num_po_ptrs; // number of polyobject pointers allocated
|
extern size_t num_po_ptrs; // number of polyobject pointers allocated
|
||||||
extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
|
extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
|
||||||
|
|
||||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
sector_t *R_FakeFlat(struct viewcontext_s *viewcontext, sector_t *sec, sector_t *tempsec,
|
||||||
INT32 *ceilinglightlevel, boolean back);
|
INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back);
|
||||||
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
|
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
|
||||||
|
|
||||||
INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
|
INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
|
||||||
|
|
187
src/r_context.h
Normal file
187
src/r_context.h
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
// Copyright (C) 2020 by Ethan Watson.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file r_context.h
|
||||||
|
/// \brief Render context
|
||||||
|
|
||||||
|
#ifndef __R_CONTEXT__
|
||||||
|
#define __R_CONTEXT__
|
||||||
|
|
||||||
|
#include "r_defs.h"
|
||||||
|
#include "r_bsp.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_splats.h"
|
||||||
|
#include "r_things.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render context is required for threaded rendering.
|
||||||
|
// So everything "global" goes in here. Everything.
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct viewcontext_s
|
||||||
|
{
|
||||||
|
fixed_t x, y, z;
|
||||||
|
angle_t angle, aimingangle;
|
||||||
|
fixed_t cos, sin;
|
||||||
|
sector_t *sector;
|
||||||
|
player_t *player;
|
||||||
|
mobj_t *mobj;
|
||||||
|
} viewcontext_t;
|
||||||
|
|
||||||
|
typedef struct bspcontext_s
|
||||||
|
{
|
||||||
|
seg_t *curline;
|
||||||
|
side_t *sidedef;
|
||||||
|
line_t *linedef;
|
||||||
|
sector_t *frontsector;
|
||||||
|
sector_t *backsector;
|
||||||
|
|
||||||
|
// very ugly realloc() of drawsegs at run-time, I upped it to 512
|
||||||
|
// instead of 256.. and someone managed to send me a level with
|
||||||
|
// 896 drawsegs! So too bad here's a limit removal a-la-Boom
|
||||||
|
drawseg_t *curdrawsegs; /**< This is used to handle multiple lists for masked drawsegs. */
|
||||||
|
drawseg_t *drawsegs;
|
||||||
|
drawseg_t *ds_p;
|
||||||
|
drawseg_t *firstseg;
|
||||||
|
size_t maxdrawsegs;
|
||||||
|
|
||||||
|
// newend is one past the last valid seg
|
||||||
|
cliprange_t *newend;
|
||||||
|
cliprange_t solidsegs[MAXSEGS];
|
||||||
|
|
||||||
|
sector_t ftempsec;
|
||||||
|
sector_t btempsec;
|
||||||
|
|
||||||
|
UINT8 doorclosed;
|
||||||
|
|
||||||
|
// Linked list for portals.
|
||||||
|
struct portal_s *portal_base, *portal_cap;
|
||||||
|
|
||||||
|
// When rendering a portal, it establishes the depth of the current BSP traversal.
|
||||||
|
UINT8 portalrender;
|
||||||
|
|
||||||
|
boolean portalline;
|
||||||
|
line_t *portalclipline;
|
||||||
|
sector_t *portalcullsector;
|
||||||
|
INT32 portalclipstart, portalclipend;
|
||||||
|
} bspcontext_t;
|
||||||
|
|
||||||
|
typedef struct planecontext_s
|
||||||
|
{
|
||||||
|
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||||
|
visplane_t *visplanes[MAXVISPLANES];
|
||||||
|
visplane_t *freetail;
|
||||||
|
visplane_t **freehead;
|
||||||
|
|
||||||
|
visplane_t *floorplane;
|
||||||
|
visplane_t *ceilingplane;
|
||||||
|
visplane_t *currentplane;
|
||||||
|
|
||||||
|
planemgr_t ffloor[MAXFFLOORS];
|
||||||
|
INT32 numffloors;
|
||||||
|
|
||||||
|
//SoM: 3/23/2000: Use boom opening limit removal
|
||||||
|
size_t maxopenings;
|
||||||
|
INT16 *openings, *lastopening; /// \todo free leak
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clip values are the solid pixel bounding the range.
|
||||||
|
// floorclip starts out SCREENHEIGHT
|
||||||
|
// ceilingclip starts out -1
|
||||||
|
//
|
||||||
|
INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
|
||||||
|
fixed_t frontscale[MAXVIDWIDTH];
|
||||||
|
|
||||||
|
//
|
||||||
|
// spanstart holds the start of a plane span
|
||||||
|
// initialized to 0 at start
|
||||||
|
//
|
||||||
|
INT32 spanstart[MAXVIDHEIGHT];
|
||||||
|
|
||||||
|
//
|
||||||
|
// texture mapping
|
||||||
|
//
|
||||||
|
lighttable_t **zlight;
|
||||||
|
fixed_t planeheight;
|
||||||
|
|
||||||
|
fixed_t cachedheight[MAXVIDHEIGHT];
|
||||||
|
fixed_t cacheddistance[MAXVIDHEIGHT];
|
||||||
|
fixed_t cachedxstep[MAXVIDHEIGHT];
|
||||||
|
fixed_t cachedystep[MAXVIDHEIGHT];
|
||||||
|
|
||||||
|
fixed_t xoffs, yoffs;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
INT32 offset;
|
||||||
|
fixed_t xfrac, yfrac;
|
||||||
|
boolean active;
|
||||||
|
} ripple;
|
||||||
|
|
||||||
|
struct rastery_s *prastertab;
|
||||||
|
struct rastery_s rastertab[MAXVIDHEIGHT];
|
||||||
|
} planecontext_t;
|
||||||
|
|
||||||
|
typedef struct spritecontext_s
|
||||||
|
{
|
||||||
|
UINT32 visspritecount;
|
||||||
|
UINT32 clippedvissprites;
|
||||||
|
vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS];
|
||||||
|
vissprite_t overflowsprite;
|
||||||
|
|
||||||
|
lighttable_t **spritelights;
|
||||||
|
|
||||||
|
boolean *sectorvisited;
|
||||||
|
|
||||||
|
drawnode_t nodebankhead;
|
||||||
|
vissprite_t vsprsortedhead;
|
||||||
|
} spritecontext_t;
|
||||||
|
|
||||||
|
typedef struct wallcontext_s
|
||||||
|
{
|
||||||
|
angle_t normalangle;
|
||||||
|
// angle to line origin
|
||||||
|
angle_t angle1;
|
||||||
|
fixed_t distance;
|
||||||
|
|
||||||
|
//
|
||||||
|
// regular wall
|
||||||
|
//
|
||||||
|
angle_t centerangle;
|
||||||
|
fixed_t offset;
|
||||||
|
fixed_t offset2; // for splats
|
||||||
|
fixed_t scale, scalestep;
|
||||||
|
fixed_t midtexturemid, toptexturemid, bottomtexturemid;
|
||||||
|
fixed_t toptextureslide, midtextureslide, bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes
|
||||||
|
fixed_t midtextureback, midtexturebackslide; // Values for masked midtexture height calculation
|
||||||
|
|
||||||
|
INT32 *silhouette;
|
||||||
|
fixed_t *tsilheight;
|
||||||
|
fixed_t *bsilheight;
|
||||||
|
} wallcontext_t;
|
||||||
|
|
||||||
|
typedef struct rendercontext_s
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
vbuffer_t buffer;
|
||||||
|
INT32 num;
|
||||||
|
|
||||||
|
INT32 begincolumn;
|
||||||
|
INT32 endcolumn;
|
||||||
|
|
||||||
|
viewcontext_t viewcontext;
|
||||||
|
bspcontext_t bspcontext;
|
||||||
|
planecontext_t planecontext;
|
||||||
|
spritecontext_t spritecontext;
|
||||||
|
|
||||||
|
colcontext_t colcontext;
|
||||||
|
spancontext_t spancontext;
|
||||||
|
} rendercontext_t;
|
||||||
|
|
||||||
|
#endif
|
|
@ -1240,8 +1240,8 @@ void R_PrecacheLevel(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap()
|
// do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap()
|
||||||
if (rendermode != render_soft)
|
// if (rendermode != render_soft)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
// Precache flats.
|
// Precache flats.
|
||||||
flatmemory = P_PrecacheLevelFlats();
|
flatmemory = P_PrecacheLevelFlats();
|
||||||
|
|
14
src/r_defs.h
14
src/r_defs.h
|
@ -22,7 +22,7 @@
|
||||||
// SECTORS do store MObjs anyway.
|
// SECTORS do store MObjs anyway.
|
||||||
#include "p_mobj.h"
|
#include "p_mobj.h"
|
||||||
|
|
||||||
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
|
#include "screen.h"
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "m_aatree.h"
|
#include "m_aatree.h"
|
||||||
|
@ -41,6 +41,9 @@ typedef struct
|
||||||
INT32 last;
|
INT32 last;
|
||||||
} cliprange_t;
|
} cliprange_t;
|
||||||
|
|
||||||
|
// Fix from boom.
|
||||||
|
#define MAXSEGS (MAXVIDWIDTH/2+1)
|
||||||
|
|
||||||
// Silhouette, needed for clipping segs (mainly) and sprites representing things.
|
// Silhouette, needed for clipping segs (mainly) and sprites representing things.
|
||||||
#define SIL_NONE 0
|
#define SIL_NONE 0
|
||||||
#define SIL_BOTTOM 1
|
#define SIL_BOTTOM 1
|
||||||
|
@ -56,6 +59,15 @@ typedef UINT8 lighttable_t;
|
||||||
#define CMF_FADEFULLBRIGHTSPRITES 1
|
#define CMF_FADEFULLBRIGHTSPRITES 1
|
||||||
#define CMF_FOG 4
|
#define CMF_FOG 4
|
||||||
|
|
||||||
|
typedef struct vbuffer_s
|
||||||
|
{
|
||||||
|
UINT8 *screens[5];
|
||||||
|
} vbuffer_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} floatv3_t;
|
||||||
|
|
||||||
// ExtraColormap type. Use for extra_colormaps from now on.
|
// ExtraColormap type. Use for extra_colormaps from now on.
|
||||||
typedef struct extracolormap_s
|
typedef struct extracolormap_s
|
||||||
{
|
{
|
||||||
|
|
102
src/r_draw.c
102
src/r_draw.c
|
@ -62,14 +62,6 @@ UINT8 *topleft;
|
||||||
// COLUMN DRAWING CODE STUFF
|
// COLUMN DRAWING CODE STUFF
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
lighttable_t *dc_colormap;
|
|
||||||
INT32 dc_x = 0, dc_yl = 0, dc_yh = 0;
|
|
||||||
|
|
||||||
fixed_t dc_iscale, dc_texturemid;
|
|
||||||
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
|
|
||||||
// soo lets make it a byte on all system for the ASM code
|
|
||||||
UINT8 *dc_source;
|
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
// translucency stuff here
|
// translucency stuff here
|
||||||
// -----------------------
|
// -----------------------
|
||||||
|
@ -78,48 +70,11 @@ UINT8 *dc_source;
|
||||||
UINT8 *transtables; // translucency tables
|
UINT8 *transtables; // translucency tables
|
||||||
UINT8 *blendtables[NUMBLENDMAPS];
|
UINT8 *blendtables[NUMBLENDMAPS];
|
||||||
|
|
||||||
/** \brief R_DrawTransColumn uses this
|
|
||||||
*/
|
|
||||||
UINT8 *dc_transmap; // one of the translucency tables
|
|
||||||
|
|
||||||
// ----------------------
|
|
||||||
// translation stuff here
|
|
||||||
// ----------------------
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief R_DrawTranslatedColumn uses this
|
|
||||||
*/
|
|
||||||
UINT8 *dc_translation;
|
|
||||||
|
|
||||||
struct r_lightlist_s *dc_lightlist = NULL;
|
|
||||||
INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// SPAN DRAWING CODE STUFF
|
// SPAN DRAWING CODE STUFF
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
INT32 ds_y, ds_x1, ds_x2;
|
float focallengthf;
|
||||||
lighttable_t *ds_colormap;
|
|
||||||
lighttable_t *ds_translation; // Lactozilla: Sprite splat drawer
|
|
||||||
|
|
||||||
fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
|
||||||
INT32 ds_waterofs, ds_bgofs;
|
|
||||||
|
|
||||||
UINT16 ds_flatwidth, ds_flatheight;
|
|
||||||
boolean ds_powersoftwo;
|
|
||||||
|
|
||||||
UINT8 *ds_source; // points to the start of a flat
|
|
||||||
UINT8 *ds_transmap; // one of the translucency tables
|
|
||||||
|
|
||||||
// Vectors for Software's tilted slope drawers
|
|
||||||
floatv3_t *ds_su, *ds_sv, *ds_sz;
|
|
||||||
floatv3_t *ds_sup, *ds_svp, *ds_szp;
|
|
||||||
float focallengthf, zeroheight;
|
|
||||||
|
|
||||||
/** \brief Variable flat sizes
|
|
||||||
*/
|
|
||||||
|
|
||||||
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// TRANSLATION COLORMAP CODE
|
// TRANSLATION COLORMAP CODE
|
||||||
|
@ -572,6 +527,15 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
|
||||||
dest_colormap[starttranscolor + i] = (UINT8)skincolors[color].ramp[i];
|
dest_colormap[starttranscolor + i] = (UINT8)skincolors[color].ramp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static I_mutex r_colormap_mutex;
|
||||||
|
|
||||||
|
# define Lock_state() I_lock_mutex(&r_colormap_mutex)
|
||||||
|
# define Unlock_state() I_unlock_mutex(r_colormap_mutex)
|
||||||
|
#else/*HAVE_THREADS*/
|
||||||
|
# define Lock_state()
|
||||||
|
# define Unlock_state()
|
||||||
|
#endif/*HAVE_THREADS*/
|
||||||
|
|
||||||
/** \brief Retrieves a translation colormap from the cache.
|
/** \brief Retrieves a translation colormap from the cache.
|
||||||
|
|
||||||
|
@ -589,13 +553,16 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
|
||||||
|
|
||||||
if (flags & GTC_CACHE)
|
if (flags & GTC_CACHE)
|
||||||
{
|
{
|
||||||
|
Lock_state();
|
||||||
// Allocate table for skin if necessary
|
// Allocate table for skin if necessary
|
||||||
if (!translationtablecache[skintableindex])
|
if (!translationtablecache[skintableindex])
|
||||||
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
|
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
// Get colormap
|
// Get colormap
|
||||||
ret = translationtablecache[skintableindex][color];
|
ret = translationtablecache[skintableindex][color];
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
// Rebuild the cache if necessary
|
// Rebuild the cache if necessary
|
||||||
if (skincolor_modified[color])
|
if (skincolor_modified[color])
|
||||||
{
|
{
|
||||||
|
@ -605,18 +572,21 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
|
||||||
|
|
||||||
skincolor_modified[color] = false;
|
skincolor_modified[color] = false;
|
||||||
}
|
}
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
else ret = NULL;
|
else ret = NULL;
|
||||||
|
|
||||||
// Generate the colormap if necessary
|
// Generate the colormap if necessary
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
Lock_state();
|
||||||
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
|
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
|
||||||
R_GenerateTranslationColormap(ret, skinnum, color);
|
R_GenerateTranslationColormap(ret, skinnum, color);
|
||||||
|
|
||||||
// Cache the colormap if desired
|
// Cache the colormap if desired
|
||||||
if (flags & GTC_CACHE)
|
if (flags & GTC_CACHE)
|
||||||
translationtablecache[skintableindex][color] = ret;
|
translationtablecache[skintableindex][color] = ret;
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -887,13 +857,37 @@ void R_DrawViewBorder(void)
|
||||||
// INCLUDE 8bpp DRAWING CODE HERE
|
// INCLUDE 8bpp DRAWING CODE HERE
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
// R_CalcTiltedLighting
|
||||||
|
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
|
||||||
|
static void R_CalcTiltedLighting(spancontext_t *ds, fixed_t start, fixed_t end)
|
||||||
|
{
|
||||||
|
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
|
||||||
|
// of this function. Here's my own.
|
||||||
|
INT32 left = ds->x1, right = ds->x2;
|
||||||
|
fixed_t step = (end-start)/(ds->x2-ds->x1+1);
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
|
||||||
|
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
|
||||||
|
|
||||||
|
for (i = left; i <= right; i++) {
|
||||||
|
ds->tiltlighting[i] = (start += step) >> FRACBITS;
|
||||||
|
if (ds->tiltlighting[i] < 0)
|
||||||
|
ds->tiltlighting[i] = 0;
|
||||||
|
else if (ds->tiltlighting[i] >= MAXLIGHTSCALE)
|
||||||
|
ds->tiltlighting[i] = MAXLIGHTSCALE-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan))
|
||||||
|
|
||||||
|
// Lighting is simple. It's just linear interpolation from start to end
|
||||||
|
#define CALC_TILTED_LIGHTING { \
|
||||||
|
float planelightfloat = PLANELIGHTFLOAT; \
|
||||||
|
float lightend = (iz + ds->szp->x*width) * planelightfloat; \
|
||||||
|
float lightstart = iz * planelightfloat; \
|
||||||
|
R_CalcTiltedLighting(ds, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); \
|
||||||
|
}
|
||||||
|
|
||||||
#include "r_draw8.c"
|
#include "r_draw8.c"
|
||||||
#include "r_draw8_npo2.c"
|
#include "r_draw8_npo2.c"
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
// INCLUDE 16bpp DRAWING CODE HERE
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
#ifdef HIGHCOLOR
|
|
||||||
#include "r_draw16.c"
|
|
||||||
#endif
|
|
||||||
|
|
281
src/r_draw.h
281
src/r_draw.h
|
@ -25,61 +25,7 @@ extern UINT8 *ylookup2[MAXVIDHEIGHT*4];
|
||||||
extern INT32 columnofs[MAXVIDWIDTH*4];
|
extern INT32 columnofs[MAXVIDWIDTH*4];
|
||||||
extern UINT8 *topleft;
|
extern UINT8 *topleft;
|
||||||
|
|
||||||
// -------------------------
|
extern float focallengthf;
|
||||||
// COLUMN DRAWING CODE STUFF
|
|
||||||
// -------------------------
|
|
||||||
|
|
||||||
extern lighttable_t *dc_colormap;
|
|
||||||
extern INT32 dc_x, dc_yl, dc_yh;
|
|
||||||
extern fixed_t dc_iscale, dc_texturemid;
|
|
||||||
extern UINT8 dc_hires;
|
|
||||||
|
|
||||||
extern UINT8 *dc_source; // first pixel in a column
|
|
||||||
|
|
||||||
// translucency stuff here
|
|
||||||
extern UINT8 *dc_transmap;
|
|
||||||
|
|
||||||
// translation stuff here
|
|
||||||
|
|
||||||
extern UINT8 *dc_translation;
|
|
||||||
|
|
||||||
extern struct r_lightlist_s *dc_lightlist;
|
|
||||||
extern INT32 dc_numlights, dc_maxlights;
|
|
||||||
|
|
||||||
//Fix TUTIFRUTI
|
|
||||||
extern INT32 dc_texheight;
|
|
||||||
|
|
||||||
// -----------------------
|
|
||||||
// SPAN DRAWING CODE STUFF
|
|
||||||
// -----------------------
|
|
||||||
|
|
||||||
extern INT32 ds_y, ds_x1, ds_x2;
|
|
||||||
extern lighttable_t *ds_colormap;
|
|
||||||
extern lighttable_t *ds_translation;
|
|
||||||
|
|
||||||
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
|
||||||
extern INT32 ds_waterofs, ds_bgofs;
|
|
||||||
|
|
||||||
extern UINT16 ds_flatwidth, ds_flatheight;
|
|
||||||
extern boolean ds_powersoftwo;
|
|
||||||
|
|
||||||
extern UINT8 *ds_source;
|
|
||||||
extern UINT8 *ds_transmap;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float x, y, z;
|
|
||||||
} floatv3_t;
|
|
||||||
|
|
||||||
// Vectors for Software's tilted slope drawers
|
|
||||||
extern floatv3_t *ds_su, *ds_sv, *ds_sz;
|
|
||||||
extern floatv3_t *ds_sup, *ds_svp, *ds_szp;
|
|
||||||
extern float focallengthf, zeroheight;
|
|
||||||
|
|
||||||
// Variable flat sizes
|
|
||||||
extern UINT32 nflatxshift;
|
|
||||||
extern UINT32 nflatyshift;
|
|
||||||
extern UINT32 nflatshiftup;
|
|
||||||
extern UINT32 nflatmask;
|
|
||||||
|
|
||||||
/// \brief Top border
|
/// \brief Top border
|
||||||
#define BRDR_T 0
|
#define BRDR_T 0
|
||||||
|
@ -163,85 +109,180 @@ void R_DrawViewBorder(void);
|
||||||
|
|
||||||
#define TRANSPARENTPIXEL 255
|
#define TRANSPARENTPIXEL 255
|
||||||
|
|
||||||
|
typedef struct colcontext_s
|
||||||
|
{
|
||||||
|
void (*func) (struct colcontext_s *);
|
||||||
|
vbuffer_t *dest;
|
||||||
|
|
||||||
|
INT32 x, yl, yh;
|
||||||
|
fixed_t iscale, texturemid;
|
||||||
|
lighttable_t *colormap;
|
||||||
|
|
||||||
|
UINT8 *source; // first pixel in a column
|
||||||
|
|
||||||
|
// translucency stuff here
|
||||||
|
UINT8 *transmap;
|
||||||
|
|
||||||
|
// translation stuff here
|
||||||
|
UINT8 *translation;
|
||||||
|
|
||||||
|
struct r_lightlist_s *lightlist;
|
||||||
|
INT32 numlights, maxlights;
|
||||||
|
|
||||||
|
//Fix TUTIFRUTI
|
||||||
|
INT32 texheight;
|
||||||
|
|
||||||
|
// vars for R_DrawMaskedColumn
|
||||||
|
// Rum and Raisin put these on the sprite context.
|
||||||
|
// I put them on the column context because it felt
|
||||||
|
// more appropriate (for [REDACTED] anyway)
|
||||||
|
INT16 *mfloorclip;
|
||||||
|
INT16 *mceilingclip;
|
||||||
|
|
||||||
|
fixed_t spryscale, sprtopscreen, sprbotscreen;
|
||||||
|
fixed_t windowtop, windowbottom;
|
||||||
|
|
||||||
|
// column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||||
|
INT32 lengthcol;
|
||||||
|
} colcontext_t;
|
||||||
|
|
||||||
|
typedef struct spancontext_s
|
||||||
|
{
|
||||||
|
void (*func) (struct spancontext_s *);
|
||||||
|
vbuffer_t *dest;
|
||||||
|
|
||||||
|
INT32 y, x1, x2;
|
||||||
|
lighttable_t *colormap;
|
||||||
|
lighttable_t *translation;
|
||||||
|
|
||||||
|
fixed_t xfrac, yfrac, xstep, ystep;
|
||||||
|
INT32 waterofs, bgofs;
|
||||||
|
|
||||||
|
UINT16 flatwidth, flatheight;
|
||||||
|
boolean powersoftwo;
|
||||||
|
|
||||||
|
UINT8 *source;
|
||||||
|
UINT8 *transmap;
|
||||||
|
|
||||||
|
// Vectors for Software's tilted slope drawers
|
||||||
|
floatv3_t *su, *sv, *sz;
|
||||||
|
floatv3_t *sup, *svp, *szp;
|
||||||
|
floatv3_t slope_origin, slope_u, slope_v;
|
||||||
|
float zeroheight;
|
||||||
|
|
||||||
|
// Variable flat sizes
|
||||||
|
UINT32 nflatxshift;
|
||||||
|
UINT32 nflatyshift;
|
||||||
|
UINT32 nflatshiftup;
|
||||||
|
UINT32 nflatmask;
|
||||||
|
|
||||||
|
lighttable_t **zlight;
|
||||||
|
INT32 tiltlighting[MAXVIDWIDTH];
|
||||||
|
} spancontext_t;
|
||||||
|
|
||||||
|
typedef void (*colfunc_t) (colcontext_t *);
|
||||||
|
typedef void (*spanfunc_t) (spancontext_t *);
|
||||||
|
|
||||||
|
// ---------------------------------------------
|
||||||
|
// color mode dependent drawer function pointers
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
#define BASEDRAWFUNC 0
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
COLDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||||
|
COLDRAWFUNC_FUZZY,
|
||||||
|
COLDRAWFUNC_TRANS,
|
||||||
|
COLDRAWFUNC_SHADE,
|
||||||
|
COLDRAWFUNC_SHADOWED,
|
||||||
|
COLDRAWFUNC_TRANSTRANS,
|
||||||
|
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||||
|
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||||
|
COLDRAWFUNC_FOG,
|
||||||
|
|
||||||
|
COLDRAWFUNC_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
extern colfunc_t colfuncs[COLDRAWFUNC_MAX];
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SPANDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||||
|
SPANDRAWFUNC_TRANS,
|
||||||
|
SPANDRAWFUNC_TILTED,
|
||||||
|
SPANDRAWFUNC_TILTEDTRANS,
|
||||||
|
|
||||||
|
SPANDRAWFUNC_SPLAT,
|
||||||
|
SPANDRAWFUNC_TRANSSPLAT,
|
||||||
|
SPANDRAWFUNC_TILTEDSPLAT,
|
||||||
|
|
||||||
|
SPANDRAWFUNC_SPRITE,
|
||||||
|
SPANDRAWFUNC_TRANSSPRITE,
|
||||||
|
SPANDRAWFUNC_TILTEDSPRITE,
|
||||||
|
SPANDRAWFUNC_TILTEDTRANSSPRITE,
|
||||||
|
|
||||||
|
SPANDRAWFUNC_WATER,
|
||||||
|
SPANDRAWFUNC_TILTEDWATER,
|
||||||
|
|
||||||
|
SPANDRAWFUNC_FOG,
|
||||||
|
|
||||||
|
SPANDRAWFUNC_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
extern spanfunc_t spanfuncs[SPANDRAWFUNC_MAX];
|
||||||
|
extern spanfunc_t spanfuncs_npo2[SPANDRAWFUNC_MAX];
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// 8bpp DRAWING CODE
|
// 8bpp DRAWING CODE
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
void R_DrawColumn_8(void);
|
void R_DrawColumn_8(colcontext_t *dc);
|
||||||
void R_DrawShadeColumn_8(void);
|
void R_DrawShadeColumn_8(colcontext_t *dc);
|
||||||
void R_DrawTranslucentColumn_8(void);
|
void R_DrawTranslucentColumn_8(colcontext_t *dc);
|
||||||
void R_DrawTranslatedColumn_8(void);
|
void R_DrawTranslatedColumn_8(colcontext_t *dc);
|
||||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
void R_DrawTranslatedTranslucentColumn_8(colcontext_t *dc);
|
||||||
void R_Draw2sMultiPatchColumn_8(void);
|
void R_Draw2sMultiPatchColumn_8(colcontext_t *dc);
|
||||||
void R_Draw2sMultiPatchTranslucentColumn_8(void);
|
void R_Draw2sMultiPatchTranslucentColumn_8(colcontext_t *dc);
|
||||||
void R_DrawFogColumn_8(void);
|
void R_DrawFogColumn_8(colcontext_t *dc);
|
||||||
void R_DrawColumnShadowed_8(void);
|
void R_DrawColumnShadowed_8(colcontext_t *dc);
|
||||||
|
|
||||||
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan))
|
void R_DrawSpan_8(spancontext_t *ds);
|
||||||
|
void R_DrawTranslucentSpan_8(spancontext_t *ds);
|
||||||
|
void R_DrawTiltedSpan_8(spancontext_t *ds);
|
||||||
|
void R_DrawTiltedTranslucentSpan_8(spancontext_t *ds);
|
||||||
|
|
||||||
void R_DrawSpan_8(void);
|
void R_DrawSplat_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentSpan_8(void);
|
void R_DrawTranslucentSplat_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedSpan_8(void);
|
void R_DrawTiltedSplat_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedTranslucentSpan_8(void);
|
|
||||||
|
|
||||||
void R_DrawSplat_8(void);
|
void R_DrawFloorSprite_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentSplat_8(void);
|
void R_DrawTranslucentFloorSprite_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedSplat_8(void);
|
void R_DrawTiltedFloorSprite_8(spancontext_t *ds);
|
||||||
|
void R_DrawTiltedTranslucentFloorSprite_8(spancontext_t *ds);
|
||||||
|
|
||||||
void R_DrawFloorSprite_8(void);
|
void R_DrawTranslucentWaterSpan_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentFloorSprite_8(void);
|
void R_DrawTiltedTranslucentWaterSpan_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedFloorSprite_8(void);
|
|
||||||
void R_DrawTiltedTranslucentFloorSprite_8(void);
|
|
||||||
|
|
||||||
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
|
void R_DrawFogSpan_8(spancontext_t *ds);
|
||||||
extern INT32 tiltlighting[MAXVIDWIDTH];
|
|
||||||
|
|
||||||
void R_DrawTranslucentWaterSpan_8(void);
|
|
||||||
void R_DrawTiltedTranslucentWaterSpan_8(void);
|
|
||||||
|
|
||||||
void R_DrawFogSpan_8(void);
|
|
||||||
|
|
||||||
// Lactozilla: Non-powers-of-two
|
// Lactozilla: Non-powers-of-two
|
||||||
void R_DrawSpan_NPO2_8(void);
|
void R_DrawSpan_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentSpan_NPO2_8(void);
|
void R_DrawTranslucentSpan_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedSpan_NPO2_8(void);
|
void R_DrawTiltedSpan_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedTranslucentSpan_NPO2_8(void);
|
void R_DrawTiltedTranslucentSpan_NPO2_8(spancontext_t *ds);
|
||||||
|
|
||||||
void R_DrawSplat_NPO2_8(void);
|
void R_DrawSplat_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentSplat_NPO2_8(void);
|
void R_DrawTranslucentSplat_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedSplat_NPO2_8(void);
|
void R_DrawTiltedSplat_NPO2_8(spancontext_t *ds);
|
||||||
|
|
||||||
void R_DrawFloorSprite_NPO2_8(void);
|
void R_DrawFloorSprite_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTranslucentFloorSprite_NPO2_8(void);
|
void R_DrawTranslucentFloorSprite_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedFloorSprite_NPO2_8(void);
|
void R_DrawTiltedFloorSprite_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void);
|
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(spancontext_t *ds);
|
||||||
|
|
||||||
void R_DrawTranslucentWaterSpan_NPO2_8(void);
|
void R_DrawTranslucentWaterSpan_NPO2_8(spancontext_t *ds);
|
||||||
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
|
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(spancontext_t *ds);
|
||||||
|
|
||||||
#ifdef USEASM
|
|
||||||
void ASMCALL R_DrawColumn_8_ASM(void);
|
|
||||||
void ASMCALL R_DrawShadeColumn_8_ASM(void);
|
|
||||||
void ASMCALL R_DrawTranslucentColumn_8_ASM(void);
|
|
||||||
void ASMCALL R_Draw2sMultiPatchColumn_8_ASM(void);
|
|
||||||
|
|
||||||
void ASMCALL R_DrawColumn_8_MMX(void);
|
|
||||||
|
|
||||||
void ASMCALL R_Draw2sMultiPatchColumn_8_MMX(void);
|
|
||||||
void ASMCALL R_DrawSpan_8_MMX(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------
|
|
||||||
// 16bpp DRAWING CODE
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
#ifdef HIGHCOLOR
|
|
||||||
void R_DrawColumn_16(void);
|
|
||||||
void R_DrawWallColumn_16(void);
|
|
||||||
void R_DrawTranslucentColumn_16(void);
|
|
||||||
void R_DrawTranslatedColumn_16(void);
|
|
||||||
void R_DrawSpan_16(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
#endif // __R_DRAW__
|
#endif // __R_DRAW__
|
||||||
|
|
214
src/r_draw16.c
214
src/r_draw16.c
|
@ -1,214 +0,0 @@
|
||||||
// SONIC ROBO BLAST 2
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
||||||
// Copyright (C) 1999-2021 by Sonic Team Junior.
|
|
||||||
//
|
|
||||||
// This program is free software distributed under the
|
|
||||||
// terms of the GNU General Public License, version 2.
|
|
||||||
// See the 'LICENSE' file for more details.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/// \file r_draw16.c
|
|
||||||
/// \brief 16bpp (HIGHCOLOR) span/column drawer functions
|
|
||||||
/// \note no includes because this is included as part of r_draw.c
|
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
// COLUMNS
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
/// \brief kick out the upper bit of each component (we're in 5 : 5 : 5)
|
|
||||||
#define HIMASK1 0x7bde
|
|
||||||
|
|
||||||
/** \brief The R_DrawColumn_16 function
|
|
||||||
standard upto 128high posts column drawer
|
|
||||||
*/
|
|
||||||
void R_DrawColumn_16(void)
|
|
||||||
{
|
|
||||||
INT32 count;
|
|
||||||
INT16 *dest;
|
|
||||||
fixed_t frac, fracstep;
|
|
||||||
|
|
||||||
count = dc_yh - dc_yl + 1;
|
|
||||||
|
|
||||||
// Zero length, column does not exceed a pixel.
|
|
||||||
if (count <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
|
||||||
I_Error("R_DrawColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Framebuffer destination address.
|
|
||||||
// Use ylookup LUT to avoid multiply with ScreenWidth.
|
|
||||||
// Use columnofs LUT for subwindows?
|
|
||||||
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
|
|
||||||
|
|
||||||
// Determine scaling, which is the only mapping to be done.
|
|
||||||
fracstep = dc_iscale;
|
|
||||||
frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
|
||||||
|
|
||||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
|
||||||
// This is as fast as it gets.
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Re-map color indices from wall texture column using a lighting/special effects LUT.
|
|
||||||
*dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&127]>>1];
|
|
||||||
|
|
||||||
dest += vid.width;
|
|
||||||
frac += fracstep;
|
|
||||||
} while (--count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief The R_DrawWallColumn_16 function
|
|
||||||
LAME cutnpaste: same as R_DrawColumn_16 but wraps around 256
|
|
||||||
instead of 128 for the tall sky textures (256x240)
|
|
||||||
*/
|
|
||||||
void R_DrawWallColumn_16(void)
|
|
||||||
{
|
|
||||||
INT32 count;
|
|
||||||
INT16 *dest;
|
|
||||||
fixed_t frac, fracstep;
|
|
||||||
|
|
||||||
count = dc_yh - dc_yl + 1;
|
|
||||||
|
|
||||||
// Zero length, column does not exceed a pixel.
|
|
||||||
if (count <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
|
||||||
I_Error("R_DrawWallColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
|
|
||||||
|
|
||||||
fracstep = dc_iscale;
|
|
||||||
frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
*dest = hicolormaps[((INT16 *)(void *)dc_source)[(frac>>FRACBITS)&255]>>1];
|
|
||||||
|
|
||||||
dest += vid.width;
|
|
||||||
frac += fracstep;
|
|
||||||
} while (--count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief The R_DrawTranslucentColumn_16 function
|
|
||||||
LAME cutnpaste: same as R_DrawColumn_16 but does
|
|
||||||
translucent
|
|
||||||
*/
|
|
||||||
void R_DrawTranslucentColumn_16(void)
|
|
||||||
{
|
|
||||||
INT32 count;
|
|
||||||
INT16 *dest;
|
|
||||||
fixed_t frac, fracstep;
|
|
||||||
|
|
||||||
// check out coords for src*
|
|
||||||
if ((dc_yl < 0) || (dc_x >= vid.width))
|
|
||||||
return;
|
|
||||||
|
|
||||||
count = dc_yh - dc_yl;
|
|
||||||
if (count < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
|
||||||
I_Error("R_DrawTranslucentColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// FIXME. As above.
|
|
||||||
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
|
|
||||||
|
|
||||||
// Looks familiar.
|
|
||||||
fracstep = dc_iscale;
|
|
||||||
frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
|
||||||
|
|
||||||
// Here we do an additional index re-mapping.
|
|
||||||
do
|
|
||||||
{
|
|
||||||
*dest = (INT16)((INT16)((color8to16[dc_source[frac>>FRACBITS]]>>1) & 0x39ce)
|
|
||||||
+ (INT16)(((*dest & HIMASK1)) & 0x7fff));
|
|
||||||
|
|
||||||
dest += vid.width;
|
|
||||||
frac += fracstep;
|
|
||||||
} while (count--);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief The R_DrawTranslatedColumn_16 function
|
|
||||||
?
|
|
||||||
*/
|
|
||||||
void R_DrawTranslatedColumn_16(void)
|
|
||||||
{
|
|
||||||
INT32 count;
|
|
||||||
INT16 *dest;
|
|
||||||
fixed_t frac, fracstep;
|
|
||||||
|
|
||||||
count = dc_yh - dc_yl;
|
|
||||||
if (count < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (dc_x >= vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
|
||||||
I_Error("R_DrawTranslatedColumn_16: %d to %d at %d", dc_yl, dc_yh, dc_x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dest = (INT16 *)(void *)(ylookup[dc_yl] + columnofs[dc_x]);
|
|
||||||
|
|
||||||
// Looks familiar.
|
|
||||||
fracstep = dc_iscale;
|
|
||||||
frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
|
||||||
|
|
||||||
// Here we do an additional index re-mapping.
|
|
||||||
do
|
|
||||||
{
|
|
||||||
*dest = color8to16[dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]];
|
|
||||||
dest += vid.width;
|
|
||||||
|
|
||||||
frac += fracstep;
|
|
||||||
} while (count--);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================================================================
|
|
||||||
// SPANS
|
|
||||||
// ==========================================================================
|
|
||||||
|
|
||||||
/** \brief The R_*_16 function
|
|
||||||
Draws the actual span.
|
|
||||||
*/
|
|
||||||
void R_DrawSpan_16(void)
|
|
||||||
{
|
|
||||||
fixed_t xfrac, yfrac;
|
|
||||||
INT16 *dest;
|
|
||||||
INT32 count, spot;
|
|
||||||
|
|
||||||
#ifdef RANGECHECK
|
|
||||||
if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= vid.width || ds_y > vid.height)
|
|
||||||
I_Error("R_DrawSpan_16: %d to %d at %d", ds_x1, ds_x2, ds_y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xfrac = ds_xfrac;
|
|
||||||
yfrac = ds_yfrac;
|
|
||||||
|
|
||||||
dest = (INT16 *)(void *)(ylookup[ds_y] + columnofs[ds_x1]);
|
|
||||||
|
|
||||||
// We do not check for zero spans here?
|
|
||||||
count = ds_x2 - ds_x1;
|
|
||||||
|
|
||||||
if (count <= 0) // We do now!
|
|
||||||
return;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Current texture index in u, v.
|
|
||||||
spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
|
|
||||||
|
|
||||||
// Lookup pixel from flat texture tile, re-index using light/colormap.
|
|
||||||
*dest++ = hicolormaps[((INT16 *)(void *)ds_source)[spot]>>1];
|
|
||||||
|
|
||||||
// Next step in u, v.
|
|
||||||
xfrac += ds_xstep;
|
|
||||||
yfrac += ds_ystep;
|
|
||||||
} while (count--);
|
|
||||||
}
|
|
898
src/r_draw8.c
898
src/r_draw8.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -34,8 +34,7 @@
|
||||||
#include "r_textures.h"
|
#include "r_textures.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
|
#include "r_context.h"
|
||||||
extern drawseg_t *firstseg;
|
|
||||||
|
|
||||||
void SplitScreen_OnChange(void);
|
void SplitScreen_OnChange(void);
|
||||||
|
|
||||||
|
|
584
src/r_main.c
584
src/r_main.c
|
@ -53,6 +53,22 @@ INT64 mytotal = 0;
|
||||||
// Fineangles in the SCREENWIDTH wide window.
|
// Fineangles in the SCREENWIDTH wide window.
|
||||||
#define FIELDOFVIEW 2048
|
#define FIELDOFVIEW 2048
|
||||||
|
|
||||||
|
typedef struct renderdata_s
|
||||||
|
{
|
||||||
|
rendercontext_t context;
|
||||||
|
I_thread_handle thread;
|
||||||
|
I_Atomicval_t running;
|
||||||
|
I_Atomicval_t shouldquit;
|
||||||
|
I_Atomicval_t framewaiting;
|
||||||
|
I_Atomicval_t framefinished;
|
||||||
|
} renderdata_t;
|
||||||
|
|
||||||
|
static renderdata_t *renderdatas;
|
||||||
|
|
||||||
|
INT32 numrendercontexts = MAX_RENDER_THREADS;
|
||||||
|
INT32 numusablerendercontexts = 0;
|
||||||
|
boolean renderthreaded = false;
|
||||||
|
|
||||||
// increment every time a check is made
|
// increment every time a check is made
|
||||||
size_t validcount = 1;
|
size_t validcount = 1;
|
||||||
|
|
||||||
|
@ -102,20 +118,21 @@ extracolormap_t *extra_colormaps = NULL;
|
||||||
// Render stats
|
// Render stats
|
||||||
precise_t ps_prevframetime = 0;
|
precise_t ps_prevframetime = 0;
|
||||||
precise_t ps_rendercalltime = 0;
|
precise_t ps_rendercalltime = 0;
|
||||||
|
precise_t ps_postprocesstime = 0;
|
||||||
precise_t ps_uitime = 0;
|
precise_t ps_uitime = 0;
|
||||||
precise_t ps_swaptime = 0;
|
precise_t ps_swaptime = 0;
|
||||||
|
|
||||||
precise_t ps_bsptime = 0;
|
precise_t ps_bsptime[MAX_RENDER_THREADS] = {0};
|
||||||
|
|
||||||
precise_t ps_sw_spritecliptime = 0;
|
precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS] = {0};
|
||||||
precise_t ps_sw_portaltime = 0;
|
precise_t ps_sw_portaltime[MAX_RENDER_THREADS] = {0};
|
||||||
precise_t ps_sw_planetime = 0;
|
precise_t ps_sw_planetime[MAX_RENDER_THREADS] = {0};
|
||||||
precise_t ps_sw_maskedtime = 0;
|
precise_t ps_sw_maskedtime[MAX_RENDER_THREADS] = {0};
|
||||||
|
|
||||||
int ps_numbspcalls = 0;
|
int ps_numbspcalls[MAX_RENDER_THREADS] = {0};
|
||||||
int ps_numsprites = 0;
|
int ps_numsprites[MAX_RENDER_THREADS] = {0};
|
||||||
int ps_numdrawnodes = 0;
|
int ps_numdrawnodes[MAX_RENDER_THREADS] = {0};
|
||||||
int ps_numpolyobjects = 0;
|
int ps_numpolyobjects[MAX_RENDER_THREADS] = {0};
|
||||||
|
|
||||||
static CV_PossibleValue_t drawdist_cons_t[] = {
|
static CV_PossibleValue_t drawdist_cons_t[] = {
|
||||||
{256, "256"}, {512, "512"}, {768, "768"},
|
{256, "256"}, {512, "512"}, {768, "768"},
|
||||||
|
@ -132,7 +149,7 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
|
||||||
|
|
||||||
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
|
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
||||||
|
|
||||||
static void Fov_OnChange(void);
|
static void Fov_OnChange(void);
|
||||||
|
@ -163,9 +180,11 @@ consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, dr
|
||||||
//consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL);
|
//consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL);
|
||||||
consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange);
|
consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange);
|
||||||
|
|
||||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
|
||||||
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL);
|
consvar_t cv_homremoval = CVAR_INIT ("homremoval", "No", CV_SAVE, homremoval_cons_t, NULL);
|
||||||
|
|
||||||
|
static CV_PossibleValue_t numthreads_cons_t[] = {{1, "MIN"}, {8, "MAX"}, {0, NULL}};
|
||||||
|
consvar_t cv_numthreads = CVAR_INIT ("numthreads", "2", CV_SAVE, numthreads_cons_t, NULL);
|
||||||
|
|
||||||
consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL);
|
consvar_t cv_maxportals = CVAR_INIT ("maxportals", "2", CV_SAVE, maxportals_cons_t, NULL);
|
||||||
|
|
||||||
consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL);
|
consvar_t cv_renderstats = CVAR_INIT ("renderstats", "Off", 0, CV_OnOff, NULL);
|
||||||
|
@ -411,35 +430,6 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1)
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// R_ScaleFromGlobalAngle
|
|
||||||
// Returns the texture mapping scale for the current line (horizontal span)
|
|
||||||
// at the given angle.
|
|
||||||
// rw_distance must be calculated first.
|
|
||||||
//
|
|
||||||
// killough 5/2/98: reformatted, cleaned up
|
|
||||||
//
|
|
||||||
// note: THIS IS USED ONLY FOR WALLS!
|
|
||||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle)
|
|
||||||
{
|
|
||||||
angle_t anglea = ANGLE_90 + (visangle-viewangle);
|
|
||||||
angle_t angleb = ANGLE_90 + (visangle-rw_normalangle);
|
|
||||||
fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT));
|
|
||||||
// proff 11/06/98: Changed for high-res
|
|
||||||
fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT));
|
|
||||||
|
|
||||||
if (den > num>>16)
|
|
||||||
{
|
|
||||||
num = FixedDiv(num, den);
|
|
||||||
if (num > 64*FRACUNIT)
|
|
||||||
return 64*FRACUNIT;
|
|
||||||
if (num < 256)
|
|
||||||
return 256;
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
return 64*FRACUNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_DoCulling
|
// R_DoCulling
|
||||||
// Checks viewz and top/bottom heights of an item against culling planes
|
// Checks viewz and top/bottom heights of an item against culling planes
|
||||||
|
@ -883,6 +873,285 @@ void R_ApplyViewMorph(void)
|
||||||
vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.width);
|
vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void R_PortalFrame(rendercontext_t *context, portal_t *portal)
|
||||||
|
{
|
||||||
|
bspcontext_t *bspcontext = &context->bspcontext;
|
||||||
|
|
||||||
|
context->viewcontext.x = portal->viewx;
|
||||||
|
context->viewcontext.y = portal->viewy;
|
||||||
|
context->viewcontext.z = portal->viewz;
|
||||||
|
|
||||||
|
context->viewcontext.angle = portal->viewangle;
|
||||||
|
context->viewcontext.sin = FINESINE(portal->viewangle>>ANGLETOFINESHIFT);
|
||||||
|
context->viewcontext.cos = FINECOSINE(portal->viewangle>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
bspcontext->portalclipstart = portal->start;
|
||||||
|
bspcontext->portalclipend = portal->end;
|
||||||
|
|
||||||
|
if (portal->clipline != -1)
|
||||||
|
{
|
||||||
|
line_t *clipline = &lines[portal->clipline];
|
||||||
|
bspcontext->portalclipline = clipline;
|
||||||
|
bspcontext->portalcullsector = clipline->frontsector;
|
||||||
|
context->viewcontext.sector = clipline->frontsector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bspcontext->portalclipline = NULL;
|
||||||
|
bspcontext->portalcullsector = NULL;
|
||||||
|
context->viewcontext.sector = R_PointInSubsector(context->viewcontext.x, context->viewcontext.y)->sector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mask_Pre (rendercontext_t *context, maskcount_t* m)
|
||||||
|
{
|
||||||
|
m->drawsegs[0] = context->bspcontext.ds_p - context->bspcontext.drawsegs;
|
||||||
|
m->vissprites[0] = context->spritecontext.visspritecount;
|
||||||
|
m->viewx = context->viewcontext.x;
|
||||||
|
m->viewy = context->viewcontext.y;
|
||||||
|
m->viewz = context->viewcontext.z;
|
||||||
|
m->viewsector = context->viewcontext.sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mask_Post (rendercontext_t *context, maskcount_t* m)
|
||||||
|
{
|
||||||
|
m->drawsegs[1] = context->bspcontext.ds_p - context->bspcontext.drawsegs;
|
||||||
|
m->vissprites[1] = context->spritecontext.visspritecount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void R_RenderViewContext(rendercontext_t *rendercontext)
|
||||||
|
{
|
||||||
|
UINT8 nummasks = 1;
|
||||||
|
maskcount_t* masks = malloc(sizeof(maskcount_t));
|
||||||
|
|
||||||
|
bspcontext_t *bspcontext = &rendercontext->bspcontext;
|
||||||
|
planecontext_t *planecontext = &rendercontext->planecontext;
|
||||||
|
|
||||||
|
INT32 i = rendercontext->num;
|
||||||
|
|
||||||
|
// The head node is the last node output.
|
||||||
|
Mask_Pre(rendercontext, &masks[nummasks - 1]);
|
||||||
|
bspcontext->curdrawsegs = bspcontext->ds_p;
|
||||||
|
|
||||||
|
ps_numbspcalls[i] = ps_numpolyobjects[i] = ps_numdrawnodes[i] = 0;
|
||||||
|
|
||||||
|
ps_bsptime[i] = I_GetPreciseTime();
|
||||||
|
R_RenderBSPNode(rendercontext, (INT32)numnodes - 1);
|
||||||
|
ps_bsptime[i] = I_GetPreciseTime() - ps_bsptime[i];
|
||||||
|
ps_numsprites[i] = rendercontext->spritecontext.visspritecount;
|
||||||
|
|
||||||
|
Mask_Post(rendercontext, &masks[nummasks - 1]);
|
||||||
|
|
||||||
|
ps_sw_spritecliptime[i] = I_GetPreciseTime();
|
||||||
|
R_ClipSprites(rendercontext, bspcontext->drawsegs, NULL);
|
||||||
|
ps_sw_spritecliptime[i] = I_GetPreciseTime() - ps_sw_spritecliptime[i];
|
||||||
|
|
||||||
|
// Add skybox portals caused by sky visplanes.
|
||||||
|
if (cv_skybox.value && skyboxmo[0])
|
||||||
|
Portal_AddSkyboxPortals(rendercontext);
|
||||||
|
|
||||||
|
// Portal rendering. Hijacks the BSP traversal.
|
||||||
|
ps_sw_portaltime[i] = I_GetPreciseTime();
|
||||||
|
if (bspcontext->portal_base)
|
||||||
|
{
|
||||||
|
portal_t *portal = bspcontext->portal_base;
|
||||||
|
|
||||||
|
for (; portal; portal = bspcontext->portal_base)
|
||||||
|
{
|
||||||
|
bspcontext->portalrender = portal->pass; // Recursiveness depth.
|
||||||
|
|
||||||
|
R_ClearFFloorClips(planecontext);
|
||||||
|
|
||||||
|
// Apply the viewpoint stored for the portal.
|
||||||
|
R_PortalFrame(rendercontext, portal);
|
||||||
|
|
||||||
|
// Hack in the clipsegs to delimit the starting
|
||||||
|
// clipping for sprites and possibly other similar
|
||||||
|
// future items.
|
||||||
|
R_ClearClipSegs(bspcontext, portal->start, portal->end);
|
||||||
|
|
||||||
|
// Hack in the top/bottom clip values for the window
|
||||||
|
// that were previously stored.
|
||||||
|
Portal_ClipApply(planecontext, portal);
|
||||||
|
|
||||||
|
masks = realloc(masks, (++nummasks)*sizeof(maskcount_t));
|
||||||
|
|
||||||
|
Mask_Pre(rendercontext, &masks[nummasks - 1]);
|
||||||
|
bspcontext->curdrawsegs = bspcontext->ds_p;
|
||||||
|
|
||||||
|
// Render the BSP from the new viewpoint, and clip
|
||||||
|
// any sprites with the new clipsegs and window.
|
||||||
|
R_RenderBSPNode(rendercontext, (INT32)numnodes - 1);
|
||||||
|
Mask_Post(rendercontext, &masks[nummasks - 1]);
|
||||||
|
|
||||||
|
R_ClipSprites(rendercontext, bspcontext->ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
|
||||||
|
|
||||||
|
Portal_Remove(bspcontext, portal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ps_sw_portaltime[i] = I_GetPreciseTime() - ps_sw_portaltime[i];
|
||||||
|
|
||||||
|
ps_sw_planetime[i] = I_GetPreciseTime();
|
||||||
|
R_DrawPlanes(rendercontext);
|
||||||
|
ps_sw_planetime[i] = I_GetPreciseTime() - ps_sw_planetime[i];
|
||||||
|
|
||||||
|
// draw mid texture and sprite
|
||||||
|
// And now 3D floors/sides!
|
||||||
|
ps_sw_maskedtime[i] = I_GetPreciseTime();
|
||||||
|
R_DrawMasked(rendercontext, masks, nummasks);
|
||||||
|
ps_sw_maskedtime[i] = I_GetPreciseTime() - ps_sw_maskedtime[i];
|
||||||
|
|
||||||
|
free(masks);
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
if (renderthreaded)
|
||||||
|
{
|
||||||
|
INT32 x = rendercontext->begincolumn;
|
||||||
|
INT32 w = (rendercontext->endcolumn - rendercontext->begincolumn);
|
||||||
|
INT32 c = 35 | V_NOSCALESTART;
|
||||||
|
|
||||||
|
V_DrawFill(x, 0, w, 1, c);
|
||||||
|
V_DrawFill(x, viewheight - 1, w, 1, c);
|
||||||
|
|
||||||
|
V_DrawFill(x, 0, 1, viewheight, c);
|
||||||
|
V_DrawFill(x+w-1, 0, 1, viewheight, c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void R_ResetContext(rendercontext_t *context, INT32 leftclip, INT32 rightclip)
|
||||||
|
{
|
||||||
|
context->begincolumn = leftclip;
|
||||||
|
context->endcolumn = rightclip;
|
||||||
|
|
||||||
|
// Clear buffers.
|
||||||
|
R_ClearPlanes(&context->planecontext);
|
||||||
|
|
||||||
|
if (viewmorph.use)
|
||||||
|
{
|
||||||
|
INT32 left = max(leftclip, viewmorph.x1);
|
||||||
|
INT32 right = min(viewwidth-viewmorph.x1-1, rightclip);
|
||||||
|
|
||||||
|
context->bspcontext.portalclipstart = left;
|
||||||
|
context->bspcontext.portalclipend = right;
|
||||||
|
|
||||||
|
R_ClearClipSegs(&context->bspcontext, left, right);
|
||||||
|
|
||||||
|
memcpy(context->planecontext.ceilingclip, viewmorph.ceilingclip, sizeof(INT16)*vid.width);
|
||||||
|
memcpy(context->planecontext.floorclip, viewmorph.floorclip, sizeof(INT16)*vid.width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context->bspcontext.portalclipstart = leftclip;
|
||||||
|
context->bspcontext.portalclipend = rightclip;
|
||||||
|
|
||||||
|
R_ClearClipSegs(&context->bspcontext, leftclip, rightclip);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_ClearDrawSegs(&context->bspcontext);
|
||||||
|
R_ClearSprites(&context->spritecontext);
|
||||||
|
|
||||||
|
Portal_InitList(&context->bspcontext);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static void R_ContextThreadFunc(void *userdata)
|
||||||
|
{
|
||||||
|
renderdata_t *data = (renderdata_t *)userdata;
|
||||||
|
|
||||||
|
I_atomic_exchange(&data->running, 1);
|
||||||
|
|
||||||
|
while (!I_atomic_load(&data->shouldquit))
|
||||||
|
{
|
||||||
|
if (I_atomic_exchange(&data->framewaiting, 0))
|
||||||
|
{
|
||||||
|
R_RenderViewContext(&data->context);
|
||||||
|
I_atomic_exchange(&data->framefinished, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
I_atomic_exchange(&data->running, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void R_StartThreads(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
INT32 currcontext;
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext)
|
||||||
|
{
|
||||||
|
renderdata_t *renderdata = &renderdatas[currcontext];
|
||||||
|
rendercontext_t *context = &renderdata->context;
|
||||||
|
|
||||||
|
context->colcontext.func = colfuncs[BASEDRAWFUNC];
|
||||||
|
context->spancontext.func = spanfuncs[BASEDRAWFUNC];
|
||||||
|
|
||||||
|
I_atomic_exchange(&renderdata->running, 0);
|
||||||
|
I_atomic_exchange(&renderdata->shouldquit, 0);
|
||||||
|
I_atomic_exchange(&renderdata->framewaiting, 0);
|
||||||
|
I_atomic_exchange(&renderdata->framefinished, 0);
|
||||||
|
|
||||||
|
renderdata->thread = I_spawn_thread("software-renderer", (I_thread_fn)R_ContextThreadFunc, context);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_StopThreads(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
INT32 currcontext;
|
||||||
|
|
||||||
|
if (!numusablerendercontexts)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext)
|
||||||
|
I_atomic_exchange(&renderdatas[currcontext].shouldquit, 1);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
INT32 stoppedthreads = 0;
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext)
|
||||||
|
stoppedthreads += !I_atomic_load(&renderdatas[currcontext].running);
|
||||||
|
|
||||||
|
if (stoppedthreads == numusablerendercontexts)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
numusablerendercontexts = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void R_InitContexts(void)
|
||||||
|
{
|
||||||
|
INT32 currcontext;
|
||||||
|
INT32 currstart;
|
||||||
|
INT32 incrementby;
|
||||||
|
|
||||||
|
currstart = 0;
|
||||||
|
incrementby = vid.width / numrendercontexts;
|
||||||
|
|
||||||
|
renderdatas = Z_Calloc(sizeof(renderdata_t) * numrendercontexts, PU_STATIC, NULL);
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numrendercontexts; ++currcontext)
|
||||||
|
{
|
||||||
|
renderdata_t *renderdata = &renderdatas[currcontext];
|
||||||
|
rendercontext_t *context = &renderdata->context;
|
||||||
|
|
||||||
|
context->num = currcontext;
|
||||||
|
context->begincolumn = max(currstart, 0);
|
||||||
|
currstart += incrementby;
|
||||||
|
context->endcolumn = min(currstart, vid.width);
|
||||||
|
|
||||||
|
context->planecontext.freehead = &context->planecontext.freetail;
|
||||||
|
|
||||||
|
R_ResetContext(&renderdata->context, context->begincolumn, context->endcolumn);
|
||||||
|
R_InitDrawNodes(&renderdata->context.spritecontext.nodebankhead);
|
||||||
|
|
||||||
|
context->colcontext.func = colfuncs[BASEDRAWFUNC];
|
||||||
|
context->spancontext.func = spanfuncs[BASEDRAWFUNC];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_SetViewSize
|
// R_SetViewSize
|
||||||
|
@ -960,7 +1229,7 @@ void R_ExecuteSetViewSize(void)
|
||||||
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
|
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ds_su)
|
/*if (ds_su)
|
||||||
Z_Free(ds_su);
|
Z_Free(ds_su);
|
||||||
if (ds_sv)
|
if (ds_sv)
|
||||||
Z_Free(ds_sv);
|
Z_Free(ds_sv);
|
||||||
|
@ -968,7 +1237,7 @@ void R_ExecuteSetViewSize(void)
|
||||||
Z_Free(ds_sz);
|
Z_Free(ds_sz);
|
||||||
|
|
||||||
ds_su = ds_sv = ds_sz = NULL;
|
ds_su = ds_sv = ds_sz = NULL;
|
||||||
ds_sup = ds_svp = ds_szp = NULL;
|
ds_sup = ds_svp = ds_szp = NULL;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(scalelight, 0xFF, sizeof(scalelight));
|
memset(scalelight, 0xFF, sizeof(scalelight));
|
||||||
|
@ -1024,7 +1293,7 @@ void R_Init(void)
|
||||||
//I_OutputMsg("\nR_InitTranslucencyTables\n");
|
//I_OutputMsg("\nR_InitTranslucencyTables\n");
|
||||||
R_InitTranslucencyTables();
|
R_InitTranslucencyTables();
|
||||||
|
|
||||||
R_InitDrawNodes();
|
R_InitContexts();
|
||||||
|
|
||||||
framecount = 0;
|
framecount = 0;
|
||||||
}
|
}
|
||||||
|
@ -1394,63 +1663,57 @@ boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void R_PortalFrame(portal_t *portal)
|
|
||||||
{
|
|
||||||
viewx = portal->viewx;
|
|
||||||
viewy = portal->viewy;
|
|
||||||
viewz = portal->viewz;
|
|
||||||
|
|
||||||
viewangle = portal->viewangle;
|
|
||||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
|
||||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
|
||||||
|
|
||||||
portalclipstart = portal->start;
|
|
||||||
portalclipend = portal->end;
|
|
||||||
|
|
||||||
if (portal->clipline != -1)
|
|
||||||
{
|
|
||||||
portalclipline = &lines[portal->clipline];
|
|
||||||
portalcullsector = portalclipline->frontsector;
|
|
||||||
viewsector = portalclipline->frontsector;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
portalclipline = NULL;
|
|
||||||
portalcullsector = NULL;
|
|
||||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Mask_Pre (maskcount_t* m)
|
|
||||||
{
|
|
||||||
m->drawsegs[0] = ds_p - drawsegs;
|
|
||||||
m->vissprites[0] = visspritecount;
|
|
||||||
m->viewx = viewx;
|
|
||||||
m->viewy = viewy;
|
|
||||||
m->viewz = viewz;
|
|
||||||
m->viewsector = viewsector;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Mask_Post (maskcount_t* m)
|
|
||||||
{
|
|
||||||
m->drawsegs[1] = ds_p - drawsegs;
|
|
||||||
m->vissprites[1] = visspritecount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// R_RenderView
|
// R_RenderView
|
||||||
// ================
|
// ================
|
||||||
|
|
||||||
// FAB NOTE FOR WIN32 PORT !! I'm not finished already,
|
static void R_PrepareViewContext(viewcontext_t *context)
|
||||||
// but I suspect network may have problems with the video buffer being locked
|
{
|
||||||
// for all duration of rendering, and being released only once at the end..
|
context->x = viewx;
|
||||||
// I mean, there is a win16lock() or something that lasts all the rendering,
|
context->y = viewy;
|
||||||
// so maybe we should release screen lock before each netupdate below..?
|
context->z = viewz;
|
||||||
|
|
||||||
|
context->angle = viewangle;
|
||||||
|
context->sin = viewsin;
|
||||||
|
context->cos = viewcos;
|
||||||
|
|
||||||
|
context->sector = viewsector;
|
||||||
|
context->player = viewplayer;
|
||||||
|
context->mobj = r_viewmobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void R_PrepareContexts(void)
|
||||||
|
{
|
||||||
|
INT32 currcontext;
|
||||||
|
INT32 currstart = 0;
|
||||||
|
INT32 desiredwidth = viewwidth / numusablerendercontexts;
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; ++currcontext)
|
||||||
|
{
|
||||||
|
rendercontext_t *context = &renderdatas[currcontext].context;
|
||||||
|
|
||||||
|
context->buffer.screens[0] = topleft;
|
||||||
|
for (i = 1; i < NUMSCREENS; i++)
|
||||||
|
context->buffer.screens[i] = screens[i];
|
||||||
|
|
||||||
|
context->begincolumn = max(currstart, 0);
|
||||||
|
currstart += desiredwidth;
|
||||||
|
context->endcolumn = min(currstart, viewwidth);
|
||||||
|
|
||||||
|
R_ResetContext(context, context->begincolumn, context->endcolumn);
|
||||||
|
R_PrepareViewContext(&context->viewcontext);
|
||||||
|
|
||||||
|
if (context->spritecontext.sectorvisited == NULL)
|
||||||
|
context->spritecontext.sectorvisited = Z_Calloc(sizeof(boolean) * numsectors, PU_LEVEL, NULL);
|
||||||
|
memset(context->spritecontext.sectorvisited, 0, sizeof(boolean) * numsectors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void R_RenderPlayerView(player_t *player)
|
void R_RenderPlayerView(player_t *player)
|
||||||
{
|
{
|
||||||
UINT8 nummasks = 1;
|
INT32 currcontext;
|
||||||
maskcount_t* masks = malloc(sizeof(maskcount_t));
|
INT32 finishedcontexts = 0;
|
||||||
|
|
||||||
if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1
|
if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1
|
||||||
{
|
{
|
||||||
|
@ -1462,117 +1725,49 @@ void R_RenderPlayerView(player_t *player)
|
||||||
|
|
||||||
R_SetupFrame(player);
|
R_SetupFrame(player);
|
||||||
framecount++;
|
framecount++;
|
||||||
validcount++;
|
|
||||||
|
|
||||||
// Clear buffers.
|
|
||||||
R_ClearPlanes();
|
|
||||||
if (viewmorph.use)
|
|
||||||
{
|
|
||||||
portalclipstart = viewmorph.x1;
|
|
||||||
portalclipend = viewwidth-viewmorph.x1-1;
|
|
||||||
R_PortalClearClipSegs(portalclipstart, portalclipend);
|
|
||||||
memcpy(ceilingclip, viewmorph.ceilingclip, sizeof(INT16)*vid.width);
|
|
||||||
memcpy(floorclip, viewmorph.floorclip, sizeof(INT16)*vid.width);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
portalclipstart = 0;
|
|
||||||
portalclipend = viewwidth;
|
|
||||||
R_ClearClipSegs();
|
|
||||||
}
|
|
||||||
R_ClearDrawSegs();
|
|
||||||
R_ClearSprites();
|
|
||||||
Portal_InitList();
|
|
||||||
|
|
||||||
// check for new console commands.
|
// check for new console commands.
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
|
|
||||||
// The head node is the last node output.
|
#ifdef HAVE_THREADS
|
||||||
|
if (cv_numthreads.value != numusablerendercontexts)
|
||||||
Mask_Pre(&masks[nummasks - 1]);
|
|
||||||
curdrawsegs = ds_p;
|
|
||||||
//profile stuff ---------------------------------------------------------
|
|
||||||
#ifdef TIMING
|
|
||||||
mytotal = 0;
|
|
||||||
ProfZeroTimer();
|
|
||||||
#endif
|
|
||||||
ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0;
|
|
||||||
ps_bsptime = I_GetPreciseTime();
|
|
||||||
R_RenderBSPNode((INT32)numnodes - 1);
|
|
||||||
ps_bsptime = I_GetPreciseTime() - ps_bsptime;
|
|
||||||
ps_numsprites = visspritecount;
|
|
||||||
#ifdef TIMING
|
|
||||||
RDMSR(0x10, &mycount);
|
|
||||||
mytotal += mycount; // 64bit add
|
|
||||||
|
|
||||||
CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal);
|
|
||||||
#endif
|
|
||||||
//profile stuff ---------------------------------------------------------
|
|
||||||
Mask_Post(&masks[nummasks - 1]);
|
|
||||||
|
|
||||||
ps_sw_spritecliptime = I_GetPreciseTime();
|
|
||||||
R_ClipSprites(drawsegs, NULL);
|
|
||||||
ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime;
|
|
||||||
|
|
||||||
|
|
||||||
// Add skybox portals caused by sky visplanes.
|
|
||||||
if (cv_skybox.value && skyboxmo[0])
|
|
||||||
Portal_AddSkyboxPortals();
|
|
||||||
|
|
||||||
// Portal rendering. Hijacks the BSP traversal.
|
|
||||||
ps_sw_portaltime = I_GetPreciseTime();
|
|
||||||
if (portal_base)
|
|
||||||
{
|
{
|
||||||
portal_t *portal;
|
if (renderthreaded)
|
||||||
|
R_StopThreads();
|
||||||
|
|
||||||
for(portal = portal_base; portal; portal = portal_base)
|
numusablerendercontexts = cv_numthreads.value;
|
||||||
|
renderthreaded = (numusablerendercontexts > 1);
|
||||||
|
|
||||||
|
if (renderthreaded)
|
||||||
|
R_StartThreads();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
numusablerendercontexts = 1;
|
||||||
|
renderthreaded = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
R_PrepareContexts();
|
||||||
|
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++)
|
||||||
{
|
{
|
||||||
portalrender = portal->pass; // Recursiveness depth.
|
#ifdef HAVE_THREADS
|
||||||
|
if (renderthreaded)
|
||||||
R_ClearFFloorClips();
|
I_atomic_exchange(&renderdatas[currcontext].framewaiting, 1);
|
||||||
|
else
|
||||||
// Apply the viewpoint stored for the portal.
|
#endif
|
||||||
R_PortalFrame(portal);
|
{
|
||||||
|
R_RenderViewContext(&renderdatas[currcontext].context);
|
||||||
// Hack in the clipsegs to delimit the starting
|
finishedcontexts++;
|
||||||
// clipping for sprites and possibly other similar
|
|
||||||
// future items.
|
|
||||||
R_PortalClearClipSegs(portal->start, portal->end);
|
|
||||||
|
|
||||||
// Hack in the top/bottom clip values for the window
|
|
||||||
// that were previously stored.
|
|
||||||
Portal_ClipApply(portal);
|
|
||||||
|
|
||||||
validcount++;
|
|
||||||
|
|
||||||
masks = realloc(masks, (++nummasks)*sizeof(maskcount_t));
|
|
||||||
|
|
||||||
Mask_Pre(&masks[nummasks - 1]);
|
|
||||||
curdrawsegs = ds_p;
|
|
||||||
|
|
||||||
// Render the BSP from the new viewpoint, and clip
|
|
||||||
// any sprites with the new clipsegs and window.
|
|
||||||
R_RenderBSPNode((INT32)numnodes - 1);
|
|
||||||
Mask_Post(&masks[nummasks - 1]);
|
|
||||||
|
|
||||||
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
|
|
||||||
|
|
||||||
Portal_Remove(portal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime;
|
|
||||||
|
|
||||||
ps_sw_planetime = I_GetPreciseTime();
|
#ifdef HAVE_THREADS
|
||||||
R_DrawPlanes();
|
while (renderthreaded && finishedcontexts != numusablerendercontexts)
|
||||||
ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime;
|
{
|
||||||
|
for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++)
|
||||||
// draw mid texture and sprite
|
finishedcontexts += I_atomic_exchange(&renderdatas[currcontext].framefinished, 0);
|
||||||
// And now 3D floors/sides!
|
}
|
||||||
ps_sw_maskedtime = I_GetPreciseTime();
|
#endif
|
||||||
R_DrawMasked(masks, nummasks);
|
|
||||||
ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime;
|
|
||||||
|
|
||||||
free(masks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -1639,6 +1834,7 @@ void R_RegisterEngineStuff(void)
|
||||||
CV_RegisterVar(&cv_translucenthud);
|
CV_RegisterVar(&cv_translucenthud);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_maxportals);
|
CV_RegisterVar(&cv_maxportals);
|
||||||
|
CV_RegisterVar(&cv_numthreads);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_movebob);
|
CV_RegisterVar(&cv_movebob);
|
||||||
}
|
}
|
||||||
|
|
26
src/r_main.h
26
src/r_main.h
|
@ -29,6 +29,10 @@ extern fixed_t centerxfrac, centeryfrac;
|
||||||
extern fixed_t projection, projectiony;
|
extern fixed_t projection, projectiony;
|
||||||
extern fixed_t fovtan;
|
extern fixed_t fovtan;
|
||||||
|
|
||||||
|
extern INT32 numrendercontexts;
|
||||||
|
extern INT32 numusablerendercontexts;
|
||||||
|
extern boolean renderthreaded;
|
||||||
|
|
||||||
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
||||||
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160), fovtan)
|
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160), fovtan)
|
||||||
|
|
||||||
|
@ -70,7 +74,6 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1);
|
||||||
fixed_t R_PointToDist(fixed_t x, fixed_t y);
|
fixed_t R_PointToDist(fixed_t x, fixed_t y);
|
||||||
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||||
|
|
||||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
|
|
||||||
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
||||||
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||||
|
|
||||||
|
@ -80,20 +83,21 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe
|
||||||
|
|
||||||
extern precise_t ps_prevframetime; // time when previous frame was rendered
|
extern precise_t ps_prevframetime; // time when previous frame was rendered
|
||||||
extern precise_t ps_rendercalltime;
|
extern precise_t ps_rendercalltime;
|
||||||
|
extern precise_t ps_postprocesstime;
|
||||||
extern precise_t ps_uitime;
|
extern precise_t ps_uitime;
|
||||||
extern precise_t ps_swaptime;
|
extern precise_t ps_swaptime;
|
||||||
|
|
||||||
extern precise_t ps_bsptime;
|
extern precise_t ps_bsptime[MAX_RENDER_THREADS];
|
||||||
|
|
||||||
extern precise_t ps_sw_spritecliptime;
|
extern precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS];
|
||||||
extern precise_t ps_sw_portaltime;
|
extern precise_t ps_sw_portaltime[MAX_RENDER_THREADS];
|
||||||
extern precise_t ps_sw_planetime;
|
extern precise_t ps_sw_planetime[MAX_RENDER_THREADS];
|
||||||
extern precise_t ps_sw_maskedtime;
|
extern precise_t ps_sw_maskedtime[MAX_RENDER_THREADS];
|
||||||
|
|
||||||
extern int ps_numbspcalls;
|
extern int ps_numbspcalls[MAX_RENDER_THREADS];
|
||||||
extern int ps_numsprites;
|
extern int ps_numsprites[MAX_RENDER_THREADS];
|
||||||
extern int ps_numdrawnodes;
|
extern int ps_numdrawnodes[MAX_RENDER_THREADS];
|
||||||
extern int ps_numpolyobjects;
|
extern int ps_numpolyobjects[MAX_RENDER_THREADS];
|
||||||
|
|
||||||
//
|
//
|
||||||
// REFRESH - the actual rendering functions.
|
// REFRESH - the actual rendering functions.
|
||||||
|
@ -131,6 +135,8 @@ void R_SkyboxFrame(player_t *player);
|
||||||
boolean R_ViewpointHasChasecam(player_t *player);
|
boolean R_ViewpointHasChasecam(player_t *player);
|
||||||
boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox);
|
boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox);
|
||||||
|
|
||||||
|
void R_StopThreads(void);
|
||||||
|
|
||||||
// Called by D_Display.
|
// Called by D_Display.
|
||||||
void R_RenderPlayerView(player_t *player);
|
void R_RenderPlayerView(player_t *player);
|
||||||
|
|
||||||
|
|
563
src/r_plane.c
563
src/r_plane.c
File diff suppressed because it is too large
Load diff
|
@ -55,52 +55,9 @@ typedef struct visplane_s
|
||||||
pslope_t *slope;
|
pslope_t *slope;
|
||||||
} visplane_t;
|
} visplane_t;
|
||||||
|
|
||||||
extern visplane_t *visplanes[MAXVISPLANES];
|
|
||||||
extern visplane_t *floorplane;
|
|
||||||
extern visplane_t *ceilingplane;
|
|
||||||
|
|
||||||
// Visplane related.
|
|
||||||
extern INT16 *lastopening, *openings;
|
|
||||||
extern size_t maxopenings;
|
|
||||||
|
|
||||||
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
|
|
||||||
extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16];
|
|
||||||
extern fixed_t cachedheight[MAXVIDHEIGHT];
|
|
||||||
extern fixed_t cacheddistance[MAXVIDHEIGHT];
|
|
||||||
extern fixed_t cachedxstep[MAXVIDHEIGHT];
|
|
||||||
extern fixed_t cachedystep[MAXVIDHEIGHT];
|
|
||||||
|
|
||||||
extern fixed_t *yslope;
|
|
||||||
extern lighttable_t **planezlight;
|
|
||||||
|
|
||||||
void R_InitPlanes(void);
|
|
||||||
void R_ClearPlanes(void);
|
|
||||||
void R_ClearFFloorClips (void);
|
|
||||||
|
|
||||||
void R_DrawPlanes(void);
|
|
||||||
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
|
|
||||||
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
|
|
||||||
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
|
|
||||||
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
|
|
||||||
void R_PlaneBounds(visplane_t *plane);
|
|
||||||
|
|
||||||
void R_CheckFlatLength(size_t size);
|
|
||||||
boolean R_CheckPowersOfTwo(void);
|
|
||||||
|
|
||||||
// Draws a single visplane.
|
|
||||||
void R_DrawSinglePlane(visplane_t *pl);
|
|
||||||
|
|
||||||
// Calculates the slope vectors needed for tilted span drawing.
|
|
||||||
void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
|
||||||
void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
|
||||||
void R_CalculateSlopeVectors(void);
|
|
||||||
|
|
||||||
// Sets the slope vector pointers for the current tilted span.
|
|
||||||
void R_SetTiltedSpan(INT32 span);
|
|
||||||
|
|
||||||
typedef struct planemgr_s
|
typedef struct planemgr_s
|
||||||
{
|
{
|
||||||
visplane_t *plane;
|
struct visplane_s *plane;
|
||||||
fixed_t height;
|
fixed_t height;
|
||||||
fixed_t f_pos; // F for Front sector
|
fixed_t f_pos; // F for Front sector
|
||||||
fixed_t b_pos; // B for Back sector
|
fixed_t b_pos; // B for Back sector
|
||||||
|
@ -117,10 +74,36 @@ typedef struct planemgr_s
|
||||||
|
|
||||||
struct ffloor_s *ffloor;
|
struct ffloor_s *ffloor;
|
||||||
polyobj_t *polyobj;
|
polyobj_t *polyobj;
|
||||||
} visffloor_t;
|
} planemgr_t;
|
||||||
|
|
||||||
extern visffloor_t ffloor[MAXFFLOORS];
|
// Visplane related.
|
||||||
extern INT32 numffloors;
|
extern fixed_t yslopetab[MAXVIDHEIGHT*16];
|
||||||
|
extern fixed_t *yslope;
|
||||||
|
|
||||||
void Portal_AddSkyboxPortals (void);
|
struct planecontext_s;
|
||||||
|
struct rendercontext_s;
|
||||||
|
struct viewcontext_s;
|
||||||
|
|
||||||
|
void R_InitPlanes(void);
|
||||||
|
void R_ClearPlanes(struct planecontext_s *context);
|
||||||
|
void R_ClearFFloorClips (struct planecontext_s *context);
|
||||||
|
|
||||||
|
void R_DrawPlanes(struct rendercontext_s *planecontext);
|
||||||
|
visplane_t *R_FindPlane(struct planecontext_s *planecontext, struct viewcontext_s *viewcontext,
|
||||||
|
fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
|
||||||
|
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
|
||||||
|
visplane_t *R_CheckPlane(struct planecontext_s *planecontext, visplane_t *pl, INT32 start, INT32 stop);
|
||||||
|
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
|
||||||
|
void R_PlaneBounds(visplane_t *plane);
|
||||||
|
|
||||||
|
// Draws a single visplane.
|
||||||
|
void R_DrawSinglePlane(struct rendercontext_s *rendercontext, visplane_t *pl);
|
||||||
|
|
||||||
|
// Calculates the slope vectors needed for tilted span drawing.
|
||||||
|
void R_SetSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||||
|
void R_SetScaledSlopePlane(pslope_t *slope, spancontext_t *ds, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||||
|
void R_CalculateSlopeVectors(spancontext_t *ds);
|
||||||
|
|
||||||
|
// Sets the slope vector pointers for the current tilted span.
|
||||||
|
void R_SetTiltedSpan(spancontext_t *ds, INT32 span);
|
||||||
#endif
|
#endif
|
||||||
|
|
101
src/r_portal.c
101
src/r_portal.c
|
@ -14,27 +14,17 @@
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
|
#include "r_context.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "p_spec.h" // Skybox viewpoints
|
#include "p_spec.h" // Skybox viewpoints
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
|
|
||||||
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
|
void Portal_InitList (bspcontext_t *bspcontext)
|
||||||
|
|
||||||
// Linked list for portals.
|
|
||||||
portal_t *portal_base, *portal_cap;
|
|
||||||
|
|
||||||
line_t *portalclipline;
|
|
||||||
sector_t *portalcullsector;
|
|
||||||
INT32 portalclipstart, portalclipend;
|
|
||||||
|
|
||||||
boolean portalline; // is curline a portal seg?
|
|
||||||
|
|
||||||
void Portal_InitList (void)
|
|
||||||
{
|
{
|
||||||
portalrender = 0;
|
bspcontext->portalrender = 0;
|
||||||
portal_base = portal_cap = NULL;
|
bspcontext->portal_base = bspcontext->portal_cap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Store the clipping window for a portal in its given range.
|
/** Store the clipping window for a portal in its given range.
|
||||||
|
@ -43,7 +33,7 @@ void Portal_InitList (void)
|
||||||
* the function is called, so it is useful for converting one-sided
|
* the function is called, so it is useful for converting one-sided
|
||||||
* lines into portals.
|
* lines into portals.
|
||||||
*/
|
*/
|
||||||
void Portal_ClipRange (portal_t* portal)
|
void Portal_ClipRange (planecontext_t *planecontext, portal_t* portal)
|
||||||
{
|
{
|
||||||
INT32 start = portal->start;
|
INT32 start = portal->start;
|
||||||
INT32 end = portal->end;
|
INT32 end = portal->end;
|
||||||
|
@ -54,18 +44,18 @@ void Portal_ClipRange (portal_t* portal)
|
||||||
INT32 i;
|
INT32 i;
|
||||||
for (i = 0; i < end-start; i++)
|
for (i = 0; i < end-start; i++)
|
||||||
{
|
{
|
||||||
*ceil = ceilingclip[start+i];
|
*ceil = planecontext->ceilingclip[start+i];
|
||||||
ceil++;
|
ceil++;
|
||||||
*floor = floorclip[start+i];
|
*floor = planecontext->floorclip[start+i];
|
||||||
floor++;
|
floor++;
|
||||||
*scale = frontscale[start+i];
|
*scale = planecontext->frontscale[start+i];
|
||||||
scale++;
|
scale++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply the clipping window from a portal.
|
/** Apply the clipping window from a portal.
|
||||||
*/
|
*/
|
||||||
void Portal_ClipApply (const portal_t* portal)
|
void Portal_ClipApply (planecontext_t *planecontext, const portal_t* portal)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
INT32 start = portal->start;
|
INT32 start = portal->start;
|
||||||
|
@ -76,28 +66,28 @@ void Portal_ClipApply (const portal_t* portal)
|
||||||
|
|
||||||
for (i = 0; i < end-start; i++)
|
for (i = 0; i < end-start; i++)
|
||||||
{
|
{
|
||||||
ceilingclip[start+i] = *ceil;
|
planecontext->ceilingclip[start+i] = *ceil;
|
||||||
ceil++;
|
ceil++;
|
||||||
floorclip[start+i] = *floor;
|
planecontext->floorclip[start+i] = *floor;
|
||||||
floor++;
|
floor++;
|
||||||
frontscale[start+i] = *scale;
|
planecontext->frontscale[start+i] = *scale;
|
||||||
scale++;
|
scale++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACKS FOLLOW
|
// HACKS FOLLOW
|
||||||
for (i = 0; i < start; i++)
|
for (i = 0; i < start; i++)
|
||||||
{
|
{
|
||||||
floorclip[i] = -1;
|
planecontext->floorclip[i] = -1;
|
||||||
ceilingclip[i] = (INT16)viewheight;
|
planecontext->ceilingclip[i] = (INT16)viewheight;
|
||||||
}
|
}
|
||||||
for (i = end; i < vid.width; i++)
|
for (i = end; i < vid.width; i++)
|
||||||
{
|
{
|
||||||
floorclip[i] = -1;
|
planecontext->floorclip[i] = -1;
|
||||||
ceilingclip[i] = (INT16)viewheight;
|
planecontext->ceilingclip[i] = (INT16)viewheight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
static portal_t* Portal_Add (bspcontext_t *context, const INT16 x1, const INT16 x2)
|
||||||
{
|
{
|
||||||
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
|
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
|
||||||
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
|
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
|
||||||
|
@ -105,15 +95,15 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
||||||
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
|
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
|
||||||
|
|
||||||
// Linked list.
|
// Linked list.
|
||||||
if (!portal_base)
|
if (!context->portal_base)
|
||||||
{
|
{
|
||||||
portal_base = portal;
|
context->portal_base = portal;
|
||||||
portal_cap = portal;
|
context->portal_cap = portal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
portal_cap->next = portal;
|
context->portal_cap->next = portal;
|
||||||
portal_cap = portal;
|
context->portal_cap = portal;
|
||||||
}
|
}
|
||||||
portal->next = NULL;
|
portal->next = NULL;
|
||||||
|
|
||||||
|
@ -125,14 +115,14 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
||||||
portal->end = x2;
|
portal->end = x2;
|
||||||
|
|
||||||
// Increase recursion level.
|
// Increase recursion level.
|
||||||
portal->pass = portalrender+1;
|
portal->pass = context->portalrender+1;
|
||||||
|
|
||||||
return portal;
|
return portal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Portal_Remove (portal_t* portal)
|
void Portal_Remove (bspcontext_t *context, portal_t* portal)
|
||||||
{
|
{
|
||||||
portal_base = portal->next;
|
context->portal_base = portal->next;
|
||||||
Z_Free(portal->ceilingclip);
|
Z_Free(portal->ceilingclip);
|
||||||
Z_Free(portal->floorclip);
|
Z_Free(portal->floorclip);
|
||||||
Z_Free(portal->frontscale);
|
Z_Free(portal->frontscale);
|
||||||
|
@ -149,9 +139,10 @@ void Portal_Remove (portal_t* portal)
|
||||||
* When the portal renders, it will create the illusion of
|
* When the portal renders, it will create the illusion of
|
||||||
* the two lines being seamed together.
|
* the two lines being seamed together.
|
||||||
*/
|
*/
|
||||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
void Portal_Add2Lines (rendercontext_t *context,
|
||||||
|
const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||||
{
|
{
|
||||||
portal_t* portal = Portal_Add(x1, x2);
|
portal_t* portal = Portal_Add(&context->bspcontext, x1, x2);
|
||||||
|
|
||||||
// Offset the portal view by the linedef centers
|
// Offset the portal view by the linedef centers
|
||||||
line_t* start = &lines[line1];
|
line_t* start = &lines[line1];
|
||||||
|
@ -172,20 +163,20 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
|
||||||
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
||||||
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
||||||
|
|
||||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
disttopoint = R_PointToDist2(start_c.x, start_c.y, context->viewcontext.x, context->viewcontext.y);
|
||||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
|
angtopoint = R_PointToAngle2(start_c.x, start_c.y, context->viewcontext.x, context->viewcontext.y);
|
||||||
angtopoint += dangle;
|
angtopoint += dangle;
|
||||||
|
|
||||||
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||||
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||||
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
portal->viewz = context->viewcontext.z + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||||
portal->viewangle = viewangle + dangle;
|
portal->viewangle = context->viewcontext.angle + dangle;
|
||||||
|
|
||||||
portal->clipline = line2;
|
portal->clipline = line2;
|
||||||
|
|
||||||
Portal_ClipRange(portal);
|
Portal_ClipRange(&context->planecontext, portal);
|
||||||
|
|
||||||
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
|
context->bspcontext.portalline = true; // this tells R_StoreWallRange that curline is a portal seg
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Store the clipping window for a portal using a visplane.
|
/** Store the clipping window for a portal using a visplane.
|
||||||
|
@ -256,7 +247,7 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
|
||||||
* Applies the necessary offsets and rotation to give
|
* Applies the necessary offsets and rotation to give
|
||||||
* a depth illusion to the skybox.
|
* a depth illusion to the skybox.
|
||||||
*/
|
*/
|
||||||
void Portal_AddSkybox (const visplane_t* plane)
|
void Portal_AddSkybox (bspcontext_t *bspcontext, viewcontext_t *viewcontext, const visplane_t* plane)
|
||||||
{
|
{
|
||||||
INT16 start, end;
|
INT16 start, end;
|
||||||
mapheader_t *mh;
|
mapheader_t *mh;
|
||||||
|
@ -265,14 +256,14 @@ void Portal_AddSkybox (const visplane_t* plane)
|
||||||
if (TrimVisplaneBounds(plane, &start, &end))
|
if (TrimVisplaneBounds(plane, &start, &end))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
portal = Portal_Add(start, end);
|
portal = Portal_Add(bspcontext, start, end);
|
||||||
|
|
||||||
Portal_ClipVisplane(plane, portal);
|
Portal_ClipVisplane(plane, portal);
|
||||||
|
|
||||||
portal->viewx = skyboxmo[0]->x;
|
portal->viewx = skyboxmo[0]->x;
|
||||||
portal->viewy = skyboxmo[0]->y;
|
portal->viewy = skyboxmo[0]->y;
|
||||||
portal->viewz = skyboxmo[0]->z;
|
portal->viewz = skyboxmo[0]->z;
|
||||||
portal->viewangle = viewangle + skyboxmo[0]->angle;
|
portal->viewangle = viewcontext->angle + skyboxmo[0]->angle;
|
||||||
|
|
||||||
mh = mapheaderinfo[gamemap-1];
|
mh = mapheaderinfo[gamemap-1];
|
||||||
|
|
||||||
|
@ -283,14 +274,14 @@ void Portal_AddSkybox (const visplane_t* plane)
|
||||||
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT;
|
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT;
|
||||||
|
|
||||||
if (mh->skybox_scalex > 0)
|
if (mh->skybox_scalex > 0)
|
||||||
x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex;
|
x = (viewcontext->x - skyboxmo[1]->x) / mh->skybox_scalex;
|
||||||
else if (mh->skybox_scalex < 0)
|
else if (mh->skybox_scalex < 0)
|
||||||
x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex;
|
x = (viewcontext->x - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||||
|
|
||||||
if (mh->skybox_scaley > 0)
|
if (mh->skybox_scaley > 0)
|
||||||
y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley;
|
y = (viewcontext->y - skyboxmo[1]->y) / mh->skybox_scaley;
|
||||||
else if (mh->skybox_scaley < 0)
|
else if (mh->skybox_scaley < 0)
|
||||||
y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley;
|
y = (viewcontext->y - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||||
|
|
||||||
// Apply transform to account for the skybox viewport angle.
|
// Apply transform to account for the skybox viewport angle.
|
||||||
portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||||
|
@ -298,9 +289,9 @@ void Portal_AddSkybox (const visplane_t* plane)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mh->skybox_scalez > 0)
|
if (mh->skybox_scalez > 0)
|
||||||
portal->viewz += viewz / mh->skybox_scalez;
|
portal->viewz += viewcontext->z / mh->skybox_scalez;
|
||||||
else if (mh->skybox_scalez < 0)
|
else if (mh->skybox_scalez < 0)
|
||||||
portal->viewz += viewz * -mh->skybox_scalez;
|
portal->viewz += viewcontext->z * -mh->skybox_scalez;
|
||||||
|
|
||||||
portal->clipline = -1;
|
portal->clipline = -1;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +299,7 @@ void Portal_AddSkybox (const visplane_t* plane)
|
||||||
/** Creates portals for the currently existing sky visplanes.
|
/** Creates portals for the currently existing sky visplanes.
|
||||||
* The visplanes are also removed and cleared from the list.
|
* The visplanes are also removed and cleared from the list.
|
||||||
*/
|
*/
|
||||||
void Portal_AddSkyboxPortals (void)
|
void Portal_AddSkyboxPortals (rendercontext_t *context)
|
||||||
{
|
{
|
||||||
visplane_t *pl;
|
visplane_t *pl;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
@ -316,11 +307,11 @@ void Portal_AddSkyboxPortals (void)
|
||||||
|
|
||||||
for (i = 0; i < MAXVISPLANES; i++, pl++)
|
for (i = 0; i < MAXVISPLANES; i++, pl++)
|
||||||
{
|
{
|
||||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
for (pl = context->planecontext.visplanes[i]; pl; pl = pl->next)
|
||||||
{
|
{
|
||||||
if (pl->picnum == skyflatnum)
|
if (pl->picnum == skyflatnum)
|
||||||
{
|
{
|
||||||
Portal_AddSkybox(pl);
|
Portal_AddSkybox(&context->bspcontext, &context->viewcontext, pl);
|
||||||
|
|
||||||
pl->minx = 0;
|
pl->minx = 0;
|
||||||
pl->maxx = -1;
|
pl->maxx = -1;
|
||||||
|
|
|
@ -41,21 +41,19 @@ typedef struct portal_s
|
||||||
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
|
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
|
||||||
} portal_t;
|
} portal_t;
|
||||||
|
|
||||||
extern portal_t* portal_base;
|
struct bspcontext_s;
|
||||||
extern portal_t* portal_cap;
|
struct planecontext_s;
|
||||||
extern UINT8 portalrender;
|
struct rendercontext_s;
|
||||||
|
struct viewcontext_s;
|
||||||
|
|
||||||
extern line_t *portalclipline;
|
void Portal_InitList (struct bspcontext_s *bspcontext);
|
||||||
extern sector_t *portalcullsector;
|
void Portal_Remove (struct bspcontext_s *context, portal_t* portal);
|
||||||
extern INT32 portalclipstart, portalclipend;
|
void Portal_Add2Lines (struct rendercontext_s *context,
|
||||||
|
const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
|
||||||
|
void Portal_AddSkybox (struct bspcontext_s *bspcontext, struct viewcontext_s *viewcontext, const visplane_t* plane);
|
||||||
|
|
||||||
void Portal_InitList (void);
|
void Portal_ClipRange (struct planecontext_s *planecontext, portal_t* portal);
|
||||||
void Portal_Remove (portal_t* portal);
|
void Portal_ClipApply (struct planecontext_s *planecontext, const portal_t* portal);
|
||||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
|
|
||||||
void Portal_AddSkybox (const visplane_t* plane);
|
|
||||||
|
|
||||||
void Portal_ClipRange (portal_t* portal);
|
void Portal_AddSkyboxPortals (struct rendercontext_s *context);
|
||||||
void Portal_ClipApply (const portal_t* portal);
|
|
||||||
|
|
||||||
void Portal_AddSkyboxPortals (void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1703
src/r_segs.c
1703
src/r_segs.c
File diff suppressed because it is too large
Load diff
|
@ -18,9 +18,12 @@
|
||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct rendercontext_s;
|
||||||
|
struct wallcontext_s;
|
||||||
|
|
||||||
transnum_t R_GetLinedefTransTable(fixed_t alpha);
|
transnum_t R_GetLinedefTransTable(fixed_t alpha);
|
||||||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
|
void R_RenderMaskedSegRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2);
|
||||||
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
|
void R_RenderThickSideRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
|
||||||
void R_StoreWallRange(INT32 start, INT32 stop);
|
void R_StoreWallRange(struct rendercontext_s *context, struct wallcontext_s *wallcontext, INT32 start, INT32 stop);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,9 +54,6 @@ INT32 globallevelskynum;
|
||||||
|
|
||||||
Called at loadlevel after skytexture is set, or when sky texture changes.
|
Called at loadlevel after skytexture is set, or when sky texture changes.
|
||||||
|
|
||||||
\warning wallcolfunc should be set at R_ExecuteSetViewSize()
|
|
||||||
I don't bother because we don't use low detail anymore
|
|
||||||
|
|
||||||
\return void
|
\return void
|
||||||
*/
|
*/
|
||||||
void R_SetupSkyDraw(void)
|
void R_SetupSkyDraw(void)
|
||||||
|
|
158
src/r_splats.c
158
src/r_splats.c
|
@ -13,37 +13,22 @@
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "r_splats.h"
|
#include "r_splats.h"
|
||||||
|
#include "r_context.h"
|
||||||
#include "r_bsp.h"
|
#include "r_bsp.h"
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_slopes.h"
|
#include "p_slopes.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
struct rastery_s *prastertab; // for ASM code
|
static void prepare_rastertab(planecontext_t *planecontext);
|
||||||
|
|
||||||
static struct rastery_s rastertab[MAXVIDHEIGHT];
|
|
||||||
static void prepare_rastertab(void);
|
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// FLOOR SPLATS
|
// FLOOR SPLATS
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis);
|
static void R_RasterizeFloorSplat(rendercontext_t *context, floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis);
|
||||||
|
|
||||||
#ifdef USEASM
|
static void rasterize_segment_tex(planecontext_t *planecontext, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir)
|
||||||
void ASMCALL rasterize_segment_tex_asm(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir)
|
|
||||||
{
|
|
||||||
#ifdef USEASM
|
|
||||||
if (R_ASM)
|
|
||||||
{
|
|
||||||
rasterize_segment_tex_asm(x1, y1, x2, y2, tv1, tv2, tc, dir);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
fixed_t xs, xe, count;
|
fixed_t xs, xe, count;
|
||||||
fixed_t dx0, dx1;
|
fixed_t dx0, dx1;
|
||||||
|
@ -66,9 +51,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rastertab[y1].maxx = xs;
|
planecontext->rastertab[y1].maxx = xs;
|
||||||
rastertab[y1].tx2 = xe;
|
planecontext->rastertab[y1].tx2 = xe;
|
||||||
rastertab[y1].ty2 = tc;
|
planecontext->rastertab[y1].ty2 = tc;
|
||||||
|
|
||||||
xs += dx0;
|
xs += dx0;
|
||||||
xe += dx1;
|
xe += dx1;
|
||||||
|
@ -81,9 +66,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rastertab[y1].maxx = xs;
|
planecontext->rastertab[y1].maxx = xs;
|
||||||
rastertab[y1].tx2 = tc;
|
planecontext->rastertab[y1].tx2 = tc;
|
||||||
rastertab[y1].ty2 = xe;
|
planecontext->rastertab[y1].ty2 = xe;
|
||||||
|
|
||||||
xs += dx0;
|
xs += dx0;
|
||||||
xe += dx1;
|
xe += dx1;
|
||||||
|
@ -108,9 +93,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rastertab[y2].minx = xs;
|
planecontext->rastertab[y2].minx = xs;
|
||||||
rastertab[y2].tx1 = xe;
|
planecontext->rastertab[y2].tx1 = xe;
|
||||||
rastertab[y2].ty1 = tc;
|
planecontext->rastertab[y2].ty1 = tc;
|
||||||
|
|
||||||
xs += dx0;
|
xs += dx0;
|
||||||
xe += dx1;
|
xe += dx1;
|
||||||
|
@ -123,9 +108,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rastertab[y2].minx = xs;
|
planecontext->rastertab[y2].minx = xs;
|
||||||
rastertab[y2].tx1 = tc;
|
planecontext->rastertab[y2].tx1 = tc;
|
||||||
rastertab[y2].ty1 = xe;
|
planecontext->rastertab[y2].ty1 = xe;
|
||||||
|
|
||||||
xs += dx0;
|
xs += dx0;
|
||||||
xe += dx1;
|
xe += dx1;
|
||||||
|
@ -136,9 +121,8 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void R_DrawFloorSplat(vissprite_t *spr)
|
void R_DrawFloorSplat(rendercontext_t *context, vissprite_t *spr)
|
||||||
{
|
{
|
||||||
floorsplat_t splat;
|
floorsplat_t splat;
|
||||||
mobj_t *mobj = spr->mobj;
|
mobj_t *mobj = spr->mobj;
|
||||||
|
@ -308,7 +292,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
|
||||||
v2d[i].y = (centeryfrac + FixedMul(rot_z, yscale))>>FRACBITS;
|
v2d[i].y = (centeryfrac + FixedMul(rot_z, yscale))>>FRACBITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_RasterizeFloorSplat(&splat, v2d, spr);
|
R_RasterizeFloorSplat(context, &splat, v2d, spr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -316,7 +300,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
|
||||||
// fill the polygon with linear interpolation, call span drawer for each
|
// fill the polygon with linear interpolation, call span drawer for each
|
||||||
// scan line
|
// scan line
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis)
|
static void R_RasterizeFloorSplat(rendercontext_t *context, floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis)
|
||||||
{
|
{
|
||||||
// rasterizing
|
// rasterizing
|
||||||
INT32 miny = viewheight + 1, maxy = 0;
|
INT32 miny = viewheight + 1, maxy = 0;
|
||||||
|
@ -325,9 +309,13 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
fixed_t planeheight = 0;
|
fixed_t planeheight = 0;
|
||||||
fixed_t step;
|
fixed_t step;
|
||||||
|
|
||||||
|
planecontext_t *planecontext = &context->planecontext;
|
||||||
|
|
||||||
|
colcontext_t *dc = &context->colcontext;
|
||||||
|
spancontext_t *ds = &context->spancontext;
|
||||||
int spanfunctype = SPANDRAWFUNC_SPRITE;
|
int spanfunctype = SPANDRAWFUNC_SPRITE;
|
||||||
|
|
||||||
prepare_rastertab();
|
prepare_rastertab(planecontext);
|
||||||
|
|
||||||
#define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \
|
#define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \
|
||||||
x1 = verts[vnum1].x; \
|
x1 = verts[vnum1].x; \
|
||||||
|
@ -372,7 +360,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
} \
|
} \
|
||||||
y2 = vid.height - 1; \
|
y2 = vid.height - 1; \
|
||||||
} \
|
} \
|
||||||
rasterize_segment_tex(x1, ry1, x2, y2, tv1, tv2, tc, dir); \
|
rasterize_segment_tex(planecontext, x1, ry1, x2, y2, tv1, tv2, tc, dir); \
|
||||||
if (ry1 < miny) \
|
if (ry1 < miny) \
|
||||||
miny = ry1; \
|
miny = ry1; \
|
||||||
if (ry1 > maxy) \
|
if (ry1 > maxy) \
|
||||||
|
@ -387,27 +375,27 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
// do segment d -> left side of texture
|
// do segment d -> left side of texture
|
||||||
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
|
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
|
||||||
|
|
||||||
ds_source = (UINT8 *)pSplat->pic;
|
ds->source = (UINT8 *)pSplat->pic;
|
||||||
ds_flatwidth = pSplat->width;
|
ds->flatwidth = pSplat->width;
|
||||||
ds_flatheight = pSplat->height;
|
ds->flatheight = pSplat->height;
|
||||||
|
|
||||||
if (R_CheckPowersOfTwo())
|
if (R_CheckPowersOfTwo(ds->flatwidth, ds->flatheight))
|
||||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
R_CheckFlatLength(ds, ds->flatwidth * ds->flatheight);
|
||||||
|
|
||||||
if (pSplat->slope)
|
if (pSplat->slope)
|
||||||
{
|
{
|
||||||
R_SetTiltedSpan(0);
|
R_SetTiltedSpan(ds, 0);
|
||||||
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
|
R_SetScaledSlopePlane(pSplat->slope, ds, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
|
||||||
R_CalculateSlopeVectors();
|
R_CalculateSlopeVectors(ds);
|
||||||
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
|
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
planeheight = abs(pSplat->z - vis->viewpoint.z);
|
planecontext->planeheight = abs(pSplat->z - vis->viewpoint.z);
|
||||||
|
|
||||||
if (pSplat->angle)
|
if (pSplat->angle)
|
||||||
{
|
{
|
||||||
memset(cachedheight, 0, sizeof(cachedheight));
|
memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight));
|
||||||
|
|
||||||
// Add the view offset, rotated by the plane angle.
|
// Add the view offset, rotated by the plane angle.
|
||||||
fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
|
fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
|
||||||
|
@ -423,22 +411,22 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_colormap = vis->colormap;
|
ds->colormap = vis->colormap;
|
||||||
ds_translation = R_GetSpriteTranslation(vis);
|
ds->translation = R_GetSpriteTranslation(vis);
|
||||||
if (ds_translation == NULL)
|
if (ds->translation == NULL)
|
||||||
ds_translation = colormaps;
|
ds->translation = colormaps;
|
||||||
|
|
||||||
if (vis->extra_colormap)
|
if (vis->extra_colormap)
|
||||||
{
|
{
|
||||||
if (!ds_colormap)
|
if (!ds->colormap)
|
||||||
ds_colormap = vis->extra_colormap->colormap;
|
ds->colormap = vis->extra_colormap->colormap;
|
||||||
else
|
else
|
||||||
ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps];
|
ds->colormap = &vis->extra_colormap->colormap[ds->colormap - colormaps];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vis->transmap)
|
if (vis->transmap)
|
||||||
{
|
{
|
||||||
ds_transmap = vis->transmap;
|
ds->transmap = vis->transmap;
|
||||||
|
|
||||||
if (pSplat->slope)
|
if (pSplat->slope)
|
||||||
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
|
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
|
||||||
|
@ -446,12 +434,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
|
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ds_transmap = NULL;
|
ds->transmap = NULL;
|
||||||
|
|
||||||
if (ds_powersoftwo)
|
if (ds->powersoftwo)
|
||||||
spanfunc = spanfuncs[spanfunctype];
|
ds->func = spanfuncs[spanfunctype];
|
||||||
else
|
else
|
||||||
spanfunc = spanfuncs_npo2[spanfunctype];
|
ds->func = spanfuncs_npo2[spanfunctype];
|
||||||
|
|
||||||
if (maxy >= vid.height)
|
if (maxy >= vid.height)
|
||||||
maxy = vid.height-1;
|
maxy = vid.height-1;
|
||||||
|
@ -460,8 +448,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
{
|
{
|
||||||
boolean cliptab[MAXVIDWIDTH+1];
|
boolean cliptab[MAXVIDWIDTH+1];
|
||||||
|
|
||||||
x1 = rastertab[y].minx>>FRACBITS;
|
x1 = planecontext->rastertab[y].minx>>FRACBITS;
|
||||||
x2 = rastertab[y].maxx>>FRACBITS;
|
x2 = planecontext->rastertab[y].maxx>>FRACBITS;
|
||||||
|
|
||||||
if (x1 > x2)
|
if (x1 > x2)
|
||||||
{
|
{
|
||||||
|
@ -482,7 +470,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = x1; i <= x2; i++)
|
for (i = x1; i <= x2; i++)
|
||||||
cliptab[i] = (y >= mfloorclip[i]);
|
cliptab[i] = (y >= dc->mfloorclip[i]);
|
||||||
|
|
||||||
// clip left
|
// clip left
|
||||||
while (cliptab[x1])
|
while (cliptab[x1])
|
||||||
|
@ -516,10 +504,10 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
angle_t planecos = FINECOSINE(angle);
|
angle_t planecos = FINECOSINE(angle);
|
||||||
angle_t planesin = FINESINE(angle);
|
angle_t planesin = FINESINE(angle);
|
||||||
|
|
||||||
if (planeheight != cachedheight[y])
|
if (planecontext->planeheight != planecontext->cachedheight[y])
|
||||||
{
|
{
|
||||||
cachedheight[y] = planeheight;
|
planecontext->cachedheight[y] = planeheight;
|
||||||
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
distance = planecontext->cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
||||||
span = abs(centery - y);
|
span = abs(centery - y);
|
||||||
|
|
||||||
if (span) // Don't divide by zero
|
if (span) // Don't divide by zero
|
||||||
|
@ -530,43 +518,43 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
||||||
else
|
else
|
||||||
xstep = ystep = FRACUNIT;
|
xstep = ystep = FRACUNIT;
|
||||||
|
|
||||||
cachedxstep[y] = xstep;
|
planecontext->cachedxstep[y] = xstep;
|
||||||
cachedystep[y] = ystep;
|
planecontext->cachedystep[y] = ystep;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
distance = cacheddistance[y];
|
distance = planecontext->cacheddistance[y];
|
||||||
xstep = cachedxstep[y];
|
xstep = planecontext->cachedxstep[y];
|
||||||
ystep = cachedystep[y];
|
ystep = planecontext->cachedystep[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_xstep = FixedDiv(xstep, pSplat->xscale);
|
ds->xstep = FixedDiv(xstep, pSplat->xscale);
|
||||||
ds_ystep = FixedDiv(ystep, pSplat->yscale);
|
ds->ystep = FixedDiv(ystep, pSplat->yscale);
|
||||||
|
|
||||||
ds_xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
|
ds->xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
|
||||||
ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
|
ds->yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_y = y;
|
ds->y = y;
|
||||||
ds_x1 = x1;
|
ds->x1 = x1;
|
||||||
ds_x2 = x2;
|
ds->x2 = x2;
|
||||||
spanfunc();
|
ds->func(ds);
|
||||||
|
|
||||||
rastertab[y].minx = INT32_MAX;
|
planecontext->rastertab[y].minx = INT32_MAX;
|
||||||
rastertab[y].maxx = INT32_MIN;
|
planecontext->rastertab[y].maxx = INT32_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSplat->angle && !pSplat->slope)
|
if (pSplat->angle && !pSplat->slope)
|
||||||
memset(cachedheight, 0, sizeof(cachedheight));
|
memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_rastertab(void)
|
static void prepare_rastertab(planecontext_t *planecontext)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
prastertab = rastertab;
|
planecontext->prastertab = planecontext->rastertab;
|
||||||
for (i = 0; i < vid.height; i++)
|
for (i = 0; i < vid.height; i++)
|
||||||
{
|
{
|
||||||
rastertab[i].minx = INT32_MAX;
|
planecontext->rastertab[i].minx = INT32_MAX;
|
||||||
rastertab[i].maxx = INT32_MIN;
|
planecontext->rastertab[i].maxx = INT32_MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ struct rastery_s
|
||||||
fixed_t tx1, ty1; // start points in texture at this line
|
fixed_t tx1, ty1; // start points in texture at this line
|
||||||
fixed_t tx2, ty2; // end points in texture at this line
|
fixed_t tx2, ty2; // end points in texture at this line
|
||||||
};
|
};
|
||||||
extern struct rastery_s *prastertab; // for ASM code
|
|
||||||
|
|
||||||
typedef struct floorsplat_s
|
typedef struct floorsplat_s
|
||||||
{
|
{
|
||||||
|
@ -41,6 +40,8 @@ typedef struct floorsplat_s
|
||||||
mobj_t *mobj; // Mobj it is tied to
|
mobj_t *mobj; // Mobj it is tied to
|
||||||
} floorsplat_t;
|
} floorsplat_t;
|
||||||
|
|
||||||
void R_DrawFloorSplat(vissprite_t *spr);
|
struct rendercontext_s;
|
||||||
|
|
||||||
|
void R_DrawFloorSplat(struct rendercontext_s *context, vissprite_t *spr);
|
||||||
|
|
||||||
#endif /*__R_SPLATS_H__*/
|
#endif /*__R_SPLATS_H__*/
|
||||||
|
|
|
@ -90,6 +90,8 @@ extern sector_t *viewsector;
|
||||||
extern player_t *viewplayer;
|
extern player_t *viewplayer;
|
||||||
extern mobj_t *r_viewmobj;
|
extern mobj_t *r_viewmobj;
|
||||||
|
|
||||||
|
extern consvar_t cv_numthreads;
|
||||||
|
|
||||||
extern consvar_t cv_allowmlook;
|
extern consvar_t cv_allowmlook;
|
||||||
extern consvar_t cv_maxportals;
|
extern consvar_t cv_maxportals;
|
||||||
|
|
||||||
|
@ -99,10 +101,4 @@ extern angle_t doubleclipangle;
|
||||||
extern INT32 viewangletox[FINEANGLES/2];
|
extern INT32 viewangletox[FINEANGLES/2];
|
||||||
extern angle_t xtoviewangle[MAXVIDWIDTH+1];
|
extern angle_t xtoviewangle[MAXVIDWIDTH+1];
|
||||||
|
|
||||||
extern fixed_t rw_distance;
|
|
||||||
extern angle_t rw_normalangle;
|
|
||||||
|
|
||||||
// angle to line origin
|
|
||||||
extern angle_t rw_angle1;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
130
src/r_textures.c
130
src/r_textures.c
|
@ -34,6 +34,15 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static I_mutex r_texture_mutex;
|
||||||
|
# define Lock_state() I_lock_mutex(&r_texture_mutex)
|
||||||
|
# define Unlock_state() I_unlock_mutex(r_texture_mutex)
|
||||||
|
#else
|
||||||
|
# define Lock_state()
|
||||||
|
# define Unlock_state()
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEXTURE_T CACHING
|
// TEXTURE_T CACHING
|
||||||
// When a texture is first needed, it counts the number of composite columns
|
// When a texture is first needed, it counts the number of composite columns
|
||||||
|
@ -508,8 +517,10 @@ INT32 R_GetTextureNum(INT32 texnum)
|
||||||
//
|
//
|
||||||
void R_CheckTextureCache(INT32 tex)
|
void R_CheckTextureCache(INT32 tex)
|
||||||
{
|
{
|
||||||
|
Lock_state();
|
||||||
if (!texturecache[tex])
|
if (!texturecache[tex])
|
||||||
R_GenerateTexture(tex);
|
R_GenerateTexture(tex);
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -525,9 +536,11 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col)
|
||||||
else
|
else
|
||||||
col &= (width - 1);
|
col &= (width - 1);
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
data = texturecache[tex];
|
data = texturecache[tex];
|
||||||
if (!data)
|
if (!data)
|
||||||
data = R_GenerateTexture(tex);
|
data = R_GenerateTexture(tex);
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return data + LONG(texturecolumnofs[tex][col]);
|
return data + LONG(texturecolumnofs[tex][col]);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +555,7 @@ void *R_GetFlat(lumpnum_t flatlumpnum)
|
||||||
//
|
//
|
||||||
// If needed, convert a texture or patch to a flat.
|
// If needed, convert a texture or patch to a flat.
|
||||||
//
|
//
|
||||||
void *R_GetLevelFlat(levelflat_t *levelflat)
|
void *R_GetLevelFlat(levelflat_t *levelflat, UINT16 *flatwidth, UINT16 *flatheight)
|
||||||
{
|
{
|
||||||
boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
|
boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
|
||||||
texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL);
|
texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL);
|
||||||
|
@ -555,8 +568,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
if (texture->flat)
|
if (texture->flat)
|
||||||
{
|
{
|
||||||
flatdata = texture->flat;
|
flatdata = texture->flat;
|
||||||
ds_flatwidth = texture->width;
|
*flatwidth = texture->width;
|
||||||
ds_flatheight = texture->height;
|
*flatheight = texture->height;
|
||||||
texturechanged = false;
|
texturechanged = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -566,12 +579,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
// If the texture changed, or the flat wasn't generated, convert.
|
// If the texture changed, or the flat wasn't generated, convert.
|
||||||
if (levelflat->picture == NULL || texturechanged)
|
if (levelflat->picture == NULL || texturechanged)
|
||||||
{
|
{
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
// Level texture
|
// Level texture
|
||||||
if (isleveltexture)
|
if (isleveltexture)
|
||||||
{
|
{
|
||||||
levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num);
|
levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num);
|
||||||
ds_flatwidth = levelflat->width = texture->width;
|
*flatwidth = levelflat->width = texture->width;
|
||||||
ds_flatheight = levelflat->height = texture->height;
|
*flatheight = levelflat->height = texture->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -584,8 +599,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
levelflat->width = (UINT16)pngwidth;
|
levelflat->width = (UINT16)pngwidth;
|
||||||
levelflat->height = (UINT16)pngheight;
|
levelflat->height = (UINT16)pngheight;
|
||||||
|
|
||||||
ds_flatwidth = levelflat->width;
|
*flatwidth = levelflat->width;
|
||||||
ds_flatheight = levelflat->height;
|
*flatheight = levelflat->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -595,8 +610,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
size_t size;
|
size_t size;
|
||||||
softwarepatch_t *patch = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
softwarepatch_t *patch = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
||||||
|
|
||||||
levelflat->width = ds_flatwidth = SHORT(patch->width);
|
levelflat->width = *flatwidth = SHORT(patch->width);
|
||||||
levelflat->height = ds_flatheight = SHORT(patch->height);
|
levelflat->height = *flatheight = SHORT(patch->height);
|
||||||
|
|
||||||
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
|
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
|
||||||
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
|
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
|
||||||
|
@ -604,11 +619,13 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
Z_Free(converted);
|
Z_Free(converted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ds_flatwidth = levelflat->width;
|
*flatwidth = levelflat->width;
|
||||||
ds_flatheight = levelflat->height;
|
*flatheight = levelflat->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
levelflat->u.texture.lastnum = levelflat->u.texture.num;
|
levelflat->u.texture.lastnum = levelflat->u.texture.num;
|
||||||
|
@ -621,23 +638,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||||
//
|
//
|
||||||
// R_CheckPowersOfTwo
|
// R_CheckPowersOfTwo
|
||||||
//
|
//
|
||||||
// Sets ds_powersoftwo true if the flat's dimensions are powers of two, and returns that.
|
// Checks if the flat's dimensions are powers of two.
|
||||||
//
|
//
|
||||||
boolean R_CheckPowersOfTwo(void)
|
boolean R_CheckPowersOfTwo(UINT16 flatwidth, UINT16 flatheight)
|
||||||
{
|
{
|
||||||
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
|
boolean wpow2 = (!(flatwidth & (flatwidth - 1)));
|
||||||
boolean hpow2 = (!(ds_flatheight & (ds_flatheight - 1)));
|
boolean hpow2 = (!(flatheight & (flatheight - 1)));
|
||||||
|
|
||||||
// Initially, the flat isn't powers-of-two-sized.
|
return ((flatwidth == flatheight) && (wpow2 && hpow2));
|
||||||
ds_powersoftwo = false;
|
|
||||||
|
|
||||||
// But if the width and height are powers of two,
|
|
||||||
// and are EQUAL, then it's okay :]
|
|
||||||
if ((ds_flatwidth == ds_flatheight) && (wpow2 && hpow2))
|
|
||||||
ds_powersoftwo = true;
|
|
||||||
|
|
||||||
// Just return ds_powersoftwo.
|
|
||||||
return ds_powersoftwo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -645,58 +653,58 @@ boolean R_CheckPowersOfTwo(void)
|
||||||
//
|
//
|
||||||
// Determine the flat's dimensions from its lump length.
|
// Determine the flat's dimensions from its lump length.
|
||||||
//
|
//
|
||||||
void R_CheckFlatLength(size_t size)
|
void R_CheckFlatLength(spancontext_t *ds, size_t size)
|
||||||
{
|
{
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case 4194304: // 2048x2048 lump
|
case 4194304: // 2048x2048 lump
|
||||||
nflatmask = 0x3FF800;
|
ds->nflatmask = 0x3FF800;
|
||||||
nflatxshift = 21;
|
ds->nflatxshift = 21;
|
||||||
nflatyshift = 10;
|
ds->nflatyshift = 10;
|
||||||
nflatshiftup = 5;
|
ds->nflatshiftup = 5;
|
||||||
ds_flatwidth = ds_flatheight = 2048;
|
ds->flatwidth = ds->flatheight = 2048;
|
||||||
break;
|
break;
|
||||||
case 1048576: // 1024x1024 lump
|
case 1048576: // 1024x1024 lump
|
||||||
nflatmask = 0xFFC00;
|
ds->nflatmask = 0xFFC00;
|
||||||
nflatxshift = 22;
|
ds->nflatxshift = 22;
|
||||||
nflatyshift = 12;
|
ds->nflatyshift = 12;
|
||||||
nflatshiftup = 6;
|
ds->nflatshiftup = 6;
|
||||||
ds_flatwidth = ds_flatheight = 1024;
|
ds->flatwidth = ds->flatheight = 1024;
|
||||||
break;
|
break;
|
||||||
case 262144:// 512x512 lump
|
case 262144:// 512x512 lump
|
||||||
nflatmask = 0x3FE00;
|
ds->nflatmask = 0x3FE00;
|
||||||
nflatxshift = 23;
|
ds->nflatxshift = 23;
|
||||||
nflatyshift = 14;
|
ds->nflatyshift = 14;
|
||||||
nflatshiftup = 7;
|
ds->nflatshiftup = 7;
|
||||||
ds_flatwidth = ds_flatheight = 512;
|
ds->flatwidth = ds->flatheight = 512;
|
||||||
break;
|
break;
|
||||||
case 65536: // 256x256 lump
|
case 65536: // 256x256 lump
|
||||||
nflatmask = 0xFF00;
|
ds->nflatmask = 0xFF00;
|
||||||
nflatxshift = 24;
|
ds->nflatxshift = 24;
|
||||||
nflatyshift = 16;
|
ds->nflatyshift = 16;
|
||||||
nflatshiftup = 8;
|
ds->nflatshiftup = 8;
|
||||||
ds_flatwidth = ds_flatheight = 256;
|
ds->flatwidth = ds->flatheight = 256;
|
||||||
break;
|
break;
|
||||||
case 16384: // 128x128 lump
|
case 16384: // 128x128 lump
|
||||||
nflatmask = 0x3F80;
|
ds->nflatmask = 0x3F80;
|
||||||
nflatxshift = 25;
|
ds->nflatxshift = 25;
|
||||||
nflatyshift = 18;
|
ds->nflatyshift = 18;
|
||||||
nflatshiftup = 9;
|
ds->nflatshiftup = 9;
|
||||||
ds_flatwidth = ds_flatheight = 128;
|
ds->flatwidth = ds->flatheight = 128;
|
||||||
break;
|
break;
|
||||||
case 1024: // 32x32 lump
|
case 1024: // 32x32 lump
|
||||||
nflatmask = 0x3E0;
|
ds->nflatmask = 0x3E0;
|
||||||
nflatxshift = 27;
|
ds->nflatxshift = 27;
|
||||||
nflatyshift = 22;
|
ds->nflatyshift = 22;
|
||||||
nflatshiftup = 11;
|
ds->nflatshiftup = 11;
|
||||||
ds_flatwidth = ds_flatheight = 32;
|
ds->flatwidth = ds->flatheight = 32;
|
||||||
break;
|
break;
|
||||||
default: // 64x64 lump
|
default: // 64x64 lump
|
||||||
nflatmask = 0xFC0;
|
ds->nflatmask = 0xFC0;
|
||||||
nflatxshift = 26;
|
ds->nflatxshift = 26;
|
||||||
nflatyshift = 20;
|
ds->nflatyshift = 20;
|
||||||
nflatshiftup = 10;
|
ds->nflatshiftup = 10;
|
||||||
ds_flatwidth = ds_flatheight = 64;
|
ds->flatwidth = ds->flatheight = 64;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "p_setup.h" // levelflats
|
#include "p_setup.h" // levelflats
|
||||||
#include "r_data.h"
|
#include "r_data.h"
|
||||||
|
#include "r_draw.h"
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma interface
|
#pragma interface
|
||||||
|
@ -86,12 +87,12 @@ void R_CheckTextureCache(INT32 tex);
|
||||||
void R_ClearTextureNumCache(boolean btell);
|
void R_ClearTextureNumCache(boolean btell);
|
||||||
|
|
||||||
// Retrieve texture data.
|
// Retrieve texture data.
|
||||||
void *R_GetLevelFlat(levelflat_t *levelflat);
|
void *R_GetLevelFlat(levelflat_t *levelflat, UINT16 *flatwidth, UINT16 *flatheight);
|
||||||
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
|
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
|
||||||
void *R_GetFlat(lumpnum_t flatnum);
|
void *R_GetFlat(lumpnum_t flatnum);
|
||||||
|
|
||||||
boolean R_CheckPowersOfTwo(void);
|
boolean R_CheckPowersOfTwo(UINT16 flatwidth, UINT16 flatheight);
|
||||||
void R_CheckFlatLength(size_t size);
|
void R_CheckFlatLength(spancontext_t *ds, size_t size);
|
||||||
|
|
||||||
// Returns the texture number for the texture name.
|
// Returns the texture number for the texture name.
|
||||||
INT32 R_TextureNumForName(const char *name);
|
INT32 R_TextureNumForName(const char *name);
|
||||||
|
|
769
src/r_things.c
769
src/r_things.c
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
||||||
|
|
||||||
|
void R_InitSprites(void);
|
||||||
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
|
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
|
||||||
|
|
||||||
//faB: find sprites in wadfile, replace existing, add new ones
|
//faB: find sprites in wadfile, replace existing, add new ones
|
||||||
|
@ -37,23 +38,16 @@ void R_AddSpriteDefs(UINT16 wadnum);
|
||||||
// MASKED COLUMN DRAWING
|
// MASKED COLUMN DRAWING
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
||||||
// vars for R_DrawMaskedColumn
|
void R_DrawMaskedColumn(colcontext_t *dc, column_t *column);
|
||||||
extern INT16 *mfloorclip;
|
void R_DrawFlippedMaskedColumn(colcontext_t *dc, column_t *column);
|
||||||
extern INT16 *mceilingclip;
|
|
||||||
extern fixed_t spryscale;
|
|
||||||
extern fixed_t sprtopscreen;
|
|
||||||
extern fixed_t sprbotscreen;
|
|
||||||
extern fixed_t windowtop;
|
|
||||||
extern fixed_t windowbottom;
|
|
||||||
extern INT32 lengthcol;
|
|
||||||
|
|
||||||
void R_DrawMaskedColumn(column_t *column);
|
|
||||||
void R_DrawFlippedMaskedColumn(column_t *column);
|
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
// SPRITE RENDERING
|
// SPRITE RENDERING
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
|
struct rendercontext_s;
|
||||||
|
struct spritecontext_s;
|
||||||
|
|
||||||
// Constant arrays used for psprite clipping
|
// Constant arrays used for psprite clipping
|
||||||
// and initializing clipping.
|
// and initializing clipping.
|
||||||
extern INT16 negonearray[MAXVIDWIDTH];
|
extern INT16 negonearray[MAXVIDWIDTH];
|
||||||
|
@ -62,17 +56,18 @@ extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||||
|
|
||||||
//SoM: 6/5/2000: Light sprites correctly!
|
//SoM: 6/5/2000: Light sprites correctly!
|
||||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
void R_AddSprites(struct rendercontext_s *context, sector_t *sec, INT32 lightlevel);
|
||||||
void R_InitSprites(void);
|
void R_ClearSprites(struct spritecontext_s *spritecontext);
|
||||||
void R_ClearSprites(void);
|
|
||||||
|
|
||||||
boolean R_ThingVisible (mobj_t *thing);
|
boolean R_ThingVisible (mobj_t *thing, mobj_t *viewmobj);
|
||||||
|
|
||||||
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
boolean R_ThingVisibleWithinDist (fixed_t viewpos_x, fixed_t viewpos_y,
|
||||||
|
mobj_t *thing, mobj_t *viewmobj,
|
||||||
fixed_t draw_dist,
|
fixed_t draw_dist,
|
||||||
fixed_t nights_draw_dist);
|
fixed_t nights_draw_dist);
|
||||||
|
|
||||||
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
boolean R_PrecipThingVisible (fixed_t viewpos_x, fixed_t viewpos_y,
|
||||||
|
precipmobj_t *precipthing,
|
||||||
fixed_t precip_draw_dist);
|
fixed_t precip_draw_dist);
|
||||||
|
|
||||||
boolean R_ThingHorizontallyFlipped (mobj_t *thing);
|
boolean R_ThingHorizontallyFlipped (mobj_t *thing);
|
||||||
|
@ -99,7 +94,7 @@ typedef struct
|
||||||
sector_t* viewsector;
|
sector_t* viewsector;
|
||||||
} maskcount_t;
|
} maskcount_t;
|
||||||
|
|
||||||
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
|
void R_DrawMasked(struct rendercontext_s *context, maskcount_t *masks, UINT8 nummasks);
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// VISSPRITES
|
// VISSPRITES
|
||||||
|
@ -210,10 +205,7 @@ typedef struct vissprite_s
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
} vissprite_t;
|
} vissprite_t;
|
||||||
|
|
||||||
extern UINT32 visspritecount;
|
void R_ClipSprites(struct rendercontext_s *context, drawseg_t* dsstart, portal_t* portal);
|
||||||
|
|
||||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
|
||||||
void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal);
|
|
||||||
|
|
||||||
boolean R_SpriteIsFlashing(vissprite_t *vis);
|
boolean R_SpriteIsFlashing(vissprite_t *vis);
|
||||||
UINT8 *R_GetSpriteTranslation(vissprite_t *vis);
|
UINT8 *R_GetSpriteTranslation(vissprite_t *vis);
|
||||||
|
@ -236,7 +228,7 @@ typedef struct drawnode_s
|
||||||
struct drawnode_s *prev;
|
struct drawnode_s *prev;
|
||||||
} drawnode_t;
|
} drawnode_t;
|
||||||
|
|
||||||
void R_InitDrawNodes(void);
|
void R_InitDrawNodes(drawnode_t *nodebankhead);
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
// SPRITE FRAME CHARACTERS
|
// SPRITE FRAME CHARACTERS
|
||||||
|
|
63
src/screen.c
63
src/screen.c
|
@ -39,20 +39,13 @@
|
||||||
#include "hardware/hw_model.h"
|
#include "hardware/hw_model.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200))
|
|
||||||
#define RUSEASM //MSC.NET can't patch itself
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
// assembly or c drawer routines for 8bpp/16bpp
|
// assembly or c drawer routines for 8bpp/16bpp
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
void (*colfunc)(void);
|
colfunc_t colfuncs[COLDRAWFUNC_MAX];
|
||||||
void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
|
||||||
|
|
||||||
void (*spanfunc)(void);
|
spanfunc_t spanfuncs[SPANDRAWFUNC_MAX];
|
||||||
void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
spanfunc_t spanfuncs_npo2[SPANDRAWFUNC_MAX];
|
||||||
void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// global video state
|
// global video state
|
||||||
|
@ -106,17 +99,10 @@ boolean R_SSE2 = false;
|
||||||
|
|
||||||
void SCR_SetDrawFuncs(void)
|
void SCR_SetDrawFuncs(void)
|
||||||
{
|
{
|
||||||
//
|
// Always run in 8bpp. todo: remove all 16bpp code?
|
||||||
// setup the right draw routines for either 8bpp or 16bpp
|
|
||||||
//
|
|
||||||
if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code?
|
|
||||||
{
|
|
||||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
|
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
|
||||||
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8;
|
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8;
|
||||||
|
|
||||||
colfunc = colfuncs[BASEDRAWFUNC];
|
|
||||||
spanfunc = spanfuncs[BASEDRAWFUNC];
|
|
||||||
|
|
||||||
colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8;
|
colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8;
|
||||||
colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8;
|
colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8;
|
||||||
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
|
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
|
||||||
|
@ -154,47 +140,6 @@ void SCR_SetDrawFuncs(void)
|
||||||
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8;
|
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8;
|
||||||
spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8;
|
spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8;
|
||||||
spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8;
|
spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8;
|
||||||
spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed
|
|
||||||
|
|
||||||
#ifdef RUSEASM
|
|
||||||
if (R_ASM)
|
|
||||||
{
|
|
||||||
if (R_MMX)
|
|
||||||
{
|
|
||||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX;
|
|
||||||
//colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
|
||||||
//colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
|
||||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX;
|
|
||||||
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM;
|
|
||||||
//colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM;
|
|
||||||
//colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM;
|
|
||||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* else if (vid.bpp > 1)
|
|
||||||
{
|
|
||||||
I_OutputMsg("using highcolor mode\n");
|
|
||||||
spanfunc = basespanfunc = R_DrawSpan_16;
|
|
||||||
transcolfunc = R_DrawTranslatedColumn_16;
|
|
||||||
transtransfunc = R_DrawTranslucentColumn_16; // No 16bit operation for this function
|
|
||||||
|
|
||||||
colfunc = basecolfunc = R_DrawColumn_16;
|
|
||||||
shadecolfunc = NULL; // detect error if used somewhere..
|
|
||||||
fuzzcolfunc = R_DrawTranslucentColumn_16;
|
|
||||||
walldrawerfunc = R_DrawWallColumn_16;
|
|
||||||
}*/
|
|
||||||
else
|
|
||||||
I_Error("unknown bytes per pixel mode %d\n", vid.bpp);
|
|
||||||
/*
|
|
||||||
if (SCR_IsAspectCorrect(vid.width, vid.height))
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCR_SetMode(void)
|
void SCR_SetMode(void)
|
||||||
|
|
52
src/screen.h
52
src/screen.h
|
@ -112,58 +112,6 @@ typedef struct vmode_s
|
||||||
#define NUMSPECIALMODES 4
|
#define NUMSPECIALMODES 4
|
||||||
extern vmode_t specialmodes[NUMSPECIALMODES];
|
extern vmode_t specialmodes[NUMSPECIALMODES];
|
||||||
|
|
||||||
// ---------------------------------------------
|
|
||||||
// color mode dependent drawer function pointers
|
|
||||||
// ---------------------------------------------
|
|
||||||
|
|
||||||
#define BASEDRAWFUNC 0
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
COLDRAWFUNC_BASE = BASEDRAWFUNC,
|
|
||||||
COLDRAWFUNC_FUZZY,
|
|
||||||
COLDRAWFUNC_TRANS,
|
|
||||||
COLDRAWFUNC_SHADE,
|
|
||||||
COLDRAWFUNC_SHADOWED,
|
|
||||||
COLDRAWFUNC_TRANSTRANS,
|
|
||||||
COLDRAWFUNC_TWOSMULTIPATCH,
|
|
||||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
|
||||||
COLDRAWFUNC_FOG,
|
|
||||||
|
|
||||||
COLDRAWFUNC_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void (*colfunc)(void);
|
|
||||||
extern void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SPANDRAWFUNC_BASE = BASEDRAWFUNC,
|
|
||||||
SPANDRAWFUNC_TRANS,
|
|
||||||
SPANDRAWFUNC_TILTED,
|
|
||||||
SPANDRAWFUNC_TILTEDTRANS,
|
|
||||||
|
|
||||||
SPANDRAWFUNC_SPLAT,
|
|
||||||
SPANDRAWFUNC_TRANSSPLAT,
|
|
||||||
SPANDRAWFUNC_TILTEDSPLAT,
|
|
||||||
|
|
||||||
SPANDRAWFUNC_SPRITE,
|
|
||||||
SPANDRAWFUNC_TRANSSPRITE,
|
|
||||||
SPANDRAWFUNC_TILTEDSPRITE,
|
|
||||||
SPANDRAWFUNC_TILTEDTRANSSPRITE,
|
|
||||||
|
|
||||||
SPANDRAWFUNC_WATER,
|
|
||||||
SPANDRAWFUNC_TILTEDWATER,
|
|
||||||
|
|
||||||
SPANDRAWFUNC_FOG,
|
|
||||||
|
|
||||||
SPANDRAWFUNC_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void (*spanfunc)(void);
|
|
||||||
extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
|
||||||
extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
// CPUID
|
// CPUID
|
||||||
// -----
|
// -----
|
||||||
|
|
|
@ -128,11 +128,9 @@ if(${SDL2_FOUND})
|
||||||
if(${SRB2_CONFIG_YASM})
|
if(${SRB2_CONFIG_YASM})
|
||||||
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER})
|
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER})
|
||||||
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT})
|
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT})
|
||||||
set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM)
|
|
||||||
else()
|
else()
|
||||||
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER})
|
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER})
|
||||||
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT})
|
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT})
|
||||||
set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,7 @@ static char returnWadPath[256];
|
||||||
#include "../screen.h" //vid.WndParent
|
#include "../screen.h" //vid.WndParent
|
||||||
#include "../d_net.h"
|
#include "../d_net.h"
|
||||||
#include "../g_game.h"
|
#include "../g_game.h"
|
||||||
|
#include "../r_main.h"
|
||||||
#include "../filesrch.h"
|
#include "../filesrch.h"
|
||||||
#include "endtxt.h"
|
#include "endtxt.h"
|
||||||
#include "sdlmain.h"
|
#include "sdlmain.h"
|
||||||
|
@ -2272,6 +2273,7 @@ INT32 I_StartupSystem(void)
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
I_start_threads();
|
I_start_threads();
|
||||||
I_AddExitFunc(I_stop_threads);
|
I_AddExitFunc(I_stop_threads);
|
||||||
|
I_AddExitFunc(R_StopThreads);
|
||||||
#endif
|
#endif
|
||||||
I_StartupConsole();
|
I_StartupConsole();
|
||||||
#ifdef NEWSIGNALHANDLER
|
#ifdef NEWSIGNALHANDLER
|
||||||
|
|
|
@ -155,7 +155,7 @@ Worker (
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
I_thread_handle
|
||||||
I_spawn_thread (
|
I_spawn_thread (
|
||||||
const char * name,
|
const char * name,
|
||||||
I_thread_fn entry,
|
I_thread_fn entry,
|
||||||
|
@ -189,6 +189,7 @@ I_spawn_thread (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
I_unlock_mutex(i_thread_pool_mutex);
|
I_unlock_mutex(i_thread_pool_mutex);
|
||||||
|
return (I_thread_handle)th;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -354,3 +355,18 @@ I_wake_all_cond (
|
||||||
if (SDL_CondBroadcast(cond) == -1)
|
if (SDL_CondBroadcast(cond) == -1)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32
|
||||||
|
I_atomic_load (
|
||||||
|
I_Atomicptr_t atomic
|
||||||
|
){
|
||||||
|
return SDL_AtomicGet(atomic);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32
|
||||||
|
I_atomic_exchange (
|
||||||
|
I_Atomicptr_t atomic,
|
||||||
|
INT32 val
|
||||||
|
){
|
||||||
|
return SDL_AtomicSet(atomic, val);
|
||||||
|
}
|
||||||
|
|
957
src/tmap.nas
957
src/tmap.nas
|
@ -1,957 +0,0 @@
|
||||||
;; SONIC ROBO BLAST 2
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
||||||
;; Copyright (C) 1999-2021 by Sonic Team Junior.
|
|
||||||
;;
|
|
||||||
;; This program is free software distributed under the
|
|
||||||
;; terms of the GNU General Public License, version 2.
|
|
||||||
;; See the 'LICENSE' file for more details.
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; FILE:
|
|
||||||
;; tmap.nas
|
|
||||||
;; DESCRIPTION:
|
|
||||||
;; Assembler optimised rendering code for software mode.
|
|
||||||
;; Draw wall columns.
|
|
||||||
|
|
||||||
|
|
||||||
[BITS 32]
|
|
||||||
|
|
||||||
%define FRACBITS 16
|
|
||||||
%define TRANSPARENTPIXEL 255
|
|
||||||
|
|
||||||
%ifdef LINUX
|
|
||||||
%macro cextern 1
|
|
||||||
[extern %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro cglobal 1
|
|
||||||
[global %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%else
|
|
||||||
%macro cextern 1
|
|
||||||
%define %1 _%1
|
|
||||||
[extern %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro cglobal 1
|
|
||||||
%define %1 _%1
|
|
||||||
[global %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
; The viddef_s structure. We only need the width field.
|
|
||||||
struc viddef_s
|
|
||||||
resb 12
|
|
||||||
.width: resb 4
|
|
||||||
resb 44
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
;; externs
|
|
||||||
;; columns
|
|
||||||
cextern dc_x
|
|
||||||
cextern dc_yl
|
|
||||||
cextern dc_yh
|
|
||||||
cextern ylookup
|
|
||||||
cextern columnofs
|
|
||||||
cextern dc_source
|
|
||||||
cextern dc_texturemid
|
|
||||||
cextern dc_texheight
|
|
||||||
cextern dc_iscale
|
|
||||||
cextern dc_hires
|
|
||||||
cextern centery
|
|
||||||
cextern centeryfrac
|
|
||||||
cextern dc_colormap
|
|
||||||
cextern dc_transmap
|
|
||||||
cextern colormaps
|
|
||||||
cextern vid
|
|
||||||
cextern topleft
|
|
||||||
|
|
||||||
; DELME
|
|
||||||
cextern R_DrawColumn_8
|
|
||||||
|
|
||||||
; polygon edge rasterizer
|
|
||||||
cextern prastertab
|
|
||||||
|
|
||||||
[SECTION .data]
|
|
||||||
|
|
||||||
;;.align 4
|
|
||||||
loopcount dd 0
|
|
||||||
pixelcount dd 0
|
|
||||||
tystep dd 0
|
|
||||||
|
|
||||||
[SECTION .text]
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;;
|
|
||||||
;; R_DrawColumn : 8bpp column drawer
|
|
||||||
;;
|
|
||||||
;; New optimised version 10-01-1998 by D.Fabrice and P.Boris
|
|
||||||
;; Revised by G. Dick July 2010 to support the intervening twelve years'
|
|
||||||
;; worth of changes to the renderer. Since I only vaguely know what I'm
|
|
||||||
;; doing, this is probably rather suboptimal. Help appreciated!
|
|
||||||
;;
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; fracstep, vid.width in memory
|
|
||||||
;; eax = accumulator
|
|
||||||
;; ebx = colormap
|
|
||||||
;; ecx = count
|
|
||||||
;; edx = heightmask
|
|
||||||
;; esi = source
|
|
||||||
;; edi = dest
|
|
||||||
;; ebp = frac
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
cglobal R_DrawColumn_8_ASM
|
|
||||||
; align 16
|
|
||||||
R_DrawColumn_8_ASM:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov ebp,[dc_yl]
|
|
||||||
mov edi,[ylookup+ebp*4]
|
|
||||||
mov ebx,[dc_x]
|
|
||||||
add edi,[columnofs+ebx*4] ;; edi = dest
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov ecx,[dc_yh]
|
|
||||||
add ecx,1
|
|
||||||
sub ecx,ebp ;; pixel count
|
|
||||||
jle near .done ;; nothing to scale
|
|
||||||
;;
|
|
||||||
;; fracstep = dc_iscale; // But we just use [dc_iscale]
|
|
||||||
;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep));
|
|
||||||
;;
|
|
||||||
mov eax,ebp ;; dc_yl
|
|
||||||
shl eax,FRACBITS
|
|
||||||
sub eax,[centeryfrac]
|
|
||||||
imul dword [dc_iscale]
|
|
||||||
shrd eax,edx,FRACBITS
|
|
||||||
add eax,[dc_texturemid]
|
|
||||||
mov ebp,eax ;; ebp = frac
|
|
||||||
|
|
||||||
mov ebx,[dc_colormap]
|
|
||||||
|
|
||||||
mov esi,[dc_source]
|
|
||||||
;;
|
|
||||||
;; if (dc_hires) frac = 0;
|
|
||||||
;;
|
|
||||||
test byte [dc_hires],0x01
|
|
||||||
jz .texheightcheck
|
|
||||||
xor ebp,ebp
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Check for power of two
|
|
||||||
;;
|
|
||||||
.texheightcheck:
|
|
||||||
mov edx,[dc_texheight]
|
|
||||||
sub edx,1 ;; edx = heightmask
|
|
||||||
test edx,[dc_texheight]
|
|
||||||
jnz .notpowertwo
|
|
||||||
|
|
||||||
test ecx,0x01 ;; Test for odd no. pixels
|
|
||||||
jnz .odd
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Texture height is a power of two, so we get modular arithmetic by
|
|
||||||
;; masking
|
|
||||||
;;
|
|
||||||
.powertwo:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part
|
|
||||||
and eax,edx ;; eax &= heightmask
|
|
||||||
movzx eax,byte [esi + eax] ;; eax = texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
movzx eax,byte [ebx+eax] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
.odd:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part
|
|
||||||
and eax,edx ;; eax &= heightmask
|
|
||||||
movzx eax,byte [esi + eax] ;; eax = texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
movzx eax,byte [ebx+eax] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
|
|
||||||
sub ecx,2 ;; count -= 2
|
|
||||||
jg .powertwo
|
|
||||||
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.notpowertwo:
|
|
||||||
add edx,1
|
|
||||||
shl edx,FRACBITS
|
|
||||||
test ebp,ebp
|
|
||||||
jns .notpowtwoloop
|
|
||||||
|
|
||||||
.makefracpos:
|
|
||||||
add ebp,edx ;; frac is negative; make it positive
|
|
||||||
js .makefracpos
|
|
||||||
|
|
||||||
.notpowtwoloop:
|
|
||||||
cmp ebp,edx ;; Reduce mod height
|
|
||||||
jl .writenonpowtwo
|
|
||||||
sub ebp,edx
|
|
||||||
jmp .notpowtwoloop
|
|
||||||
|
|
||||||
.writenonpowtwo:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part.
|
|
||||||
mov bl,[esi + eax] ;; ebx = colormap + texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
movzx eax,byte [ebx] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
sub ecx,1
|
|
||||||
jnz .notpowtwoloop
|
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
.done:
|
|
||||||
pop ebx ;; restore register variables
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp ;; restore caller's stack frame pointer
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;;
|
|
||||||
;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent
|
|
||||||
;; pixels.
|
|
||||||
;;
|
|
||||||
;; New optimised version 10-01-1998 by D.Fabrice and P.Boris
|
|
||||||
;; Revised by G. Dick July 2010 to support the intervening twelve years'
|
|
||||||
;; worth of changes to the renderer. Since I only vaguely know what I'm
|
|
||||||
;; doing, this is probably rather suboptimal. Help appreciated!
|
|
||||||
;;
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; fracstep, vid.width in memory
|
|
||||||
;; eax = accumulator
|
|
||||||
;; ebx = colormap
|
|
||||||
;; ecx = count
|
|
||||||
;; edx = heightmask
|
|
||||||
;; esi = source
|
|
||||||
;; edi = dest
|
|
||||||
;; ebp = frac
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
cglobal R_Draw2sMultiPatchColumn_8_ASM
|
|
||||||
; align 16
|
|
||||||
R_Draw2sMultiPatchColumn_8_ASM:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov ebp,[dc_yl]
|
|
||||||
mov edi,[ylookup+ebp*4]
|
|
||||||
mov ebx,[dc_x]
|
|
||||||
add edi,[columnofs+ebx*4] ;; edi = dest
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov ecx,[dc_yh]
|
|
||||||
add ecx,1
|
|
||||||
sub ecx,ebp ;; pixel count
|
|
||||||
jle near .done ;; nothing to scale
|
|
||||||
;;
|
|
||||||
;; fracstep = dc_iscale; // But we just use [dc_iscale]
|
|
||||||
;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep));
|
|
||||||
;;
|
|
||||||
mov eax,ebp ;; dc_yl
|
|
||||||
shl eax,FRACBITS
|
|
||||||
sub eax,[centeryfrac]
|
|
||||||
imul dword [dc_iscale]
|
|
||||||
shrd eax,edx,FRACBITS
|
|
||||||
add eax,[dc_texturemid]
|
|
||||||
mov ebp,eax ;; ebp = frac
|
|
||||||
|
|
||||||
mov ebx,[dc_colormap]
|
|
||||||
|
|
||||||
mov esi,[dc_source]
|
|
||||||
;;
|
|
||||||
;; if (dc_hires) frac = 0;
|
|
||||||
;;
|
|
||||||
test byte [dc_hires],0x01
|
|
||||||
jz .texheightcheck
|
|
||||||
xor ebp,ebp
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Check for power of two
|
|
||||||
;;
|
|
||||||
.texheightcheck:
|
|
||||||
mov edx,[dc_texheight]
|
|
||||||
sub edx,1 ;; edx = heightmask
|
|
||||||
test edx,[dc_texheight]
|
|
||||||
jnz .notpowertwo
|
|
||||||
|
|
||||||
test ecx,0x01 ;; Test for odd no. pixels
|
|
||||||
jnz .odd
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Texture height is a power of two, so we get modular arithmetic by
|
|
||||||
;; masking
|
|
||||||
;;
|
|
||||||
.powertwo:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part
|
|
||||||
and eax,edx ;; eax &= heightmask
|
|
||||||
movzx eax,byte [esi + eax] ;; eax = texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
cmp al,TRANSPARENTPIXEL ;; Is pixel transparent?
|
|
||||||
je .nextpowtwoeven ;; If so, advance.
|
|
||||||
movzx eax,byte [ebx+eax] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
.nextpowtwoeven:
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
.odd:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part
|
|
||||||
and eax,edx ;; eax &= heightmask
|
|
||||||
movzx eax,byte [esi + eax] ;; eax = texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
cmp al,TRANSPARENTPIXEL ;; Is pixel transparent?
|
|
||||||
je .nextpowtwoodd ;; If so, advance.
|
|
||||||
movzx eax,byte [ebx+eax] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
.nextpowtwoodd:
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
|
|
||||||
sub ecx,2 ;; count -= 2
|
|
||||||
jg .powertwo
|
|
||||||
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.notpowertwo:
|
|
||||||
add edx,1
|
|
||||||
shl edx,FRACBITS
|
|
||||||
test ebp,ebp
|
|
||||||
jns .notpowtwoloop
|
|
||||||
|
|
||||||
.makefracpos:
|
|
||||||
add ebp,edx ;; frac is negative; make it positive
|
|
||||||
js .makefracpos
|
|
||||||
|
|
||||||
.notpowtwoloop:
|
|
||||||
cmp ebp,edx ;; Reduce mod height
|
|
||||||
jl .writenonpowtwo
|
|
||||||
sub ebp,edx
|
|
||||||
jmp .notpowtwoloop
|
|
||||||
|
|
||||||
.writenonpowtwo:
|
|
||||||
mov eax,ebp ;; eax = frac
|
|
||||||
sar eax,FRACBITS ;; Integer part.
|
|
||||||
mov bl,[esi + eax] ;; ebx = colormap + texel
|
|
||||||
add ebp,[dc_iscale] ;; frac += fracstep
|
|
||||||
cmp bl,TRANSPARENTPIXEL ;; Is pixel transparent?
|
|
||||||
je .nextnonpowtwo ;; If so, advance.
|
|
||||||
movzx eax,byte [ebx] ;; Map through colormap
|
|
||||||
mov [edi],al ;; Write pixel
|
|
||||||
.nextnonpowtwo:
|
|
||||||
;; dest += vid.width
|
|
||||||
add edi,[vid + viddef_s.width]
|
|
||||||
|
|
||||||
sub ecx,1
|
|
||||||
jnz .notpowtwoloop
|
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
.done:
|
|
||||||
pop ebx ;; restore register variables
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp ;; restore caller's stack frame pointer
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; R_DrawTranslucentColumnA_8
|
|
||||||
;;
|
|
||||||
;; Vertical column texture drawer, with transparency. Replaces Doom2's
|
|
||||||
;; 'fuzz' effect, which was not so beautiful.
|
|
||||||
;; Transparency is always impressive in some way, don't know why...
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
cglobal R_DrawTranslucentColumn_8_ASM
|
|
||||||
R_DrawTranslucentColumn_8_ASM:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov ebp,[dc_yl]
|
|
||||||
mov ebx,ebp
|
|
||||||
mov edi,[ylookup+ebx*4]
|
|
||||||
mov ebx,[dc_x]
|
|
||||||
add edi,[columnofs+ebx*4] ;; edi = dest
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov eax,[dc_yh]
|
|
||||||
inc eax
|
|
||||||
sub eax,ebp ;; pixel count
|
|
||||||
mov [pixelcount],eax ;; save for final pixel
|
|
||||||
jle near vtdone ;; nothing to scale
|
|
||||||
;;
|
|
||||||
;; frac = dc_texturemid - (centery-dc_yl)*fracstep;
|
|
||||||
;;
|
|
||||||
mov ecx,[dc_iscale] ;; fracstep
|
|
||||||
mov eax,[centery]
|
|
||||||
sub eax,ebp
|
|
||||||
imul eax,ecx
|
|
||||||
mov edx,[dc_texturemid]
|
|
||||||
sub edx,eax
|
|
||||||
mov ebx,edx
|
|
||||||
|
|
||||||
shr ebx,16 ;; frac int.
|
|
||||||
and ebx,0x7f
|
|
||||||
shl edx,16 ;; y frac up
|
|
||||||
|
|
||||||
mov ebp,ecx
|
|
||||||
shl ebp,16 ;; fracstep f. up
|
|
||||||
shr ecx,16 ;; fracstep i. ->cl
|
|
||||||
and cl,0x7f
|
|
||||||
push cx
|
|
||||||
mov ecx,edx
|
|
||||||
pop cx
|
|
||||||
mov edx,[dc_colormap]
|
|
||||||
mov esi,[dc_source]
|
|
||||||
;;
|
|
||||||
;; lets rock :) !
|
|
||||||
;;
|
|
||||||
mov eax,[pixelcount]
|
|
||||||
shr eax,0x2
|
|
||||||
test byte [pixelcount],0x3
|
|
||||||
mov ch,al ;; quad count
|
|
||||||
mov eax,[dc_transmap]
|
|
||||||
je vt4quadloop
|
|
||||||
;;
|
|
||||||
;; do un-even pixel
|
|
||||||
;;
|
|
||||||
test byte [pixelcount],0x1
|
|
||||||
je trf2
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add ecx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [edi],dl
|
|
||||||
pf: add edi,0x12345678
|
|
||||||
;;
|
|
||||||
;; do two non-quad-aligned pixels
|
|
||||||
;;
|
|
||||||
trf2: test byte [pixelcount],0x2
|
|
||||||
je trf3
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add ecx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [edi],dl
|
|
||||||
pg: add edi,0x12345678
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add ecx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [edi],dl
|
|
||||||
ph: add edi,0x12345678
|
|
||||||
;;
|
|
||||||
;; test if there was at least 4 pixels
|
|
||||||
;;
|
|
||||||
trf3: test ch,0xff ;; test quad count
|
|
||||||
je near vtdone
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ebp : ystep frac. upper 24 bits
|
|
||||||
;; edx : y frac. upper 24 bits
|
|
||||||
;; ebx : y i. lower 7 bits, masked for index
|
|
||||||
;; ecx : ch = counter, cl = y step i.
|
|
||||||
;; eax : colormap aligned 256
|
|
||||||
;; esi : source texture column
|
|
||||||
;; edi : dest screen
|
|
||||||
;;
|
|
||||||
vt4quadloop:
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [tystep],ebp
|
|
||||||
pi: add edi,0x12345678
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
pj: sub edi,0x12345678
|
|
||||||
mov ebp,edi
|
|
||||||
pk: sub edi,0x12345678
|
|
||||||
jmp short inloop
|
|
||||||
align 4
|
|
||||||
vtquadloop:
|
|
||||||
add ecx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
q1: add ebp,0x23456789
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [edi],dl
|
|
||||||
mov al,[ebp] ;; fetch dest : index into colormap
|
|
||||||
inloop:
|
|
||||||
add ecx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
q2: add edi,0x23456789
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [ebp+0x0],dl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
add ecx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
q3: add ebp,0x23456789
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [edi],dl
|
|
||||||
mov al,[ebp] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
add ecx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
q4: add edi,0x23456789
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov dl,[edx]
|
|
||||||
mov [ebp],dl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
dec ch
|
|
||||||
jne vtquadloop
|
|
||||||
vtdone:
|
|
||||||
pop ebx
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; R_DrawShadeColumn
|
|
||||||
;;
|
|
||||||
;; for smoke..etc.. test.
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
cglobal R_DrawShadeColumn_8_ASM
|
|
||||||
R_DrawShadeColumn_8_ASM:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov ebp,[dc_yl]
|
|
||||||
mov ebx,ebp
|
|
||||||
mov edi,[ylookup+ebx*4]
|
|
||||||
mov ebx,[dc_x]
|
|
||||||
add edi,[columnofs+ebx*4] ;; edi = dest
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov eax,[dc_yh]
|
|
||||||
inc eax
|
|
||||||
sub eax,ebp ;; pixel count
|
|
||||||
mov [pixelcount],eax ;; save for final pixel
|
|
||||||
jle near shdone ;; nothing to scale
|
|
||||||
;;
|
|
||||||
;; frac = dc_texturemid - (centery-dc_yl)*fracstep;
|
|
||||||
;;
|
|
||||||
mov ecx,[dc_iscale] ;; fracstep
|
|
||||||
mov eax,[centery]
|
|
||||||
sub eax,ebp
|
|
||||||
imul eax,ecx
|
|
||||||
mov edx,[dc_texturemid]
|
|
||||||
sub edx,eax
|
|
||||||
mov ebx,edx
|
|
||||||
shr ebx,16 ;; frac int.
|
|
||||||
and ebx,byte +0x7f
|
|
||||||
shl edx,16 ;; y frac up
|
|
||||||
|
|
||||||
mov ebp,ecx
|
|
||||||
shl ebp,16 ;; fracstep f. up
|
|
||||||
shr ecx,16 ;; fracstep i. ->cl
|
|
||||||
and cl,0x7f
|
|
||||||
|
|
||||||
mov esi,[dc_source]
|
|
||||||
;;
|
|
||||||
;; lets rock :) !
|
|
||||||
;;
|
|
||||||
mov eax,[pixelcount]
|
|
||||||
mov dh,al
|
|
||||||
shr eax,2
|
|
||||||
mov ch,al ;; quad count
|
|
||||||
mov eax,[colormaps]
|
|
||||||
test dh,3
|
|
||||||
je sh4quadloop
|
|
||||||
;;
|
|
||||||
;; do un-even pixel
|
|
||||||
;;
|
|
||||||
test dh,0x1
|
|
||||||
je shf2
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add edx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov [edi],dl
|
|
||||||
pl: add edi,0x12345678
|
|
||||||
;;
|
|
||||||
;; do two non-quad-aligned pixels
|
|
||||||
;;
|
|
||||||
shf2:
|
|
||||||
test dh,0x2
|
|
||||||
je shf3
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add edx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov [edi],dl
|
|
||||||
pm: add edi,0x12345678
|
|
||||||
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
add edx,ebp
|
|
||||||
adc bl,cl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
and bl,0x7f
|
|
||||||
mov dl,[eax]
|
|
||||||
mov [edi],dl
|
|
||||||
pn: add edi,0x12345678
|
|
||||||
;;
|
|
||||||
;; test if there was at least 4 pixels
|
|
||||||
;;
|
|
||||||
shf3:
|
|
||||||
test ch,0xff ;; test quad count
|
|
||||||
je near shdone
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ebp : ystep frac. upper 24 bits
|
|
||||||
;; edx : y frac. upper 24 bits
|
|
||||||
;; ebx : y i. lower 7 bits, masked for index
|
|
||||||
;; ecx : ch = counter, cl = y step i.
|
|
||||||
;; eax : colormap aligned 256
|
|
||||||
;; esi : source texture column
|
|
||||||
;; edi : dest screen
|
|
||||||
;;
|
|
||||||
sh4quadloop:
|
|
||||||
mov dh,0x7f ;; prep mask
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [tystep],ebp
|
|
||||||
po: add edi,0x12345678
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
pp: sub edi,0x12345678
|
|
||||||
mov ebp,edi
|
|
||||||
pq: sub edi,0x12345678
|
|
||||||
jmp short shinloop
|
|
||||||
|
|
||||||
align 4
|
|
||||||
shquadloop:
|
|
||||||
add edx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
and bl,dh
|
|
||||||
q5: add ebp,0x12345678
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [edi],dl
|
|
||||||
mov al,[ebp] ;; fetch dest : index into colormap
|
|
||||||
shinloop:
|
|
||||||
add edx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
and bl,dh
|
|
||||||
q6: add edi,0x12345678
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [ebp],dl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
add edx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
and bl,dh
|
|
||||||
q7: add ebp,0x12345678
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [edi],dl
|
|
||||||
mov al,[ebp] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
add edx,[tystep]
|
|
||||||
adc bl,cl
|
|
||||||
and bl,dh
|
|
||||||
q8: add edi,0x12345678
|
|
||||||
mov dl,[eax]
|
|
||||||
mov ah,[esi+ebx] ;; fetch texel : colormap number
|
|
||||||
mov [ebp],dl
|
|
||||||
mov al,[edi] ;; fetch dest : index into colormap
|
|
||||||
|
|
||||||
dec ch
|
|
||||||
jne shquadloop
|
|
||||||
|
|
||||||
shdone:
|
|
||||||
pop ebx ;; restore register variables
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp ;; restore caller's stack frame pointer
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
;; ========================================================================
|
|
||||||
;; Rasterization of the segments of a LINEAR polygne textur of manire.
|
|
||||||
;; It is thus a question of interpolating coordinate them at the edges of texture in
|
|
||||||
;; the time that the X-coordinates minx/maxx for each line.
|
|
||||||
;; the argument ' dir' indicates which edges of texture are Interpol?:
|
|
||||||
;; 0: segments associs at edge TOP? and BOTTOM? (constant TY)
|
|
||||||
;; 1: segments associs at the LEFT and RIGHT edge (constant TX)
|
|
||||||
;; ========================================================================
|
|
||||||
;;
|
|
||||||
;; void rasterize_segment_tex( LONG x1, LONG y1, LONG x2, LONG y2, LONG tv1, LONG tv2, LONG tc, LONG dir );
|
|
||||||
;; ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8
|
|
||||||
;;
|
|
||||||
;; Pour dir = 0, (tv1,tv2) = (tX1,tX2), tc = tY, en effet TY est constant.
|
|
||||||
;;
|
|
||||||
;; Pour dir = 1, (tv1,tv2) = (tY1,tY2), tc = tX, en effet TX est constant.
|
|
||||||
;;
|
|
||||||
;;
|
|
||||||
;; Uses: extern struct rastery *_rastertab;
|
|
||||||
;;
|
|
||||||
|
|
||||||
MINX EQU 0
|
|
||||||
MAXX EQU 4
|
|
||||||
TX1 EQU 8
|
|
||||||
TY1 EQU 12
|
|
||||||
TX2 EQU 16
|
|
||||||
TY2 EQU 20
|
|
||||||
RASTERY_SIZEOF EQU 24
|
|
||||||
|
|
||||||
cglobal rasterize_segment_tex_asm
|
|
||||||
rasterize_segment_tex_asm:
|
|
||||||
push ebp
|
|
||||||
mov ebp,esp
|
|
||||||
|
|
||||||
sub esp,byte +0x8 ;; allocate the local variables
|
|
||||||
|
|
||||||
push ebx
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
o16 mov ax,es
|
|
||||||
push eax
|
|
||||||
|
|
||||||
;; #define DX [ebp-4]
|
|
||||||
;; #define TD [ebp-8]
|
|
||||||
|
|
||||||
mov eax,[ebp+0xc] ;; y1
|
|
||||||
mov ebx,[ebp+0x14] ;; y2
|
|
||||||
cmp ebx,eax
|
|
||||||
je near .L_finished ;; special (y1==y2) segment horizontal, exit!
|
|
||||||
|
|
||||||
jg near .L_rasterize_right
|
|
||||||
|
|
||||||
;;rasterize_left: ;; one rasterize a segment LEFT of the polygne
|
|
||||||
|
|
||||||
mov ecx,eax
|
|
||||||
sub ecx,ebx
|
|
||||||
inc ecx ;; y1-y2+1
|
|
||||||
|
|
||||||
mov eax,RASTERY_SIZEOF
|
|
||||||
mul ebx ;; * y2
|
|
||||||
mov esi,[prastertab]
|
|
||||||
add esi,eax ;; point into rastertab[y2]
|
|
||||||
|
|
||||||
mov eax,[ebp+0x8] ;; ARG1
|
|
||||||
sub eax,[ebp+0x10] ;; ARG3
|
|
||||||
shl eax,0x10 ;; ((x1-x2)<<PRE) ...
|
|
||||||
cdq
|
|
||||||
idiv ecx ;; dx = ... / (y1-y2+1)
|
|
||||||
mov [ebp-0x4],eax ;; DX
|
|
||||||
|
|
||||||
mov eax,[ebp+0x18] ;; ARG5
|
|
||||||
sub eax,[ebp+0x1c] ;; ARG6
|
|
||||||
shl eax,0x10
|
|
||||||
cdq
|
|
||||||
idiv ecx ;; tdx =((tx1-tx2)<<PRE) / (y1-y2+1)
|
|
||||||
mov [ebp-0x8],eax ;; idem tdy =((ty1-ty2)<<PRE) / (y1-y2+1)
|
|
||||||
|
|
||||||
mov eax,[ebp+0x10] ;; ARG3
|
|
||||||
shl eax,0x10 ;; x = x2<<PRE
|
|
||||||
|
|
||||||
mov ebx,[ebp+0x1c] ;; ARG6
|
|
||||||
shl ebx,0x10 ;; tx = tx2<<PRE d0
|
|
||||||
;; ty = ty2<<PRE d1
|
|
||||||
mov edx,[ebp+0x20] ;; ARG7
|
|
||||||
shl edx,0x10 ;; ty = ty<<PRE d0
|
|
||||||
;; tx = tx<<PRE d1
|
|
||||||
push ebp
|
|
||||||
mov edi,[ebp-0x4] ;; DX
|
|
||||||
cmp dword [ebp+0x24],byte +0x0 ;; ARG8 direction ?
|
|
||||||
|
|
||||||
mov ebp,[ebp-0x8] ;; TD
|
|
||||||
je .L_rleft_h_loop
|
|
||||||
;;
|
|
||||||
;; TY varies, TX is constant
|
|
||||||
;;
|
|
||||||
.L_rleft_v_loop:
|
|
||||||
mov [esi+MINX],eax ;; rastertab[y].minx = x
|
|
||||||
add ebx,ebp
|
|
||||||
mov [esi+TX1],edx ;; .tx1 = tx
|
|
||||||
add eax,edi
|
|
||||||
mov [esi+TY1],ebx ;; .ty1 = ty
|
|
||||||
|
|
||||||
;;addl DX, %eax // x += dx
|
|
||||||
;;addl TD, %ebx // ty += tdy
|
|
||||||
|
|
||||||
add esi,RASTERY_SIZEOF ;; next raster line into rastertab[]
|
|
||||||
dec ecx
|
|
||||||
jne .L_rleft_v_loop
|
|
||||||
pop ebp
|
|
||||||
jmp .L_finished
|
|
||||||
;;
|
|
||||||
;; TX varies, TY is constant
|
|
||||||
;;
|
|
||||||
.L_rleft_h_loop:
|
|
||||||
mov [esi+MINX],eax ;; rastertab[y].minx = x
|
|
||||||
add eax,edi
|
|
||||||
mov [esi+TX1],ebx ;; .tx1 = tx
|
|
||||||
add ebx,ebp
|
|
||||||
mov [esi+TY1],edx ;; .ty1 = ty
|
|
||||||
|
|
||||||
;;addl DX, %eax // x += dx
|
|
||||||
;;addl TD, %ebx // tx += tdx
|
|
||||||
|
|
||||||
add esi,RASTERY_SIZEOF ;; next raster line into rastertab[]
|
|
||||||
dec ecx
|
|
||||||
jne .L_rleft_h_loop
|
|
||||||
pop ebp
|
|
||||||
jmp .L_finished
|
|
||||||
;;
|
|
||||||
;; one rasterize a segment LINE of the polygne
|
|
||||||
;;
|
|
||||||
.L_rasterize_right:
|
|
||||||
mov ecx,ebx
|
|
||||||
sub ecx,eax
|
|
||||||
inc ecx ;; y2-y1+1
|
|
||||||
|
|
||||||
mov ebx,RASTERY_SIZEOF
|
|
||||||
mul ebx ;; * y1
|
|
||||||
mov esi,[prastertab]
|
|
||||||
add esi,eax ;; point into rastertab[y1]
|
|
||||||
|
|
||||||
mov eax,[ebp+0x10] ;; ARG3
|
|
||||||
sub eax,[ebp+0x8] ;; ARG1
|
|
||||||
shl eax,0x10 ;; ((x2-x1)<<PRE) ...
|
|
||||||
cdq
|
|
||||||
idiv ecx ;; dx = ... / (y2-y1+1)
|
|
||||||
mov [ebp-0x4],eax ;; DX
|
|
||||||
|
|
||||||
mov eax,[ebp+0x1c] ;; ARG6
|
|
||||||
sub eax,[ebp+0x18] ;; ARG5
|
|
||||||
shl eax,0x10
|
|
||||||
cdq
|
|
||||||
idiv ecx ;; tdx =((tx2-tx1)<<PRE) / (y2-y1+1)
|
|
||||||
mov [ebp-0x8],eax ;; idem tdy =((ty2-ty1)<<PRE) / (y2-y1+1)
|
|
||||||
|
|
||||||
mov eax,[ebp+0x8] ;; ARG1
|
|
||||||
shl eax,0x10 ;; x = x1<<PRE
|
|
||||||
|
|
||||||
mov ebx,[ebp+0x18] ;; ARG5
|
|
||||||
shl ebx,0x10 ;; tx = tx1<<PRE d0
|
|
||||||
;; ty = ty1<<PRE d1
|
|
||||||
mov edx,[ebp+0x20] ;; ARG7
|
|
||||||
shl edx,0x10 ;; ty = ty<<PRE d0
|
|
||||||
;; tx = tx<<PRE d1
|
|
||||||
push ebp
|
|
||||||
mov edi,[ebp-0x4] ;; DX
|
|
||||||
|
|
||||||
cmp dword [ebp+0x24], 0 ;; direction ?
|
|
||||||
|
|
||||||
mov ebp,[ebp-0x8] ;; TD
|
|
||||||
je .L_rright_h_loop
|
|
||||||
;;
|
|
||||||
;; TY varies, TX is constant
|
|
||||||
;;
|
|
||||||
.L_rright_v_loop:
|
|
||||||
|
|
||||||
mov [esi+MAXX],eax ;; rastertab[y].maxx = x
|
|
||||||
add ebx,ebp
|
|
||||||
mov [esi+TX2],edx ;; .tx2 = tx
|
|
||||||
add eax,edi
|
|
||||||
mov [esi+TY2],ebx ;; .ty2 = ty
|
|
||||||
|
|
||||||
;;addl DX, %eax // x += dx
|
|
||||||
;;addl TD, %ebx // ty += tdy
|
|
||||||
|
|
||||||
add esi,RASTERY_SIZEOF
|
|
||||||
dec ecx
|
|
||||||
jne .L_rright_v_loop
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
|
|
||||||
jmp short .L_finished
|
|
||||||
;;
|
|
||||||
;; TX varies, TY is constant
|
|
||||||
;;
|
|
||||||
.L_rright_h_loop:
|
|
||||||
mov [esi+MAXX],eax ;; rastertab[y].maxx = x
|
|
||||||
add eax,edi
|
|
||||||
mov [esi+TX2],ebx ;; .tx2 = tx
|
|
||||||
add ebx,ebp
|
|
||||||
mov [esi+TY2],edx ;; .ty2 = ty
|
|
||||||
|
|
||||||
;;addl DX, %eax // x += dx
|
|
||||||
;;addl TD, %ebx // tx += tdx
|
|
||||||
|
|
||||||
add esi,RASTERY_SIZEOF
|
|
||||||
dec ecx
|
|
||||||
jne .L_rright_h_loop
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
|
|
||||||
.L_finished:
|
|
||||||
pop eax
|
|
||||||
o16 mov es,ax
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
mov esp,ebp
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
1587
src/tmap.s
1587
src/tmap.s
File diff suppressed because it is too large
Load diff
322
src/tmap_asm.s
322
src/tmap_asm.s
|
@ -1,322 +0,0 @@
|
||||||
// SONIC ROBO BLAST 2
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
||||||
// Copyright (C) 1999-2021 by Sonic Team Junior.
|
|
||||||
//
|
|
||||||
// This program is free software distributed under the
|
|
||||||
// terms of the GNU General Public License, version 2.
|
|
||||||
// See the 'LICENSE' file for more details.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/// \file tmap_asm.s
|
|
||||||
/// \brief ???
|
|
||||||
|
|
||||||
//.comm _dc_colormap,4
|
|
||||||
//.comm _dc_x,4
|
|
||||||
//.comm _dc_yl,4
|
|
||||||
//.comm _dc_yh,4
|
|
||||||
//.comm _dc_iscale,4
|
|
||||||
//.comm _dc_texturemid,4
|
|
||||||
//.comm _dc_source,4
|
|
||||||
//.comm _ylookup,4
|
|
||||||
//.comm _columnofs,4
|
|
||||||
//.comm _loopcount,4
|
|
||||||
//.comm _pixelcount,4
|
|
||||||
.data
|
|
||||||
_pixelcount:
|
|
||||||
.long 0x00000000
|
|
||||||
_loopcount:
|
|
||||||
.long 0x00000000
|
|
||||||
.align 8
|
|
||||||
_mmxcomm:
|
|
||||||
.long 0x00000000
|
|
||||||
.text
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
.globl _R_DrawColumn8_NOMMX
|
|
||||||
_R_DrawColumn8_NOMMX:
|
|
||||||
pushl %ebp
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
pushl %ebx
|
|
||||||
movl _dc_yl,%edx
|
|
||||||
movl _dc_yh,%eax
|
|
||||||
subl %edx,%eax
|
|
||||||
leal 1(%eax),%ebx
|
|
||||||
testl %ebx,%ebx
|
|
||||||
jle rdc8ndone
|
|
||||||
movl _dc_x,%eax
|
|
||||||
movl _ylookup, %edi
|
|
||||||
movl (%edi,%edx,4),%esi
|
|
||||||
movl _columnofs, %edi
|
|
||||||
addl (%edi,%eax,4),%esi
|
|
||||||
movl _dc_iscale,%edi
|
|
||||||
movl %edx,%eax
|
|
||||||
imull %edi,%eax
|
|
||||||
movl _dc_texturemid,%ecx
|
|
||||||
addl %eax,%ecx
|
|
||||||
|
|
||||||
movl _dc_source,%ebp
|
|
||||||
xorl %edx, %edx
|
|
||||||
subl $0x12345678, %esi
|
|
||||||
.globl rdc8nwidth1
|
|
||||||
rdc8nwidth1:
|
|
||||||
.align 4,0x90
|
|
||||||
rdc8nloop:
|
|
||||||
movl %ecx,%eax
|
|
||||||
shrl $16,%eax
|
|
||||||
addl %edi,%ecx
|
|
||||||
andl $127,%eax
|
|
||||||
addl $0x12345678,%esi
|
|
||||||
.globl rdc8nwidth2
|
|
||||||
rdc8nwidth2:
|
|
||||||
movb (%eax,%ebp),%dl
|
|
||||||
movl _dc_colormap,%eax
|
|
||||||
movb (%eax,%edx),%al
|
|
||||||
movb %al,(%esi)
|
|
||||||
decl %ebx
|
|
||||||
jne rdc8nloop
|
|
||||||
rdc8ndone:
|
|
||||||
popl %ebx
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
//
|
|
||||||
// Optimised specifically for P54C/P55C (aka Pentium with/without MMX)
|
|
||||||
// By ES 1998/08/01
|
|
||||||
//
|
|
||||||
|
|
||||||
.globl _R_DrawColumn_8_Pentium
|
|
||||||
_R_DrawColumn_8_Pentium:
|
|
||||||
pushl %ebp
|
|
||||||
pushl %ebx
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
movl _dc_yl,%eax // Top pixel
|
|
||||||
movl _dc_yh,%ebx // Bottom pixel
|
|
||||||
movl _ylookup, %edi
|
|
||||||
movl (%edi,%ebx,4),%ecx
|
|
||||||
subl %eax,%ebx // ebx=number of pixels-1
|
|
||||||
jl rdc8pdone // no pixel to draw, done
|
|
||||||
jnz rdc8pmany
|
|
||||||
movl _dc_x,%edx // Special case: only one pixel
|
|
||||||
movl _columnofs, %edi
|
|
||||||
addl (%edi,%edx,4),%ecx // dest pixel at (%ecx)
|
|
||||||
movl _dc_iscale,%esi
|
|
||||||
imull %esi,%eax
|
|
||||||
movl _dc_texturemid,%edi
|
|
||||||
addl %eax,%edi // texture index in edi
|
|
||||||
movl _dc_colormap,%edx
|
|
||||||
shrl $16, %edi
|
|
||||||
movl _dc_source,%ebp
|
|
||||||
andl $127,%edi
|
|
||||||
movb (%edi,%ebp),%dl // read texture pixel
|
|
||||||
movb (%edx),%al // lookup for light
|
|
||||||
movb %al,0(%ecx) // write it
|
|
||||||
jmp rdc8pdone // done!
|
|
||||||
.align 4, 0x90
|
|
||||||
rdc8pmany: // draw >1 pixel
|
|
||||||
movl _dc_x,%edx
|
|
||||||
movl _columnofs, %edi
|
|
||||||
movl (%edi,%edx,4),%edx
|
|
||||||
leal 0x12345678(%edx, %ecx), %edi // edi = two pixels above bottom
|
|
||||||
.globl rdc8pwidth5
|
|
||||||
rdc8pwidth5: // DeadBeef = -2*SCREENWIDTH
|
|
||||||
movl _dc_iscale,%edx // edx = fracstep
|
|
||||||
imull %edx,%eax
|
|
||||||
shll $9, %edx // fixme: Should get 7.25 fix as input
|
|
||||||
movl _dc_texturemid,%ecx
|
|
||||||
addl %eax,%ecx // ecx = frac
|
|
||||||
movl _dc_colormap,%eax // eax = lighting/special effects LUT
|
|
||||||
shll $9, %ecx
|
|
||||||
movl _dc_source,%esi // esi = source ptr
|
|
||||||
|
|
||||||
imull $0x12345678, %ebx // ebx = negative offset to pixel
|
|
||||||
.globl rdc8pwidth6
|
|
||||||
rdc8pwidth6: // DeadBeef = -SCREENWIDTH
|
|
||||||
|
|
||||||
// Begin the calculation of the two first pixels
|
|
||||||
leal (%ecx, %edx), %ebp
|
|
||||||
shrl $25, %ecx
|
|
||||||
movb (%esi, %ecx), %al
|
|
||||||
leal (%edx, %ebp), %ecx
|
|
||||||
shrl $25, %ebp
|
|
||||||
movb (%eax), %dl
|
|
||||||
|
|
||||||
// The main loop
|
|
||||||
rdc8ploop:
|
|
||||||
movb (%esi,%ebp), %al // load 1
|
|
||||||
leal (%ecx, %edx), %ebp // calc frac 3
|
|
||||||
|
|
||||||
shrl $25, %ecx // shift frac 2
|
|
||||||
movb %dl, 0x12345678(%edi, %ebx)// store 0
|
|
||||||
.globl rdc8pwidth1
|
|
||||||
rdc8pwidth1: // DeadBeef = 2*SCREENWIDTH
|
|
||||||
|
|
||||||
movb (%eax), %al // lookup 1
|
|
||||||
|
|
||||||
movb %al, 0x12345678(%edi, %ebx)// store 1
|
|
||||||
.globl rdc8pwidth2
|
|
||||||
rdc8pwidth2: // DeadBeef = 3*SCREENWIDTH
|
|
||||||
movb (%esi, %ecx), %al // load 2
|
|
||||||
|
|
||||||
leal (%ebp, %edx), %ecx // calc frac 4
|
|
||||||
|
|
||||||
shrl $25, %ebp // shift frac 3
|
|
||||||
movb (%eax), %dl // lookup 2
|
|
||||||
|
|
||||||
addl $0x12345678, %ebx // counter
|
|
||||||
.globl rdc8pwidth3
|
|
||||||
rdc8pwidth3: // DeadBeef = 2*SCREENWIDTH
|
|
||||||
jl rdc8ploop // loop
|
|
||||||
|
|
||||||
// End of loop. Write extra pixel or just exit.
|
|
||||||
jnz rdc8pdone
|
|
||||||
movb %dl, 0x12345678(%edi, %ebx)// Write odd pixel
|
|
||||||
.globl rdc8pwidth4
|
|
||||||
rdc8pwidth4: // DeadBeef = 2*SCREENWIDTH
|
|
||||||
|
|
||||||
rdc8pdone:
|
|
||||||
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
popl %ebx
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
//
|
|
||||||
// MMX asm version, optimised for K6
|
|
||||||
// By ES 1998/07/05
|
|
||||||
//
|
|
||||||
|
|
||||||
.globl _R_DrawColumn_8_K6_MMX
|
|
||||||
_R_DrawColumn_8_K6_MMX:
|
|
||||||
pushl %ebp
|
|
||||||
pushl %ebx
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
|
|
||||||
movl %esp, %eax // Push 8 or 12, so that (%esp) gets aligned by 8
|
|
||||||
andl $7,%eax
|
|
||||||
addl $8,%eax
|
|
||||||
movl %eax, _mmxcomm // Temp storage in mmxcomm: (%esp) is used instead
|
|
||||||
subl %eax,%esp
|
|
||||||
|
|
||||||
movl _dc_yl,%edx // Top pixel
|
|
||||||
movl _dc_yh,%ebx // Bottom pixel
|
|
||||||
movl _ylookup, %edi
|
|
||||||
movl (%edi,%ebx,4),%ecx
|
|
||||||
subl %edx,%ebx // ebx=number of pixels-1
|
|
||||||
jl 0x12345678 // no pixel to draw, done
|
|
||||||
.globl rdc8moffs1
|
|
||||||
rdc8moffs1:
|
|
||||||
jnz rdc8mmany
|
|
||||||
movl _dc_x,%eax // Special case: only one pixel
|
|
||||||
movl _columnofs, %edi
|
|
||||||
addl (%edi,%eax,4),%ecx // dest pixel at (%ecx)
|
|
||||||
movl _dc_iscale,%esi
|
|
||||||
imull %esi,%edx
|
|
||||||
movl _dc_texturemid,%edi
|
|
||||||
addl %edx,%edi // texture index in edi
|
|
||||||
movl _dc_colormap,%edx
|
|
||||||
shrl $16, %edi
|
|
||||||
movl _dc_source,%ebp
|
|
||||||
andl $127,%edi
|
|
||||||
movb (%edi,%ebp),%dl // read texture pixel
|
|
||||||
movb (%edx),%al // lookup for light
|
|
||||||
movb %al,0(%ecx) // write it
|
|
||||||
jmp rdc8mdone // done!
|
|
||||||
.globl rdc8moffs2
|
|
||||||
rdc8moffs2:
|
|
||||||
.align 4, 0x90
|
|
||||||
rdc8mmany: // draw >1 pixel
|
|
||||||
movl _dc_x,%eax
|
|
||||||
movl _columnofs, %edi
|
|
||||||
movl (%edi,%eax,4),%eax
|
|
||||||
leal 0x12345678(%eax, %ecx), %esi // esi = two pixels above bottom
|
|
||||||
.globl rdc8mwidth3
|
|
||||||
rdc8mwidth3: // DeadBeef = -2*SCREENWIDTH
|
|
||||||
movl _dc_iscale,%ecx // ecx = fracstep
|
|
||||||
imull %ecx,%edx
|
|
||||||
shll $9, %ecx // fixme: Should get 7.25 fix as input
|
|
||||||
movl _dc_texturemid,%eax
|
|
||||||
addl %edx,%eax // eax = frac
|
|
||||||
movl _dc_colormap,%edx // edx = lighting/special effects LUT
|
|
||||||
shll $9, %eax
|
|
||||||
leal (%ecx, %ecx), %edi
|
|
||||||
movl _dc_source,%ebp // ebp = source ptr
|
|
||||||
movl %edi, 0(%esp) // Start moving frac and fracstep to MMX regs
|
|
||||||
|
|
||||||
imull $0x12345678, %ebx // ebx = negative offset to pixel
|
|
||||||
.globl rdc8mwidth5
|
|
||||||
rdc8mwidth5: // DeadBeef = -SCREENWIDTH
|
|
||||||
|
|
||||||
movl %edi, 4(%esp)
|
|
||||||
leal (%eax, %ecx), %edi
|
|
||||||
movq 0(%esp), %mm1 // fracstep:fracstep in mm1
|
|
||||||
movl %eax, 0(%esp)
|
|
||||||
shrl $25, %eax
|
|
||||||
movl %edi, 4(%esp)
|
|
||||||
movzbl (%ebp, %eax), %eax
|
|
||||||
movq 0(%esp), %mm0 // frac:frac in mm0
|
|
||||||
|
|
||||||
paddd %mm1, %mm0
|
|
||||||
shrl $25, %edi
|
|
||||||
movq %mm0, %mm2
|
|
||||||
psrld $25, %mm2 // texture index in mm2
|
|
||||||
paddd %mm1, %mm0
|
|
||||||
movq %mm2, 0(%esp)
|
|
||||||
|
|
||||||
.globl rdc8mloop
|
|
||||||
rdc8mloop: // The main loop
|
|
||||||
movq %mm0, %mm2 // move 4-5 to temp reg
|
|
||||||
movzbl (%ebp, %edi), %edi // read 1
|
|
||||||
|
|
||||||
psrld $25, %mm2 // shift 4-5
|
|
||||||
movb (%edx,%eax), %cl // lookup 0
|
|
||||||
|
|
||||||
movl 0(%esp), %eax // load 2
|
|
||||||
addl $0x12345678, %ebx // counter
|
|
||||||
.globl rdc8mwidth2
|
|
||||||
rdc8mwidth2: // DeadBeef = 2*SCREENWIDTH
|
|
||||||
|
|
||||||
movb %cl, (%esi, %ebx) // write 0
|
|
||||||
movb (%edx,%edi), %ch // lookup 1
|
|
||||||
|
|
||||||
movb %ch, 0x12345678(%esi, %ebx) // write 1
|
|
||||||
.globl rdc8mwidth1
|
|
||||||
rdc8mwidth1: // DeadBeef = SCREENWIDTH
|
|
||||||
movl 4(%esp), %edi // load 3
|
|
||||||
|
|
||||||
paddd %mm1, %mm0 // frac 6-7
|
|
||||||
movzbl (%ebp, %eax), %eax // lookup 2
|
|
||||||
|
|
||||||
movq %mm2, 0(%esp) // store texture index 4-5
|
|
||||||
jl rdc8mloop
|
|
||||||
|
|
||||||
jnz rdc8mno_odd
|
|
||||||
movb (%edx,%eax), %cl // write the last odd pixel
|
|
||||||
movb %cl, 0x12345678(%esi)
|
|
||||||
.globl rdc8mwidth4
|
|
||||||
rdc8mwidth4: // DeadBeef = 2*SCREENWIDTH
|
|
||||||
rdc8mno_odd:
|
|
||||||
|
|
||||||
.globl rdc8mdone
|
|
||||||
rdc8mdone:
|
|
||||||
emms
|
|
||||||
|
|
||||||
addl _mmxcomm, %esp
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
popl %ebx
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
// Need some extra space to align run-time
|
|
||||||
.globl R_DrawColumn_8_K6_MMX_end
|
|
||||||
R_DrawColumn_8_K6_MMX_end:
|
|
||||||
nop;nop;nop;nop;nop;nop;nop;nop;
|
|
||||||
nop;nop;nop;nop;nop;nop;nop;nop;
|
|
||||||
nop;nop;nop;nop;nop;nop;nop;nop;
|
|
||||||
nop;nop;nop;nop;nop;nop;nop;
|
|
674
src/tmap_mmx.nas
674
src/tmap_mmx.nas
|
@ -1,674 +0,0 @@
|
||||||
;; SONIC ROBO BLAST 2
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; Copyright (C) 1998-2000 by DOSDOOM.
|
|
||||||
;; Copyright (C) 2010-2021 by Sonic Team Junior.
|
|
||||||
;;
|
|
||||||
;; This program is free software distributed under the
|
|
||||||
;; terms of the GNU General Public License, version 2.
|
|
||||||
;; See the 'LICENSE' file for more details.
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; FILE:
|
|
||||||
;; tmap_mmx.nas
|
|
||||||
;; DESCRIPTION:
|
|
||||||
;; Assembler optimised rendering code for software mode, using SIMD
|
|
||||||
;; instructions.
|
|
||||||
;; Draw wall columns.
|
|
||||||
|
|
||||||
|
|
||||||
[BITS 32]
|
|
||||||
|
|
||||||
%define FRACBITS 16
|
|
||||||
%define TRANSPARENTPIXEL 255
|
|
||||||
|
|
||||||
%ifdef LINUX
|
|
||||||
%macro cextern 1
|
|
||||||
[extern %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro cglobal 1
|
|
||||||
[global %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%else
|
|
||||||
%macro cextern 1
|
|
||||||
%define %1 _%1
|
|
||||||
[extern %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro cglobal 1
|
|
||||||
%define %1 _%1
|
|
||||||
[global %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
; The viddef_s structure. We only need the width field.
|
|
||||||
struc viddef_s
|
|
||||||
resb 12
|
|
||||||
.width: resb 4
|
|
||||||
resb 44
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
|
|
||||||
;; externs
|
|
||||||
;; columns
|
|
||||||
cextern dc_colormap
|
|
||||||
cextern dc_x
|
|
||||||
cextern dc_yl
|
|
||||||
cextern dc_yh
|
|
||||||
cextern dc_iscale
|
|
||||||
cextern dc_texturemid
|
|
||||||
cextern dc_texheight
|
|
||||||
cextern dc_source
|
|
||||||
cextern dc_hires
|
|
||||||
cextern centery
|
|
||||||
cextern centeryfrac
|
|
||||||
cextern dc_transmap
|
|
||||||
|
|
||||||
cextern R_DrawColumn_8_ASM
|
|
||||||
cextern R_Draw2sMultiPatchColumn_8_ASM
|
|
||||||
|
|
||||||
;; spans
|
|
||||||
cextern nflatshiftup
|
|
||||||
cextern nflatxshift
|
|
||||||
cextern nflatyshift
|
|
||||||
cextern nflatmask
|
|
||||||
cextern ds_xfrac
|
|
||||||
cextern ds_yfrac
|
|
||||||
cextern ds_xstep
|
|
||||||
cextern ds_ystep
|
|
||||||
cextern ds_x1
|
|
||||||
cextern ds_x2
|
|
||||||
cextern ds_y
|
|
||||||
cextern ds_source
|
|
||||||
cextern ds_colormap
|
|
||||||
|
|
||||||
cextern ylookup
|
|
||||||
cextern columnofs
|
|
||||||
cextern vid
|
|
||||||
|
|
||||||
[SECTION .data]
|
|
||||||
|
|
||||||
nflatmask64 dq 0
|
|
||||||
|
|
||||||
|
|
||||||
[SECTION .text]
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;;
|
|
||||||
;; R_DrawColumn : 8bpp column drawer
|
|
||||||
;;
|
|
||||||
;; MMX column drawer.
|
|
||||||
;;
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; eax = accumulator
|
|
||||||
;; ebx = colormap
|
|
||||||
;; ecx = count
|
|
||||||
;; edx = accumulator
|
|
||||||
;; esi = source
|
|
||||||
;; edi = dest
|
|
||||||
;; ebp = vid.width
|
|
||||||
;; mm0 = accumulator
|
|
||||||
;; mm1 = heightmask, twice
|
|
||||||
;; mm2 = 2 * fracstep, twice
|
|
||||||
;; mm3 = pair of consecutive fracs
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
cglobal R_DrawColumn_8_MMX
|
|
||||||
R_DrawColumn_8_MMX:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Our algorithm requires that the texture height be a power of two.
|
|
||||||
;; If not, fall back to the non-MMX drawer.
|
|
||||||
;;
|
|
||||||
.texheightcheck:
|
|
||||||
mov edx, [dc_texheight]
|
|
||||||
sub edx, 1 ;; edx = heightmask
|
|
||||||
test edx, [dc_texheight]
|
|
||||||
jnz near .usenonMMX
|
|
||||||
|
|
||||||
mov ebp, edx ;; Keep a copy of heightmask in a
|
|
||||||
;; GPR for the time being.
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Fill mm1 with heightmask
|
|
||||||
;;
|
|
||||||
movd mm1, edx ;; low dword = heightmask
|
|
||||||
punpckldq mm1, mm1 ;; copy low dword to high dword
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov eax, [dc_yl]
|
|
||||||
mov edi, [ylookup+eax*4]
|
|
||||||
mov ebx, [dc_x]
|
|
||||||
add edi, [columnofs+ebx*4] ;; edi = dest
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov ecx, [dc_yh]
|
|
||||||
add ecx, 1
|
|
||||||
sub ecx, eax ;; pixel count
|
|
||||||
jle near .done ;; nothing to scale
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; fracstep = dc_iscale;
|
|
||||||
;;
|
|
||||||
movd mm2, [dc_iscale] ;; fracstep in low dword
|
|
||||||
punpckldq mm2, mm2 ;; copy to high dword
|
|
||||||
|
|
||||||
mov ebx, [dc_colormap]
|
|
||||||
mov esi, [dc_source]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep));
|
|
||||||
;;
|
|
||||||
;; eax == dc_yl already
|
|
||||||
shl eax, FRACBITS
|
|
||||||
sub eax, [centeryfrac]
|
|
||||||
imul dword [dc_iscale]
|
|
||||||
shrd eax, edx, FRACBITS
|
|
||||||
add eax, [dc_texturemid]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; if (dc_hires) frac = 0;
|
|
||||||
;;
|
|
||||||
test byte [dc_hires], 0x01
|
|
||||||
jz .mod2
|
|
||||||
xor eax, eax
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Do mod-2 pixel.
|
|
||||||
;;
|
|
||||||
.mod2:
|
|
||||||
test ecx, 1
|
|
||||||
jz .pairprepare
|
|
||||||
mov edx, eax ;; edx = frac
|
|
||||||
add eax, [dc_iscale] ;; eax += fracstep
|
|
||||||
sar edx, FRACBITS
|
|
||||||
and edx, ebp ;; edx &= heightmask
|
|
||||||
movzx edx, byte [esi + edx]
|
|
||||||
movzx edx, byte [ebx + edx]
|
|
||||||
mov [edi], dl
|
|
||||||
|
|
||||||
add edi, [vid + viddef_s.width]
|
|
||||||
sub ecx, 1
|
|
||||||
jz .done
|
|
||||||
|
|
||||||
.pairprepare:
|
|
||||||
;;
|
|
||||||
;; Prepare for the main loop.
|
|
||||||
;;
|
|
||||||
movd mm3, eax ;; Low dword = frac
|
|
||||||
movq mm4, mm3 ;; Copy to intermediate register
|
|
||||||
paddd mm4, mm2 ;; dwords of mm4 += fracstep
|
|
||||||
punpckldq mm3, mm4 ;; Low dword = first frac, high = second
|
|
||||||
pslld mm2, 1 ;; fracstep *= 2
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ebp = vid.width
|
|
||||||
;;
|
|
||||||
mov ebp, [vid + viddef_s.width]
|
|
||||||
|
|
||||||
align 16
|
|
||||||
.pairloop:
|
|
||||||
movq mm0, mm3 ;; 3B 1u.
|
|
||||||
psrad mm0, FRACBITS ;; 4B 1u.
|
|
||||||
pand mm0, mm1 ;; 3B 1u. frac &= heightmask
|
|
||||||
paddd mm3, mm2 ;; 3B 1u. frac += fracstep
|
|
||||||
|
|
||||||
movd eax, mm0 ;; 3B 1u. Get first frac
|
|
||||||
;; IFETCH boundary
|
|
||||||
movzx eax, byte [esi + eax] ;; 4B 1u. Texture map
|
|
||||||
movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap
|
|
||||||
|
|
||||||
punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword
|
|
||||||
movd edx, mm0 ;; 3B 1u. Get second frac
|
|
||||||
mov [edi], al ;; 2B 1(2)u. First pixel
|
|
||||||
;; IFETCH boundary
|
|
||||||
|
|
||||||
movzx edx, byte [esi + edx] ;; 4B 1u. Texture map
|
|
||||||
movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap
|
|
||||||
mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel
|
|
||||||
|
|
||||||
lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width
|
|
||||||
;; IFETCH boundary
|
|
||||||
sub ecx, 2 ;; 3B 1u. count -= 2
|
|
||||||
jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop
|
|
||||||
|
|
||||||
|
|
||||||
.done:
|
|
||||||
;;
|
|
||||||
;; Clear MMX state, or else FPU operations will go badly awry.
|
|
||||||
;;
|
|
||||||
emms
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.usenonMMX:
|
|
||||||
call R_DrawColumn_8_ASM
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;;
|
|
||||||
;; R_Draw2sMultiPatchColumn : Like R_DrawColumn, but omits transparent
|
|
||||||
;; pixels.
|
|
||||||
;;
|
|
||||||
;; MMX column drawer.
|
|
||||||
;;
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; eax = accumulator
|
|
||||||
;; ebx = colormap
|
|
||||||
;; ecx = count
|
|
||||||
;; edx = accumulator
|
|
||||||
;; esi = source
|
|
||||||
;; edi = dest
|
|
||||||
;; ebp = vid.width
|
|
||||||
;; mm0 = accumulator
|
|
||||||
;; mm1 = heightmask, twice
|
|
||||||
;; mm2 = 2 * fracstep, twice
|
|
||||||
;; mm3 = pair of consecutive fracs
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
cglobal R_Draw2sMultiPatchColumn_8_MMX
|
|
||||||
R_Draw2sMultiPatchColumn_8_MMX:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Our algorithm requires that the texture height be a power of two.
|
|
||||||
;; If not, fall back to the non-MMX drawer.
|
|
||||||
;;
|
|
||||||
.texheightcheck:
|
|
||||||
mov edx, [dc_texheight]
|
|
||||||
sub edx, 1 ;; edx = heightmask
|
|
||||||
test edx, [dc_texheight]
|
|
||||||
jnz near .usenonMMX
|
|
||||||
|
|
||||||
mov ebp, edx ;; Keep a copy of heightmask in a
|
|
||||||
;; GPR for the time being.
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Fill mm1 with heightmask
|
|
||||||
;;
|
|
||||||
movd mm1, edx ;; low dword = heightmask
|
|
||||||
punpckldq mm1, mm1 ;; copy low dword to high dword
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; dest = ylookup[dc_yl] + columnofs[dc_x];
|
|
||||||
;;
|
|
||||||
mov eax, [dc_yl]
|
|
||||||
mov edi, [ylookup+eax*4]
|
|
||||||
mov ebx, [dc_x]
|
|
||||||
add edi, [columnofs+ebx*4] ;; edi = dest
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; pixelcount = yh - yl + 1
|
|
||||||
;;
|
|
||||||
mov ecx, [dc_yh]
|
|
||||||
add ecx, 1
|
|
||||||
sub ecx, eax ;; pixel count
|
|
||||||
jle near .done ;; nothing to scale
|
|
||||||
;;
|
|
||||||
;; fracstep = dc_iscale;
|
|
||||||
;;
|
|
||||||
movd mm2, [dc_iscale] ;; fracstep in low dword
|
|
||||||
punpckldq mm2, mm2 ;; copy to high dword
|
|
||||||
|
|
||||||
mov ebx, [dc_colormap]
|
|
||||||
mov esi, [dc_source]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep));
|
|
||||||
;;
|
|
||||||
;; eax == dc_yl already
|
|
||||||
shl eax, FRACBITS
|
|
||||||
sub eax, [centeryfrac]
|
|
||||||
imul dword [dc_iscale]
|
|
||||||
shrd eax, edx, FRACBITS
|
|
||||||
add eax, [dc_texturemid]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; if (dc_hires) frac = 0;
|
|
||||||
;;
|
|
||||||
test byte [dc_hires], 0x01
|
|
||||||
jz .mod2
|
|
||||||
xor eax, eax
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Do mod-2 pixel.
|
|
||||||
;;
|
|
||||||
.mod2:
|
|
||||||
test ecx, 1
|
|
||||||
jz .pairprepare
|
|
||||||
mov edx, eax ;; edx = frac
|
|
||||||
add eax, [dc_iscale] ;; eax += fracstep
|
|
||||||
sar edx, FRACBITS
|
|
||||||
and edx, ebp ;; edx &= heightmask
|
|
||||||
movzx edx, byte [esi + edx]
|
|
||||||
cmp dl, TRANSPARENTPIXEL
|
|
||||||
je .nextmod2
|
|
||||||
movzx edx, byte [ebx + edx]
|
|
||||||
mov [edi], dl
|
|
||||||
|
|
||||||
.nextmod2:
|
|
||||||
add edi, [vid + viddef_s.width]
|
|
||||||
sub ecx, 1
|
|
||||||
jz .done
|
|
||||||
|
|
||||||
.pairprepare:
|
|
||||||
;;
|
|
||||||
;; Prepare for the main loop.
|
|
||||||
;;
|
|
||||||
movd mm3, eax ;; Low dword = frac
|
|
||||||
movq mm4, mm3 ;; Copy to intermediate register
|
|
||||||
paddd mm4, mm2 ;; dwords of mm4 += fracstep
|
|
||||||
punpckldq mm3, mm4 ;; Low dword = first frac, high = second
|
|
||||||
pslld mm2, 1 ;; fracstep *= 2
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ebp = vid.width
|
|
||||||
;;
|
|
||||||
mov ebp, [vid + viddef_s.width]
|
|
||||||
|
|
||||||
align 16
|
|
||||||
.pairloop:
|
|
||||||
movq mm0, mm3 ;; 3B 1u.
|
|
||||||
psrad mm0, FRACBITS ;; 4B 1u.
|
|
||||||
pand mm0, mm1 ;; 3B 1u. frac &= heightmask
|
|
||||||
paddd mm3, mm2 ;; 3B 1u. frac += fracstep
|
|
||||||
|
|
||||||
movd eax, mm0 ;; 3B 1u. Get first frac
|
|
||||||
;; IFETCH boundary
|
|
||||||
movzx eax, byte [esi + eax] ;; 4B 1u. Texture map
|
|
||||||
punpckhdq mm0, mm0 ;; 3B 1(2)u. low dword = high dword
|
|
||||||
movd edx, mm0 ;; 3B 1u. Get second frac
|
|
||||||
cmp al, TRANSPARENTPIXEL ;; 2B 1u.
|
|
||||||
je .secondinpair ;; 2B 1u.
|
|
||||||
;; IFETCH boundary
|
|
||||||
movzx eax, byte [ebx + eax] ;; 4B 1u. Colormap
|
|
||||||
mov [edi], al ;; 2B 1(2)u. First pixel
|
|
||||||
|
|
||||||
.secondinpair:
|
|
||||||
movzx edx, byte [esi + edx] ;; 4B 1u. Texture map
|
|
||||||
cmp dl, TRANSPARENTPIXEL ;; 2B 1u.
|
|
||||||
je .nextpair ;; 2B 1u.
|
|
||||||
;; IFETCH boundary
|
|
||||||
movzx edx, byte [ebx + edx] ;; 4B 1u. Colormap
|
|
||||||
mov [edi + 1*ebp], dl ;; 3B 1(2)u. Second pixel
|
|
||||||
|
|
||||||
.nextpair:
|
|
||||||
lea edi, [edi + 2*ebp] ;; 3B 1u. edi += 2 * vid.width
|
|
||||||
sub ecx, 2 ;; 3B 1u. count -= 2
|
|
||||||
jnz .pairloop ;; 2B 1u. if(count != 0) goto .pairloop
|
|
||||||
|
|
||||||
|
|
||||||
.done:
|
|
||||||
;;
|
|
||||||
;; Clear MMX state, or else FPU operations will go badly awry.
|
|
||||||
;;
|
|
||||||
emms
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.usenonMMX:
|
|
||||||
call R_Draw2sMultiPatchColumn_8_ASM
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;;
|
|
||||||
;; R_DrawSpan : 8bpp span drawer
|
|
||||||
;;
|
|
||||||
;; MMX span drawer.
|
|
||||||
;;
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
;; eax = accumulator
|
|
||||||
;; ebx = colormap
|
|
||||||
;; ecx = count
|
|
||||||
;; edx = accumulator
|
|
||||||
;; esi = source
|
|
||||||
;; edi = dest
|
|
||||||
;; ebp = two pixels
|
|
||||||
;; mm0 = accumulator
|
|
||||||
;; mm1 = xposition
|
|
||||||
;; mm2 = yposition
|
|
||||||
;; mm3 = 2 * xstep
|
|
||||||
;; mm4 = 2 * ystep
|
|
||||||
;; mm5 = nflatxshift
|
|
||||||
;; mm6 = nflatyshift
|
|
||||||
;; mm7 = accumulator
|
|
||||||
;;----------------------------------------------------------------------
|
|
||||||
|
|
||||||
cglobal R_DrawSpan_8_MMX
|
|
||||||
R_DrawSpan_8_MMX:
|
|
||||||
push ebp ;; preserve caller's stack frame pointer
|
|
||||||
push esi ;; preserve register variables
|
|
||||||
push edi
|
|
||||||
push ebx
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; esi = ds_source
|
|
||||||
;; ebx = ds_colormap
|
|
||||||
;;
|
|
||||||
mov esi, [ds_source]
|
|
||||||
mov ebx, [ds_colormap]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; edi = ylookup[ds_y] + columnofs[ds_x1]
|
|
||||||
;;
|
|
||||||
mov eax, [ds_y]
|
|
||||||
mov edi, [ylookup + eax*4]
|
|
||||||
mov edx, [ds_x1]
|
|
||||||
add edi, [columnofs + edx*4]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ecx = ds_x2 - ds_x1 + 1
|
|
||||||
;;
|
|
||||||
mov ecx, [ds_x2]
|
|
||||||
sub ecx, edx
|
|
||||||
add ecx, 1
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Needed for fracs and steps
|
|
||||||
;;
|
|
||||||
movd mm7, [nflatshiftup]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; mm3 = xstep
|
|
||||||
;;
|
|
||||||
movd mm3, [ds_xstep]
|
|
||||||
pslld mm3, mm7
|
|
||||||
punpckldq mm3, mm3
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; mm4 = ystep
|
|
||||||
;;
|
|
||||||
movd mm4, [ds_ystep]
|
|
||||||
pslld mm4, mm7
|
|
||||||
punpckldq mm4, mm4
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; mm1 = pair of consecutive xpositions
|
|
||||||
;;
|
|
||||||
movd mm1, [ds_xfrac]
|
|
||||||
pslld mm1, mm7
|
|
||||||
movq mm6, mm1
|
|
||||||
paddd mm6, mm3
|
|
||||||
punpckldq mm1, mm6
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; mm2 = pair of consecutive ypositions
|
|
||||||
;;
|
|
||||||
movd mm2, [ds_yfrac]
|
|
||||||
pslld mm2, mm7
|
|
||||||
movq mm6, mm2
|
|
||||||
paddd mm6, mm4
|
|
||||||
punpckldq mm2, mm6
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; mm5 = nflatxshift
|
|
||||||
;; mm6 = nflatyshift
|
|
||||||
;;
|
|
||||||
movd mm5, [nflatxshift]
|
|
||||||
movd mm6, [nflatyshift]
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Mask is in memory due to lack of registers.
|
|
||||||
;;
|
|
||||||
mov eax, [nflatmask]
|
|
||||||
mov [nflatmask64], eax
|
|
||||||
mov [nflatmask64 + 4], eax
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Go until we reach a dword boundary.
|
|
||||||
;;
|
|
||||||
.unaligned:
|
|
||||||
test edi, 3
|
|
||||||
jz .alignedprep
|
|
||||||
.stragglers:
|
|
||||||
cmp ecx, 0
|
|
||||||
je .done ;; If ecx == 0, we're finished.
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; eax = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)
|
|
||||||
;;
|
|
||||||
movq mm0, mm1 ;; mm0 = xposition
|
|
||||||
movq mm7, mm2 ;; mm7 = yposition
|
|
||||||
paddd mm1, mm3 ;; xposition += xstep (once!)
|
|
||||||
paddd mm2, mm4 ;; yposition += ystep (once!)
|
|
||||||
psrld mm0, mm5 ;; shift
|
|
||||||
psrld mm7, mm6 ;; shift
|
|
||||||
pand mm7, [nflatmask64] ;; mask
|
|
||||||
por mm0, mm7 ;; or x and y together
|
|
||||||
|
|
||||||
movd eax, mm0 ;; eax = index of first pixel
|
|
||||||
movzx eax, byte [esi + eax] ;; al = source[eax]
|
|
||||||
movzx eax, byte [ebx + eax] ;; al = colormap[al]
|
|
||||||
|
|
||||||
mov [edi], al
|
|
||||||
add edi, 1
|
|
||||||
|
|
||||||
sub ecx, 1
|
|
||||||
jmp .unaligned
|
|
||||||
|
|
||||||
|
|
||||||
.alignedprep:
|
|
||||||
;;
|
|
||||||
;; We can double the steps now.
|
|
||||||
;;
|
|
||||||
pslld mm3, 1
|
|
||||||
pslld mm4, 1
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Generate chunks of four pixels.
|
|
||||||
;;
|
|
||||||
.alignedloop:
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Make sure we have at least four pixels.
|
|
||||||
;;
|
|
||||||
cmp ecx, 4
|
|
||||||
jl .prestragglers
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; First two pixels.
|
|
||||||
;;
|
|
||||||
movq mm0, mm1 ;; mm0 = xposition
|
|
||||||
movq mm7, mm2 ;; mm7 = yposition
|
|
||||||
paddd mm1, mm3 ;; xposition += xstep
|
|
||||||
paddd mm2, mm4 ;; yposition += ystep
|
|
||||||
psrld mm0, mm5 ;; shift
|
|
||||||
psrld mm7, mm6 ;; shift
|
|
||||||
pand mm7, [nflatmask64] ;; mask
|
|
||||||
por mm0, mm7 ;; or x and y together
|
|
||||||
|
|
||||||
movd eax, mm0 ;; eax = index of first pixel
|
|
||||||
movzx eax, byte [esi + eax] ;; al = source[eax]
|
|
||||||
movzx ebp, byte [ebx + eax] ;; ebp = colormap[al]
|
|
||||||
|
|
||||||
punpckhdq mm0, mm0 ;; both dwords = high dword
|
|
||||||
movd eax, mm0 ;; eax = index of second pixel
|
|
||||||
movzx eax, byte [esi + eax] ;; al = source[eax]
|
|
||||||
movzx eax, byte [ebx + eax] ;; al = colormap[al]
|
|
||||||
shl eax, 8 ;; get pixel in right byte
|
|
||||||
or ebp, eax ;; put pixel in ebp
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Next two pixels.
|
|
||||||
;;
|
|
||||||
movq mm0, mm1 ;; mm0 = xposition
|
|
||||||
movq mm7, mm2 ;; mm7 = yposition
|
|
||||||
paddd mm1, mm3 ;; xposition += xstep
|
|
||||||
paddd mm2, mm4 ;; yposition += ystep
|
|
||||||
psrld mm0, mm5 ;; shift
|
|
||||||
psrld mm7, mm6 ;; shift
|
|
||||||
pand mm7, [nflatmask64] ;; mask
|
|
||||||
por mm0, mm7 ;; or x and y together
|
|
||||||
|
|
||||||
movd eax, mm0 ;; eax = index of third pixel
|
|
||||||
movzx eax, byte [esi + eax] ;; al = source[eax]
|
|
||||||
movzx eax, byte [ebx + eax] ;; al = colormap[al]
|
|
||||||
shl eax, 16 ;; get pixel in right byte
|
|
||||||
or ebp, eax ;; put pixel in ebp
|
|
||||||
|
|
||||||
punpckhdq mm0, mm0 ;; both dwords = high dword
|
|
||||||
movd eax, mm0 ;; eax = index of second pixel
|
|
||||||
movzx eax, byte [esi + eax] ;; al = source[eax]
|
|
||||||
movzx eax, byte [ebx + eax] ;; al = colormap[al]
|
|
||||||
shl eax, 24 ;; get pixel in right byte
|
|
||||||
or ebp, eax ;; put pixel in ebp
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Write pixels.
|
|
||||||
;;
|
|
||||||
mov [edi], ebp
|
|
||||||
add edi, 4
|
|
||||||
|
|
||||||
sub ecx, 4
|
|
||||||
jmp .alignedloop
|
|
||||||
|
|
||||||
.prestragglers:
|
|
||||||
;;
|
|
||||||
;; Back to one step at a time.
|
|
||||||
;;
|
|
||||||
psrad mm3, 1
|
|
||||||
psrad mm4, 1
|
|
||||||
jmp .stragglers
|
|
||||||
|
|
||||||
.done:
|
|
||||||
;;
|
|
||||||
;; Clear MMX state, or else FPU operations will go badly awry.
|
|
||||||
;;
|
|
||||||
emms
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
|
@ -1,48 +0,0 @@
|
||||||
;; SONIC ROBO BLAST 2
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; Copyright (C) 1998-2000 by DooM Legacy Team.
|
|
||||||
;; Copyright (C) 1999-2021 by Sonic Team Junior.
|
|
||||||
;;
|
|
||||||
;; This program is free software distributed under the
|
|
||||||
;; terms of the GNU General Public License, version 2.
|
|
||||||
;; See the 'LICENSE' file for more details.
|
|
||||||
;;-----------------------------------------------------------------------------
|
|
||||||
;; FILE:
|
|
||||||
;; tmap_vc.nas
|
|
||||||
;; DESCRIPTION:
|
|
||||||
;; Assembler optimised math code for Visual C++.
|
|
||||||
|
|
||||||
|
|
||||||
[BITS 32]
|
|
||||||
|
|
||||||
%macro cglobal 1
|
|
||||||
%define %1 _%1
|
|
||||||
[global %1]
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
[SECTION .text write]
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
;fixed_t FixedMul (fixed_t a, fixed_t b)
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
cglobal FixedMul
|
|
||||||
; align 16
|
|
||||||
FixedMul:
|
|
||||||
mov eax,[esp+4]
|
|
||||||
imul dword [esp+8]
|
|
||||||
shrd eax,edx,16
|
|
||||||
ret
|
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
;fixed_t FixedDiv2 (fixed_t a, fixed_t b);
|
|
||||||
;----------------------------------------------------------------------------
|
|
||||||
cglobal FixedDiv2
|
|
||||||
; align 16
|
|
||||||
FixedDiv2:
|
|
||||||
mov eax,[esp+4]
|
|
||||||
mov edx,eax ;; these two instructions allow the next
|
|
||||||
sar edx,31 ;; two to pair, on the Pentium processor.
|
|
||||||
shld edx,eax,16
|
|
||||||
sal eax,16
|
|
||||||
idiv dword [esp+8]
|
|
||||||
ret
|
|
60
src/w_wad.c
60
src/w_wad.c
|
@ -82,6 +82,14 @@
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static I_mutex wad_mutex;
|
||||||
|
# define Lock_state() I_lock_mutex(&wad_mutex)
|
||||||
|
# define Unlock_state() I_unlock_mutex(wad_mutex)
|
||||||
|
#else
|
||||||
|
# define Lock_state()
|
||||||
|
# define Unlock_state()
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -1922,6 +1930,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
if (!TestValidLump(wad,lump))
|
if (!TestValidLump(wad,lump))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
lumpcache = wadfiles[wad]->lumpcache;
|
lumpcache = wadfiles[wad]->lumpcache;
|
||||||
if (!lumpcache[lump])
|
if (!lumpcache[lump])
|
||||||
{
|
{
|
||||||
|
@ -1931,6 +1941,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
else
|
else
|
||||||
Z_ChangeTag(lumpcache[lump], tag);
|
Z_ChangeTag(lumpcache[lump], tag);
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return lumpcache[lump];
|
return lumpcache[lump];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1955,9 +1967,13 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag)
|
||||||
if (!TestValidLump(wad,lump))
|
if (!TestValidLump(wad,lump))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, NULL);
|
ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, NULL);
|
||||||
W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full
|
W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1975,15 +1991,23 @@ static inline boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
||||||
if (!TestValidLump(wad, lump))
|
if (!TestValidLump(wad, lump))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
lcache = wadfiles[wad]->lumpcache[lump];
|
lcache = wadfiles[wad]->lumpcache[lump];
|
||||||
|
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
if (ptr == lcache)
|
if (ptr == lcache) {
|
||||||
|
Unlock_state();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (lcache)
|
}
|
||||||
|
else if (lcache) {
|
||||||
|
Unlock_state();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2007,15 +2031,23 @@ static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
||||||
if (!TestValidLump(wad, lump))
|
if (!TestValidLump(wad, lump))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
lcache = wadfiles[wad]->patchcache[lump];
|
lcache = wadfiles[wad]->patchcache[lump];
|
||||||
|
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
if (ptr == lcache)
|
if (ptr == lcache) {
|
||||||
|
Unlock_state();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (lcache)
|
}
|
||||||
|
else if (lcache) {
|
||||||
|
Unlock_state();
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2048,7 +2080,7 @@ void *W_CacheLumpName(const char *name, INT32 tag)
|
||||||
// Cache a patch into heap memory, convert the patch format as necessary
|
// Cache a patch into heap memory, convert the patch format as necessary
|
||||||
//
|
//
|
||||||
|
|
||||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
static void *W_CacheSoftwarePatch(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
{
|
{
|
||||||
lumpcache_t *lumpcache = NULL;
|
lumpcache_t *lumpcache = NULL;
|
||||||
|
|
||||||
|
@ -2082,11 +2114,6 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
return lumpcache[lump];
|
return lumpcache[lump];
|
||||||
}
|
}
|
||||||
|
|
||||||
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
|
|
||||||
{
|
|
||||||
return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
{
|
{
|
||||||
patch_t *patch;
|
patch_t *patch;
|
||||||
|
@ -2094,16 +2121,23 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||||
if (!TestValidLump(wad, lump))
|
if (!TestValidLump(wad, lump))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
patch = W_CacheSoftwarePatchNumPwad(wad, lump, tag);
|
Lock_state();
|
||||||
|
|
||||||
|
patch = W_CacheSoftwarePatch(wad, lump, tag);
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
// Software-only compile cache the data without conversion
|
// Software-only compile cache the data without conversion
|
||||||
if (rendermode == render_soft || rendermode == render_none)
|
if (rendermode == render_soft || rendermode == render_none)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
Unlock_state();
|
||||||
return (void *)patch;
|
return (void *)patch;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
Patch_CreateGL(patch);
|
Patch_CreateGL(patch);
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return (void *)patch;
|
return (void *)patch;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2118,6 +2152,8 @@ void W_UnlockCachedPatch(void *patch)
|
||||||
if (!patch)
|
if (!patch)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
// The hardware code does its own memory management, as its patches
|
// The hardware code does its own memory management, as its patches
|
||||||
// have different lifetimes from software's.
|
// have different lifetimes from software's.
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
@ -2126,6 +2162,8 @@ void W_UnlockCachedPatch(void *patch)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
Z_Unlock(patch);
|
Z_Unlock(patch);
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *W_CachePatchName(const char *name, INT32 tag)
|
void *W_CachePatchName(const char *name, INT32 tag)
|
||||||
|
|
|
@ -207,11 +207,6 @@ void *W_CachePatchLongName(const char *name, INT32 tag);
|
||||||
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
|
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
|
||||||
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
|
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
|
||||||
|
|
||||||
// Returns a Software patch.
|
|
||||||
// Performs any necessary conversions from PNG images.
|
|
||||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
|
|
||||||
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag);
|
|
||||||
|
|
||||||
void W_UnlockCachedPatch(void *patch);
|
void W_UnlockCachedPatch(void *patch);
|
||||||
|
|
||||||
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
|
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
|
||||||
|
|
26
src/z_zone.c
26
src/z_zone.c
|
@ -39,6 +39,15 @@
|
||||||
#include "hardware/hw_main.h" // For hardware memory info
|
#include "hardware/hw_main.h" // For hardware memory info
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static I_mutex Z_mutex;
|
||||||
|
# define Lock_state() I_lock_mutex(&Z_mutex)
|
||||||
|
# define Unlock_state() I_unlock_mutex(Z_mutex)
|
||||||
|
#else
|
||||||
|
# define Lock_state()
|
||||||
|
# define Unlock_state()
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_VALGRIND
|
#ifdef HAVE_VALGRIND
|
||||||
#include "valgrind.h"
|
#include "valgrind.h"
|
||||||
static boolean Z_calloc = false;
|
static boolean Z_calloc = false;
|
||||||
|
@ -203,6 +212,8 @@ void Z_Free(void *ptr)
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
#ifdef ZDEBUG2
|
#ifdef ZDEBUG2
|
||||||
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
|
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
|
||||||
#endif
|
#endif
|
||||||
|
@ -237,6 +248,8 @@ void Z_Free(void *ptr)
|
||||||
block->prev->next = block->next;
|
block->prev->next = block->next;
|
||||||
block->next->prev = block->prev;
|
block->next->prev = block->prev;
|
||||||
free(block);
|
free(block);
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** malloc() that doesn't accept failure.
|
/** malloc() that doesn't accept failure.
|
||||||
|
@ -295,6 +308,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
||||||
void *given;
|
void *given;
|
||||||
size_t blocksize = extrabytes + sizeof *hdr + size;
|
size_t blocksize = extrabytes + sizeof *hdr + size;
|
||||||
|
|
||||||
|
Lock_state();
|
||||||
|
|
||||||
#ifdef ZDEBUG2
|
#ifdef ZDEBUG2
|
||||||
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
||||||
#endif
|
#endif
|
||||||
|
@ -359,6 +374,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
||||||
I_Error("Z_Malloc: attempted to allocate purgable block "
|
I_Error("Z_Malloc: attempted to allocate purgable block "
|
||||||
"(size %s) with no user", sizeu1(size));
|
"(size %s) with no user", sizeu1(size));
|
||||||
|
|
||||||
|
Unlock_state();
|
||||||
|
|
||||||
return given;
|
return given;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,14 +398,19 @@ void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char
|
||||||
void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
void *mem;
|
||||||
|
Lock_state();
|
||||||
#ifdef VALGRIND_MEMPOOL_ALLOC
|
#ifdef VALGRIND_MEMPOOL_ALLOC
|
||||||
Z_calloc = true;
|
Z_calloc = true;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ZDEBUG
|
#ifdef ZDEBUG
|
||||||
return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size);
|
mem = Z_Malloc2 (size, tag, user, alignbits, file, line);
|
||||||
#else
|
#else
|
||||||
return memset(Z_MallocAlign(size, tag, user, alignbits ), 0, size);
|
mem = Z_MallocAlign(size, tag, user, alignbits );
|
||||||
#endif
|
#endif
|
||||||
|
memset(mem, 0, size);
|
||||||
|
Unlock_state();
|
||||||
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The Z_ReallocAlign function.
|
/** The Z_ReallocAlign function.
|
||||||
|
|
Loading…
Reference in a new issue