mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-24 13:21:20 +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_NASM_SOURCES tmap_mmx.nas tmap.nas)
|
||||
|
||||
### Configuration
|
||||
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.")
|
||||
|
@ -213,8 +211,7 @@ if(${SRB2_CONFIG_USEASM})
|
|||
target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse")
|
||||
|
||||
target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES}
|
||||
${SRB2_NASM_SOURCES})
|
||||
target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES})
|
||||
else()
|
||||
set(SRB2_USEASM OFF)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM)
|
||||
|
|
|
@ -210,7 +210,7 @@ sources+=\
|
|||
$(call List,blua/Sourcefile)\
|
||||
|
||||
depends:=$(basename $(filter %.c %.s,$(sources)))
|
||||
objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
|
||||
objects:=$(basename $(filter %.c %.s,$(sources)))
|
||||
|
||||
depends:=$(depends:%=$(depdir)/%.d)
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ endif
|
|||
|
||||
ifndef NOASM
|
||||
ifndef NONX86
|
||||
sources+=tmap.nas tmap_mmx.nas
|
||||
opts+=-DUSEASM
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -511,8 +511,10 @@ static void D_Display(void)
|
|||
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
|
||||
}
|
||||
}
|
||||
ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime;
|
||||
|
||||
// Image postprocessing effect
|
||||
ps_postprocesstime = I_GetPreciseTime();
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (!splitscreen)
|
||||
|
@ -523,7 +525,7 @@ static void D_Display(void)
|
|||
if (postimgtype2)
|
||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||
}
|
||||
ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime;
|
||||
ps_postprocesstime = I_GetPreciseTime() - ps_postprocesstime;
|
||||
}
|
||||
|
||||
if (lastdraw)
|
||||
|
|
|
@ -537,6 +537,9 @@ INT32 I_GetKey(void);
|
|||
// Max gamepad/joysticks that can be detected/used.
|
||||
#define MAX_JOYSTICKS 4
|
||||
|
||||
// Software multithreading
|
||||
#define MAX_RENDER_THREADS 8
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
@ -608,13 +611,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
|
||||
//#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
|
||||
#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_DrawViewBorder(INT32 clearlines);
|
||||
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
|
||||
void HWR_InitTextureMapping(void);
|
||||
void HWR_SetViewSize(void);
|
||||
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);
|
||||
|
|
|
@ -15,6 +15,17 @@
|
|||
#define I_THREADS_H
|
||||
|
||||
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_cond;
|
||||
|
@ -22,7 +33,7 @@ typedef void * I_cond;
|
|||
void I_start_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 */
|
||||
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_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/*HAVE_THREADS*/
|
||||
|
|
|
@ -100,7 +100,30 @@ enum {
|
|||
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();
|
||||
|
||||
|
@ -122,15 +145,19 @@ static void M_DrawPerfString(perfstatcol_t *col, int type)
|
|||
|
||||
if (hires)
|
||||
{
|
||||
V_DrawSmallString(col->hires_x, draw_row, draw_flags,
|
||||
va("%s %d", row->hires_label, value));
|
||||
const char *string = 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(col->lores_x, draw_row, draw_flags,
|
||||
va("%s %d", row->lores_label, value));
|
||||
const char *string = 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;
|
||||
}
|
||||
|
@ -139,12 +166,12 @@ static void M_DrawPerfString(perfstatcol_t *col, int type)
|
|||
|
||||
static void M_DrawPerfTiming(perfstatcol_t *col)
|
||||
{
|
||||
M_DrawPerfString(col, PERF_TIME);
|
||||
M_DrawPerfMeasurement(col, PERF_TIME);
|
||||
}
|
||||
|
||||
static void M_DrawPerfCount(perfstatcol_t *col)
|
||||
{
|
||||
M_DrawPerfString(col, PERF_COUNT);
|
||||
M_DrawPerfMeasurement(col, PERF_COUNT);
|
||||
}
|
||||
|
||||
static void M_DrawRenderStats(void)
|
||||
|
@ -161,7 +188,7 @@ static void M_DrawRenderStats(void)
|
|||
};
|
||||
|
||||
perfstatrow_t rendercalltime_row[] = {
|
||||
{"drwtime", "3d rendering: ", &ps_rendercalltime},
|
||||
{"drwtime", "3D rendering: ", &ps_rendercalltime},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -176,16 +203,6 @@ static void M_DrawRenderStats(void)
|
|||
{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[] = {
|
||||
{"ui ", "UI render: ", &ps_uitime},
|
||||
{"finupdt", "I_FinishUpdate:", &ps_swaptime},
|
||||
|
@ -197,14 +214,6 @@ static void M_DrawRenderStats(void)
|
|||
{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[] = {
|
||||
{"batsort", "Batch sort: ", &ps_hw_batchsorttime},
|
||||
{"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 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 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 batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row};
|
||||
|
@ -256,12 +262,13 @@ static void M_DrawRenderStats(void)
|
|||
M_DrawPerfTiming(&rendercalltime_col);
|
||||
|
||||
// Remember to update this calculation when adding more 3d rendering stats!
|
||||
extrarendertime = ps_rendercalltime - ps_bsptime;
|
||||
extrarendertime = ps_rendercalltime;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
extrarendertime -=
|
||||
extrarendertime =
|
||||
ps_bsptime[0] +
|
||||
ps_hw_skyboxtime +
|
||||
ps_hw_nodesorttime +
|
||||
ps_hw_nodedrawtime +
|
||||
|
@ -280,14 +287,33 @@ static void M_DrawRenderStats(void)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
extrarendertime -=
|
||||
ps_sw_spritecliptime +
|
||||
ps_sw_portaltime +
|
||||
ps_sw_planetime +
|
||||
ps_sw_maskedtime;
|
||||
INT32 i = 0;
|
||||
|
||||
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(&other_col);
|
||||
}
|
||||
}
|
||||
|
||||
M_DrawPerfTiming(&uiswaptime_col);
|
||||
|
@ -298,7 +324,40 @@ static void M_DrawRenderStats(void)
|
|||
if (rendering)
|
||||
{
|
||||
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);
|
||||
} 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
|
||||
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 "taglist.h"
|
||||
|
||||
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 = 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;
|
||||
#ifdef HAVE_THREADS
|
||||
static I_mutex R_BSP_mutex;
|
||||
# define Lock_state() I_lock_mutex(&R_BSP_mutex)
|
||||
# define Unlock_state() I_unlock_mutex(R_BSP_mutex)
|
||||
#else
|
||||
# define Lock_state()
|
||||
# define Unlock_state()
|
||||
#endif
|
||||
|
||||
//
|
||||
// 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
|
||||
// Does handle solid walls,
|
||||
// e.g. single sided LineDefs (middle texture)
|
||||
// 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 *start;
|
||||
|
||||
// Find the first range that touches the range (adjacent pixels are touching).
|
||||
start = solidsegs;
|
||||
start = bspcontext->solidsegs;
|
||||
while (start->last < first - 1)
|
||||
start++;
|
||||
|
||||
|
@ -75,11 +62,11 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
if (last < start->first - 1)
|
||||
{
|
||||
// Post is entirely visible (above start), so insert a new clippost.
|
||||
R_StoreWallRange(first, last);
|
||||
next = newend;
|
||||
newend++;
|
||||
R_StoreWallRange(context, wallcontext, first, last);
|
||||
next = bspcontext->newend;
|
||||
bspcontext->newend++;
|
||||
// NO MORE CRASHING!
|
||||
if (newend - solidsegs > MAXSEGS)
|
||||
if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS)
|
||||
I_Error("R_ClipSolidWallSegment: Solid Segs overflow!\n");
|
||||
|
||||
while (next != start)
|
||||
|
@ -93,7 +80,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
}
|
||||
|
||||
// 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.
|
||||
start->first = first;
|
||||
}
|
||||
|
@ -106,7 +93,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
while (last >= (next+1)->first - 1)
|
||||
{
|
||||
// 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++;
|
||||
|
||||
if (last <= next->last)
|
||||
|
@ -119,7 +106,7 @@ static void R_ClipSolidWallSegment(INT32 first, INT32 last)
|
|||
}
|
||||
|
||||
// There is a fragment after *next.
|
||||
R_StoreWallRange(next->last + 1, last);
|
||||
R_StoreWallRange(context, wallcontext, next->last + 1, last);
|
||||
// Adjust the clip size.
|
||||
start->last = last;
|
||||
|
||||
|
@ -128,13 +115,13 @@ crunch:
|
|||
if (next == start)
|
||||
return; // Post just extended past the bottom of one post.
|
||||
|
||||
while (next++ != newend)
|
||||
while (next++ != bspcontext->newend)
|
||||
*++start = *next; // Remove a post.
|
||||
|
||||
newend = start + 1;
|
||||
bspcontext->newend = start + 1;
|
||||
|
||||
// NO MORE CRASHING!
|
||||
if (newend - solidsegs > MAXSEGS)
|
||||
if (bspcontext->newend - bspcontext->solidsegs > MAXSEGS)
|
||||
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.
|
||||
// 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;
|
||||
|
||||
// Find the first range that touches the range
|
||||
// (adjacent pixels are touching).
|
||||
start = solidsegs;
|
||||
start = context->bspcontext.solidsegs;
|
||||
while (start->last < first - 1)
|
||||
start++;
|
||||
|
||||
|
@ -158,12 +145,12 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
|||
if (last < start->first - 1)
|
||||
{
|
||||
// Post is entirely visible (above start).
|
||||
R_StoreWallRange(first, last);
|
||||
R_StoreWallRange(context, wallcontext, first, last);
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a fragment above *start.
|
||||
R_StoreWallRange(first, start->first - 1);
|
||||
R_StoreWallRange(context, wallcontext, first, start->first - 1);
|
||||
}
|
||||
|
||||
// Bottom contained in start?
|
||||
|
@ -173,7 +160,7 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
|||
while (last >= (start+1)->first - 1)
|
||||
{
|
||||
// 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++;
|
||||
|
||||
if (last <= start->last)
|
||||
|
@ -181,27 +168,19 @@ static inline void R_ClipPassWallSegment(INT32 first, INT32 last)
|
|||
}
|
||||
|
||||
// There is a fragment after *next.
|
||||
R_StoreWallRange(start->last + 1, last);
|
||||
R_StoreWallRange(context, wallcontext, start->last + 1, last);
|
||||
}
|
||||
|
||||
//
|
||||
// R_ClearClipSegs
|
||||
//
|
||||
void R_ClearClipSegs(void)
|
||||
void R_ClearClipSegs(bspcontext_t *context, INT32 start, INT32 end)
|
||||
{
|
||||
solidsegs[0].first = -0x7fffffff;
|
||||
solidsegs[0].last = -1;
|
||||
solidsegs[1].first = viewwidth;
|
||||
solidsegs[1].last = 0x7fffffff;
|
||||
newend = 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;
|
||||
context->solidsegs[0].first = -0x7fffffff;
|
||||
context->solidsegs[0].last = start-1;
|
||||
context->solidsegs[1].first = end;
|
||||
context->solidsegs[1].last = 0x7fffffff;
|
||||
context->newend = context->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
|
||||
// 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
|
||||
|
||||
// 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:
|
||||
&& (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.
|
||||
//
|
||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||
INT32 *ceilinglightlevel, boolean back)
|
||||
sector_t *R_FakeFlat(viewcontext_t *viewcontext, sector_t *sec, sector_t *tempsec,
|
||||
INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back)
|
||||
{
|
||||
if (floorlightlevel)
|
||||
*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)
|
||||
{
|
||||
const sector_t *s = §ors[sec->heightsec];
|
||||
mobj_t *viewmobj = viewplayer->mo;
|
||||
mobj_t *viewmobj = viewcontext->player->mo;
|
||||
INT32 heightsec;
|
||||
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;
|
||||
else if (camera.chase && viewplayer == &players[displayplayer])
|
||||
else if (camera.chase && viewcontext->player == &players[displayplayer])
|
||||
heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec;
|
||||
else if (viewmobj)
|
||||
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
|
||||
else
|
||||
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
|
||||
*tempsec = *sec;
|
||||
|
@ -272,7 +251,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->ceilingheight = s->ceilingheight;
|
||||
|
||||
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
|
||||
tempsec->floorpic = s->floorpic;
|
||||
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
|
||||
: 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)
|
||||
{ // Above-ceiling hack
|
||||
tempsec->ceilingheight = s->ceilingheight;
|
||||
|
@ -382,22 +361,25 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
|
|||
// R_AddLine
|
||||
// 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;
|
||||
angle_t angle1, angle2, span, tspan;
|
||||
static sector_t tempsec;
|
||||
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))
|
||||
return;
|
||||
|
||||
// big room fix
|
||||
angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
|
||||
curline = line;
|
||||
angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, line->v2->x, line->v2->y);
|
||||
bspcontext->curline = line;
|
||||
|
||||
// Clip to view edges.
|
||||
span = angle1 - angle2;
|
||||
|
@ -407,9 +389,9 @@ static void R_AddLine(seg_t *line)
|
|||
return;
|
||||
|
||||
// Global angle needed by segcalc.
|
||||
rw_angle1 = angle1;
|
||||
angle1 -= viewangle;
|
||||
angle2 -= viewangle;
|
||||
wallcontext.angle1 = angle1;
|
||||
angle1 -= viewcontext->angle;
|
||||
angle2 -= viewcontext->angle;
|
||||
|
||||
tspan = angle1 + clipangle;
|
||||
if (tspan > doubleclipangle)
|
||||
|
@ -440,18 +422,21 @@ static void R_AddLine(seg_t *line)
|
|||
x1 = viewangletox[angle1];
|
||||
x2 = viewangletox[angle2];
|
||||
|
||||
x1 = max(rendercontext->begincolumn, x1);
|
||||
x2 = min(rendercontext->endcolumn, x2);
|
||||
|
||||
// Does not cross a pixel?
|
||||
if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness
|
||||
return;
|
||||
|
||||
backsector = line->backsector;
|
||||
bspcontext->backsector = line->backsector;
|
||||
|
||||
// Portal line
|
||||
if (line->linedef->special == 40 && line->side == 0)
|
||||
{
|
||||
// Render portal if recursiveness limit hasn't been reached.
|
||||
// Otherwise, render the wall normally.
|
||||
if (portalrender < cv_maxportals.value)
|
||||
if (bspcontext->portalrender < cv_maxportals.value)
|
||||
{
|
||||
size_t p;
|
||||
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))
|
||||
continue;
|
||||
|
||||
Portal_Add2Lines(li1, li2, x1, x2);
|
||||
Portal_Add2Lines(rendercontext, li1, li2, x1, x2);
|
||||
goto clipsolid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Single sided line?
|
||||
if (!backsector)
|
||||
if (!bspcontext->backsector)
|
||||
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;
|
||||
if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum)
|
||||
if (bspcontext->backsector->floorpic == skyflatnum && bspcontext->frontsector->floorpic == skyflatnum)
|
||||
bothfloorssky = true;
|
||||
|
||||
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
|
||||
{
|
||||
if (!line->polyseg &&
|
||||
!line->sidedef->midtexture
|
||||
&& ((!frontsector->ffloors && !backsector->ffloors)
|
||||
|| Tag_Compare(&frontsector->tags, &backsector->tags)))
|
||||
&& ((!bspcontext->frontsector->ffloors && !bspcontext->backsector->ffloors)
|
||||
|| Tag_Compare(&bspcontext->frontsector->tags, &bspcontext->backsector->tags)))
|
||||
return; // line is empty, don't even bother
|
||||
|
||||
goto clippass; // treat like wide open window instead
|
||||
}
|
||||
|
||||
// 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 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); \
|
||||
end2 = P_GetZAt(slope, line->v2->x, line->v2->y, normalheight);
|
||||
|
||||
SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector-> floorheight)
|
||||
SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
|
||||
SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector-> floorheight)
|
||||
SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight)
|
||||
SLOPEPARAMS(bspcontext->frontsector->f_slope, frontf1, frontf2, bspcontext->frontsector-> floorheight)
|
||||
SLOPEPARAMS(bspcontext->frontsector->c_slope, frontc1, frontc2, bspcontext->frontsector->ceilingheight)
|
||||
SLOPEPARAMS( bspcontext->backsector->f_slope, backf1, backf2, bspcontext->backsector-> floorheight)
|
||||
SLOPEPARAMS( bspcontext->backsector->c_slope, backc1, backc2, bspcontext->backsector->ceilingheight)
|
||||
#undef SLOPEPARAMS
|
||||
// if both ceilings are skies, consider it always "open"
|
||||
// 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
|
||||
doorclosed = (backc1 <= backf1 && backc2 <= backf2
|
||||
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
|
||||
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture));
|
||||
bspcontext->doorclosed = (backc1 <= backf1 && backc2 <= backf2
|
||||
&& ((backc1 >= frontc1 && backc2 >= frontc2) || bspcontext->curline->sidedef->toptexture)
|
||||
&& ((backf1 <= frontf1 && backf2 >= frontf2) || bspcontext->curline->sidedef->bottomtexture));
|
||||
|
||||
if (doorclosed)
|
||||
if (bspcontext->doorclosed)
|
||||
goto clipsolid;
|
||||
}
|
||||
|
||||
|
@ -541,40 +528,39 @@ static void R_AddLine(seg_t *line)
|
|||
// same for floors
|
||||
if (!bothceilingssky && !bothfloorssky)
|
||||
{
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
if (bspcontext->backsector->ceilingheight <= bspcontext->frontsector->floorheight
|
||||
|| bspcontext->backsector->floorheight >= bspcontext->frontsector->ceilingheight)
|
||||
{
|
||||
goto clipsolid;
|
||||
}
|
||||
|
||||
// Check for automap fix. Store in doorclosed for r_segs.c
|
||||
doorclosed = R_DoorClosed();
|
||||
if (doorclosed)
|
||||
bspcontext->doorclosed = R_DoorClosed(bspcontext);
|
||||
if (bspcontext->doorclosed)
|
||||
goto clipsolid;
|
||||
}
|
||||
|
||||
// Window.
|
||||
if (!bothceilingssky) // ceilings are always the "same" when sky
|
||||
if (backsector->ceilingheight != frontsector->ceilingheight)
|
||||
if (bspcontext->backsector->ceilingheight != bspcontext->frontsector->ceilingheight)
|
||||
goto clippass;
|
||||
if (!bothfloorssky) // floors are always the "same" when sky
|
||||
if (backsector->floorheight != frontsector->floorheight)
|
||||
if (bspcontext->backsector->floorheight != bspcontext->frontsector->floorheight)
|
||||
goto clippass;
|
||||
}
|
||||
|
||||
// Reject empty lines used for triggers and special events.
|
||||
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
||||
// and no middle texture.
|
||||
|
||||
if (R_IsEmptyLine(line, frontsector, backsector))
|
||||
if (R_IsEmptyLine(line, bspcontext->frontsector, bspcontext->backsector))
|
||||
return;
|
||||
|
||||
clippass:
|
||||
R_ClipPassWallSegment(x1, x2 - 1);
|
||||
R_ClipPassWallSegment(rendercontext, &wallcontext, x1, x2 - 1);
|
||||
return;
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
static boolean R_CheckBBox(const fixed_t *bspcoord)
|
||||
static boolean R_CheckBBox(rendercontext_t *context, const fixed_t *bspcoord)
|
||||
{
|
||||
angle_t angle1, angle2;
|
||||
INT32 sx1, sx2, boxpos;
|
||||
const INT32* check;
|
||||
cliprange_t *start;
|
||||
viewcontext_t *viewcontext = &context->viewcontext;
|
||||
|
||||
// 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;
|
||||
|
||||
check = checkcoord[boxpos];
|
||||
|
||||
// big room fix
|
||||
angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
||||
angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
||||
angle1 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[0]], bspcoord[check[1]]) - viewcontext->angle;
|
||||
angle2 = R_PointToAngleEx(viewcontext->x, viewcontext->y, bspcoord[check[2]], bspcoord[check[3]]) - viewcontext->angle;
|
||||
|
||||
if ((signed)angle1 < (signed)angle2)
|
||||
{
|
||||
|
@ -641,7 +629,7 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
|
|||
// Does not cross a pixel.
|
||||
if (sx1 >= sx2) return false;
|
||||
|
||||
start = solidsegs;
|
||||
start = context->bspcontext.solidsegs;
|
||||
while (start->last < sx2)
|
||||
start++;
|
||||
|
||||
|
@ -789,7 +777,7 @@ static int R_PolysegCompare(const void *p1, const void *p2)
|
|||
// haleyjd 02/19/06
|
||||
// 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;
|
||||
size_t i, j;
|
||||
|
@ -804,7 +792,7 @@ static void R_AddPolyObjects(subsector_t *sub)
|
|||
}
|
||||
|
||||
// for render stats
|
||||
ps_numpolyobjects += numpolys;
|
||||
ps_numpolyobjects[context->num] += numpolys;
|
||||
|
||||
// sort polyobjects
|
||||
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);
|
||||
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.
|
||||
//
|
||||
|
||||
drawseg_t *firstseg;
|
||||
|
||||
static void R_Subsector(size_t num)
|
||||
static void R_Subsector(rendercontext_t *context, size_t num)
|
||||
{
|
||||
INT32 count, floorlightlevel, ceilinglightlevel, light;
|
||||
seg_t *line;
|
||||
subsector_t *sub;
|
||||
static sector_t tempsec; // Deep water hack
|
||||
extracolormap_t *floorcolormap;
|
||||
extracolormap_t *ceilingcolormap;
|
||||
fixed_t floorcenterz, ceilingcenterz;
|
||||
sector_t *frontsector;
|
||||
|
||||
bspcontext_t *bspcontext = &context->bspcontext;
|
||||
planecontext_t *planecontext = &context->planecontext;
|
||||
viewcontext_t *viewcontext = &context->viewcontext;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num >= numsubsectors)
|
||||
|
@ -847,12 +837,11 @@ static void R_Subsector(size_t num)
|
|||
return;
|
||||
|
||||
sub = &subsectors[num];
|
||||
frontsector = sub->sector;
|
||||
count = sub->numlines;
|
||||
line = &segs[sub->firstline];
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -866,9 +855,12 @@ static void R_Subsector(size_t num)
|
|||
{
|
||||
frontsector->numlights = sub->sector->numlights = 0;
|
||||
R_Prep3DFloors(frontsector);
|
||||
|
||||
Lock_state();
|
||||
sub->sector->lightlist = frontsector->lightlist;
|
||||
sub->sector->numlights = frontsector->numlights;
|
||||
sub->sector->moved = frontsector->moved = false;
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
||||
|
@ -883,106 +875,109 @@ static void R_Subsector(size_t num)
|
|||
|
||||
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->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);
|
||||
}
|
||||
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->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,
|
||||
ceilingcolormap, NULL, NULL, frontsector->c_slope);
|
||||
}
|
||||
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)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
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))
|
||||
continue;
|
||||
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ffloor[numffloors].plane = NULL;
|
||||
ffloor[numffloors].polyobj = NULL;
|
||||
planecontext->ffloor[planecontext->numffloors].plane = 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);
|
||||
if (planecenterz <= ceilingcenterz
|
||||
&& planecenterz >= floorcenterz
|
||||
&& ((viewz < 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)))
|
||||
|| (viewcontext->z > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
|
||||
{
|
||||
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,
|
||||
*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.
|
||||
if (ffloor[numffloors].slope)
|
||||
if (planecontext->ffloor[planecontext->numffloors].slope)
|
||||
frontsector->hasslope = true;
|
||||
|
||||
ffloor[numffloors].height = heightcheck;
|
||||
ffloor[numffloors].ffloor = rover;
|
||||
numffloors++;
|
||||
planecontext->ffloor[planecontext->numffloors].height = heightcheck;
|
||||
planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||
planecontext->numffloors++;
|
||||
}
|
||||
if (numffloors >= MAXFFLOORS)
|
||||
if (planecontext->numffloors >= MAXFFLOORS)
|
||||
break;
|
||||
ffloor[numffloors].plane = NULL;
|
||||
ffloor[numffloors].polyobj = NULL;
|
||||
planecontext->ffloor[planecontext->numffloors].plane = 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);
|
||||
if (planecenterz >= floorcenterz
|
||||
&& planecenterz <= ceilingcenterz
|
||||
&& ((viewz > 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)))
|
||||
|| (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].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.
|
||||
if (ffloor[numffloors].slope)
|
||||
if (planecontext->ffloor[planecontext->numffloors].slope)
|
||||
frontsector->hasslope = true;
|
||||
|
||||
ffloor[numffloors].height = heightcheck;
|
||||
ffloor[numffloors].ffloor = rover;
|
||||
numffloors++;
|
||||
planecontext->ffloor[planecontext->numffloors].height = heightcheck;
|
||||
planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||
planecontext->numffloors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -995,7 +990,7 @@ static void R_Subsector(size_t num)
|
|||
|
||||
while (po)
|
||||
{
|
||||
if (numffloors >= MAXFFLOORS)
|
||||
if (planecontext->numffloors >= MAXFFLOORS)
|
||||
break;
|
||||
|
||||
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;
|
||||
ffloor[numffloors].plane = NULL;
|
||||
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||
|
||||
if (polysec->floorheight <= ceilingcenterz
|
||||
&& polysec->floorheight >= floorcenterz
|
||||
&& (viewz < polysec->floorheight))
|
||||
&& (viewcontext->z < polysec->floorheight))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight);
|
||||
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,
|
||||
polysec->floorpic_angle-po->angle,
|
||||
(light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
||||
NULL); // will ffloors be slopable eventually?
|
||||
|
||||
ffloor[numffloors].height = polysec->floorheight;
|
||||
ffloor[numffloors].polyobj = po;
|
||||
ffloor[numffloors].slope = NULL;
|
||||
//ffloor[numffloors].ffloor = rover;
|
||||
po->visplane = ffloor[numffloors].plane;
|
||||
numffloors++;
|
||||
planecontext->ffloor[planecontext->numffloors].height = polysec->floorheight;
|
||||
planecontext->ffloor[planecontext->numffloors].polyobj = po;
|
||||
planecontext->ffloor[planecontext->numffloors].slope = NULL;
|
||||
//planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||
po->visplane = planecontext->ffloor[planecontext->numffloors].plane;
|
||||
planecontext->numffloors++;
|
||||
}
|
||||
|
||||
if (numffloors >= MAXFFLOORS)
|
||||
if (planecontext->numffloors >= MAXFFLOORS)
|
||||
break;
|
||||
|
||||
ffloor[numffloors].plane = NULL;
|
||||
planecontext->ffloor[planecontext->numffloors].plane = NULL;
|
||||
|
||||
if (polysec->ceilingheight >= floorcenterz
|
||||
&& polysec->ceilingheight <= ceilingcenterz
|
||||
&& (viewz > polysec->ceilingheight))
|
||||
&& (viewcontext->z > polysec->ceilingheight))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewcontext->z < polysec->floorheight);
|
||||
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->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po,
|
||||
NULL); // will ffloors be slopable eventually?
|
||||
|
||||
ffloor[numffloors].polyobj = po;
|
||||
ffloor[numffloors].height = polysec->ceilingheight;
|
||||
ffloor[numffloors].slope = NULL;
|
||||
//ffloor[numffloors].ffloor = rover;
|
||||
po->visplane = ffloor[numffloors].plane;
|
||||
numffloors++;
|
||||
planecontext->ffloor[planecontext->numffloors].polyobj = po;
|
||||
planecontext->ffloor[planecontext->numffloors].height = polysec->ceilingheight;
|
||||
planecontext->ffloor[planecontext->numffloors].slope = NULL;
|
||||
//planecontext->ffloor[planecontext->numffloors].ffloor = rover;
|
||||
po->visplane = planecontext->ffloor[planecontext->numffloors].plane;
|
||||
planecontext->numffloors++;
|
||||
}
|
||||
|
||||
po = (polyobj_t *)(po->link.next);
|
||||
}
|
||||
}
|
||||
|
||||
bspcontext->frontsector = frontsector;
|
||||
|
||||
// killough 9/18/98: Fix underwater slowdown, by passing real sector
|
||||
// instead of fake one. Improve sprite lighting by basing sprite
|
||||
// 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
|
||||
// real sector, or you must account for the lighting in some other way,
|
||||
// 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
|
||||
if (sub->polyList)
|
||||
R_AddPolyObjects(sub);
|
||||
R_AddPolyObjects(context, sub);
|
||||
|
||||
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
|
||||
R_AddLine(line);
|
||||
R_AddLine(context, 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
|
||||
|
||||
void R_RenderBSPNode(INT32 bspnum)
|
||||
void R_RenderBSPNode(rendercontext_t *context, INT32 bspnum)
|
||||
{
|
||||
node_t *bsp;
|
||||
INT32 side;
|
||||
|
||||
ps_numbspcalls++;
|
||||
ps_numbspcalls[context->num]++;
|
||||
|
||||
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
|
||||
{
|
||||
bsp = &nodes[bspnum];
|
||||
|
||||
// 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.
|
||||
R_RenderBSPNode(bsp->children[side]);
|
||||
R_RenderBSPNode(context, bsp->children[side]);
|
||||
|
||||
// Possibly divide back space.
|
||||
|
||||
if (!R_CheckBBox(bsp->bbox[side^1]))
|
||||
if (!R_CheckBBox(context, bsp->bbox[side^1]))
|
||||
return;
|
||||
|
||||
bspnum = bsp->children[side^1];
|
||||
}
|
||||
|
||||
// PORTAL CULLING
|
||||
if (portalcullsector) {
|
||||
if (context->bspcontext.portalcullsector) {
|
||||
sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector;
|
||||
if (sect != portalcullsector)
|
||||
if (sect != context->bspcontext.portalcullsector)
|
||||
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
|
||||
#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 drawseg_t *curdrawsegs;
|
||||
extern drawseg_t *drawsegs;
|
||||
extern drawseg_t *ds_p;
|
||||
extern INT32 doorclosed;
|
||||
struct bspcontext_s;
|
||||
struct rendercontext_s;
|
||||
struct viewcontext_s;
|
||||
|
||||
// BSP?
|
||||
void R_ClearClipSegs(void);
|
||||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||
void R_ClearDrawSegs(void);
|
||||
void R_RenderBSPNode(INT32 bspnum);
|
||||
void R_ClearClipSegs(struct bspcontext_s *context, INT32 start, INT32 end);
|
||||
void R_ClearDrawSegs(struct bspcontext_s *context);
|
||||
void R_RenderBSPNode(struct rendercontext_s *context, INT32 bspnum);
|
||||
|
||||
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 polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
|
||||
|
||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||
INT32 *ceilinglightlevel, boolean back);
|
||||
sector_t *R_FakeFlat(struct viewcontext_s *viewcontext, sector_t *sec, sector_t *tempsec,
|
||||
INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back);
|
||||
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
|
||||
|
||||
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;
|
||||
|
||||
// do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap()
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
// if (rendermode != render_soft)
|
||||
// return;
|
||||
|
||||
// Precache flats.
|
||||
flatmemory = P_PrecacheLevelFlats();
|
||||
|
|
14
src/r_defs.h
14
src/r_defs.h
|
@ -22,7 +22,7 @@
|
|||
// SECTORS do store MObjs anyway.
|
||||
#include "p_mobj.h"
|
||||
|
||||
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
|
||||
#include "screen.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "m_aatree.h"
|
||||
|
@ -41,6 +41,9 @@ typedef struct
|
|||
INT32 last;
|
||||
} cliprange_t;
|
||||
|
||||
// Fix from boom.
|
||||
#define MAXSEGS (MAXVIDWIDTH/2+1)
|
||||
|
||||
// Silhouette, needed for clipping segs (mainly) and sprites representing things.
|
||||
#define SIL_NONE 0
|
||||
#define SIL_BOTTOM 1
|
||||
|
@ -56,6 +59,15 @@ typedef UINT8 lighttable_t;
|
|||
#define CMF_FADEFULLBRIGHTSPRITES 1
|
||||
#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.
|
||||
typedef struct extracolormap_s
|
||||
{
|
||||
|
|
102
src/r_draw.c
102
src/r_draw.c
|
@ -62,14 +62,6 @@ UINT8 *topleft;
|
|||
// 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
|
||||
// -----------------------
|
||||
|
@ -78,48 +70,11 @@ UINT8 *dc_source;
|
|||
UINT8 *transtables; // translucency tables
|
||||
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
|
||||
// =========================================================================
|
||||
|
||||
INT32 ds_y, ds_x1, ds_x2;
|
||||
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;
|
||||
float focallengthf;
|
||||
|
||||
// =========================================================================
|
||||
// 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];
|
||||
}
|
||||
|
||||
#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.
|
||||
|
||||
|
@ -589,13 +553,16 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
|
|||
|
||||
if (flags & GTC_CACHE)
|
||||
{
|
||||
Lock_state();
|
||||
// Allocate table for skin if necessary
|
||||
if (!translationtablecache[skintableindex])
|
||||
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
|
||||
Unlock_state();
|
||||
|
||||
// Get colormap
|
||||
ret = translationtablecache[skintableindex][color];
|
||||
|
||||
Lock_state();
|
||||
// Rebuild the cache if necessary
|
||||
if (skincolor_modified[color])
|
||||
{
|
||||
|
@ -605,18 +572,21 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
|
|||
|
||||
skincolor_modified[color] = false;
|
||||
}
|
||||
Unlock_state();
|
||||
}
|
||||
else ret = NULL;
|
||||
|
||||
// Generate the colormap if necessary
|
||||
if (!ret)
|
||||
{
|
||||
Lock_state();
|
||||
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
|
||||
R_GenerateTranslationColormap(ret, skinnum, color);
|
||||
|
||||
// Cache the colormap if desired
|
||||
if (flags & GTC_CACHE)
|
||||
translationtablecache[skintableindex][color] = ret;
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -887,13 +857,37 @@ void R_DrawViewBorder(void)
|
|||
// 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_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 UINT8 *topleft;
|
||||
|
||||
// -------------------------
|
||||
// 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;
|
||||
extern float focallengthf;
|
||||
|
||||
/// \brief Top border
|
||||
#define BRDR_T 0
|
||||
|
@ -163,85 +109,180 @@ void R_DrawViewBorder(void);
|
|||
|
||||
#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
|
||||
// -----------------
|
||||
|
||||
void R_DrawColumn_8(void);
|
||||
void R_DrawShadeColumn_8(void);
|
||||
void R_DrawTranslucentColumn_8(void);
|
||||
void R_DrawTranslatedColumn_8(void);
|
||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||
void R_Draw2sMultiPatchColumn_8(void);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void);
|
||||
void R_DrawFogColumn_8(void);
|
||||
void R_DrawColumnShadowed_8(void);
|
||||
void R_DrawColumn_8(colcontext_t *dc);
|
||||
void R_DrawShadeColumn_8(colcontext_t *dc);
|
||||
void R_DrawTranslucentColumn_8(colcontext_t *dc);
|
||||
void R_DrawTranslatedColumn_8(colcontext_t *dc);
|
||||
void R_DrawTranslatedTranslucentColumn_8(colcontext_t *dc);
|
||||
void R_Draw2sMultiPatchColumn_8(colcontext_t *dc);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(colcontext_t *dc);
|
||||
void R_DrawFogColumn_8(colcontext_t *dc);
|
||||
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_DrawTranslucentSpan_8(void);
|
||||
void R_DrawTiltedSpan_8(void);
|
||||
void R_DrawTiltedTranslucentSpan_8(void);
|
||||
void R_DrawSplat_8(spancontext_t *ds);
|
||||
void R_DrawTranslucentSplat_8(spancontext_t *ds);
|
||||
void R_DrawTiltedSplat_8(spancontext_t *ds);
|
||||
|
||||
void R_DrawSplat_8(void);
|
||||
void R_DrawTranslucentSplat_8(void);
|
||||
void R_DrawTiltedSplat_8(void);
|
||||
void R_DrawFloorSprite_8(spancontext_t *ds);
|
||||
void R_DrawTranslucentFloorSprite_8(spancontext_t *ds);
|
||||
void R_DrawTiltedFloorSprite_8(spancontext_t *ds);
|
||||
void R_DrawTiltedTranslucentFloorSprite_8(spancontext_t *ds);
|
||||
|
||||
void R_DrawFloorSprite_8(void);
|
||||
void R_DrawTranslucentFloorSprite_8(void);
|
||||
void R_DrawTiltedFloorSprite_8(void);
|
||||
void R_DrawTiltedTranslucentFloorSprite_8(void);
|
||||
void R_DrawTranslucentWaterSpan_8(spancontext_t *ds);
|
||||
void R_DrawTiltedTranslucentWaterSpan_8(spancontext_t *ds);
|
||||
|
||||
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
|
||||
extern INT32 tiltlighting[MAXVIDWIDTH];
|
||||
|
||||
void R_DrawTranslucentWaterSpan_8(void);
|
||||
void R_DrawTiltedTranslucentWaterSpan_8(void);
|
||||
|
||||
void R_DrawFogSpan_8(void);
|
||||
void R_DrawFogSpan_8(spancontext_t *ds);
|
||||
|
||||
// Lactozilla: Non-powers-of-two
|
||||
void R_DrawSpan_NPO2_8(void);
|
||||
void R_DrawTranslucentSpan_NPO2_8(void);
|
||||
void R_DrawTiltedSpan_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentSpan_NPO2_8(void);
|
||||
void R_DrawSpan_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTranslucentSpan_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedSpan_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedTranslucentSpan_NPO2_8(spancontext_t *ds);
|
||||
|
||||
void R_DrawSplat_NPO2_8(void);
|
||||
void R_DrawTranslucentSplat_NPO2_8(void);
|
||||
void R_DrawTiltedSplat_NPO2_8(void);
|
||||
void R_DrawSplat_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTranslucentSplat_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedSplat_NPO2_8(spancontext_t *ds);
|
||||
|
||||
void R_DrawFloorSprite_NPO2_8(void);
|
||||
void R_DrawTranslucentFloorSprite_NPO2_8(void);
|
||||
void R_DrawTiltedFloorSprite_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void);
|
||||
void R_DrawFloorSprite_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTranslucentFloorSprite_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedFloorSprite_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(spancontext_t *ds);
|
||||
|
||||
void R_DrawTranslucentWaterSpan_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
|
||||
|
||||
#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
|
||||
void R_DrawTranslucentWaterSpan_NPO2_8(spancontext_t *ds);
|
||||
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(spancontext_t *ds);
|
||||
|
||||
// =========================================================================
|
||||
#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_things.h"
|
||||
#include "r_draw.h"
|
||||
|
||||
extern drawseg_t *firstseg;
|
||||
#include "r_context.h"
|
||||
|
||||
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.
|
||||
#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
|
||||
size_t validcount = 1;
|
||||
|
||||
|
@ -102,20 +118,21 @@ extracolormap_t *extra_colormaps = NULL;
|
|||
// Render stats
|
||||
precise_t ps_prevframetime = 0;
|
||||
precise_t ps_rendercalltime = 0;
|
||||
precise_t ps_postprocesstime = 0;
|
||||
precise_t ps_uitime = 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_portaltime = 0;
|
||||
precise_t ps_sw_planetime = 0;
|
||||
precise_t ps_sw_maskedtime = 0;
|
||||
precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS] = {0};
|
||||
precise_t ps_sw_portaltime[MAX_RENDER_THREADS] = {0};
|
||||
precise_t ps_sw_planetime[MAX_RENDER_THREADS] = {0};
|
||||
precise_t ps_sw_maskedtime[MAX_RENDER_THREADS] = {0};
|
||||
|
||||
int ps_numbspcalls = 0;
|
||||
int ps_numsprites = 0;
|
||||
int ps_numdrawnodes = 0;
|
||||
int ps_numpolyobjects = 0;
|
||||
int ps_numbspcalls[MAX_RENDER_THREADS] = {0};
|
||||
int ps_numsprites[MAX_RENDER_THREADS] = {0};
|
||||
int ps_numdrawnodes[MAX_RENDER_THREADS] = {0};
|
||||
int ps_numpolyobjects[MAX_RENDER_THREADS] = {0};
|
||||
|
||||
static CV_PossibleValue_t drawdist_cons_t[] = {
|
||||
{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 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 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_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);
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
//
|
||||
// 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
|
||||
// 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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -960,7 +1229,7 @@ void R_ExecuteSetViewSize(void)
|
|||
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
|
||||
}
|
||||
|
||||
if (ds_su)
|
||||
/*if (ds_su)
|
||||
Z_Free(ds_su);
|
||||
if (ds_sv)
|
||||
Z_Free(ds_sv);
|
||||
|
@ -968,7 +1237,7 @@ void R_ExecuteSetViewSize(void)
|
|||
Z_Free(ds_sz);
|
||||
|
||||
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));
|
||||
|
@ -1024,7 +1293,7 @@ void R_Init(void)
|
|||
//I_OutputMsg("\nR_InitTranslucencyTables\n");
|
||||
R_InitTranslucencyTables();
|
||||
|
||||
R_InitDrawNodes();
|
||||
R_InitContexts();
|
||||
|
||||
framecount = 0;
|
||||
}
|
||||
|
@ -1394,63 +1663,57 @@ boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox)
|
|||
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
|
||||
// ================
|
||||
|
||||
// FAB NOTE FOR WIN32 PORT !! I'm not finished already,
|
||||
// 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..
|
||||
// I mean, there is a win16lock() or something that lasts all the rendering,
|
||||
// so maybe we should release screen lock before each netupdate below..?
|
||||
static void R_PrepareViewContext(viewcontext_t *context)
|
||||
{
|
||||
context->x = viewx;
|
||||
context->y = viewy;
|
||||
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)
|
||||
{
|
||||
UINT8 nummasks = 1;
|
||||
maskcount_t* masks = malloc(sizeof(maskcount_t));
|
||||
INT32 currcontext;
|
||||
INT32 finishedcontexts = 0;
|
||||
|
||||
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);
|
||||
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.
|
||||
NetUpdate();
|
||||
|
||||
// The head node is the last node output.
|
||||
|
||||
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)
|
||||
#ifdef HAVE_THREADS
|
||||
if (cv_numthreads.value != numusablerendercontexts)
|
||||
{
|
||||
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.
|
||||
|
||||
R_ClearFFloorClips();
|
||||
|
||||
// Apply the viewpoint stored for the portal.
|
||||
R_PortalFrame(portal);
|
||||
|
||||
// Hack in the clipsegs to delimit the starting
|
||||
// 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);
|
||||
#ifdef HAVE_THREADS
|
||||
if (renderthreaded)
|
||||
I_atomic_exchange(&renderdatas[currcontext].framewaiting, 1);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
R_RenderViewContext(&renderdatas[currcontext].context);
|
||||
finishedcontexts++;
|
||||
}
|
||||
}
|
||||
ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime;
|
||||
|
||||
ps_sw_planetime = I_GetPreciseTime();
|
||||
R_DrawPlanes();
|
||||
ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime;
|
||||
|
||||
// draw mid texture and sprite
|
||||
// And now 3D floors/sides!
|
||||
ps_sw_maskedtime = I_GetPreciseTime();
|
||||
R_DrawMasked(masks, nummasks);
|
||||
ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime;
|
||||
|
||||
free(masks);
|
||||
#ifdef HAVE_THREADS
|
||||
while (renderthreaded && finishedcontexts != numusablerendercontexts)
|
||||
{
|
||||
for (currcontext = 0; currcontext < numusablerendercontexts; currcontext++)
|
||||
finishedcontexts += I_atomic_exchange(&renderdatas[currcontext].framefinished, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
@ -1639,6 +1834,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_translucenthud);
|
||||
|
||||
CV_RegisterVar(&cv_maxportals);
|
||||
CV_RegisterVar(&cv_numthreads);
|
||||
|
||||
CV_RegisterVar(&cv_movebob);
|
||||
}
|
||||
|
|
28
src/r_main.h
28
src/r_main.h
|
@ -29,6 +29,10 @@ extern fixed_t centerxfrac, centeryfrac;
|
|||
extern fixed_t projection, projectiony;
|
||||
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!
|
||||
#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_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_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||
|
||||
|
@ -78,22 +81,23 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe
|
|||
|
||||
// Render stats
|
||||
|
||||
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_postprocesstime;
|
||||
extern precise_t ps_uitime;
|
||||
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_portaltime;
|
||||
extern precise_t ps_sw_planetime;
|
||||
extern precise_t ps_sw_maskedtime;
|
||||
extern precise_t ps_sw_spritecliptime[MAX_RENDER_THREADS];
|
||||
extern precise_t ps_sw_portaltime[MAX_RENDER_THREADS];
|
||||
extern precise_t ps_sw_planetime[MAX_RENDER_THREADS];
|
||||
extern precise_t ps_sw_maskedtime[MAX_RENDER_THREADS];
|
||||
|
||||
extern int ps_numbspcalls;
|
||||
extern int ps_numsprites;
|
||||
extern int ps_numdrawnodes;
|
||||
extern int ps_numpolyobjects;
|
||||
extern int ps_numbspcalls[MAX_RENDER_THREADS];
|
||||
extern int ps_numsprites[MAX_RENDER_THREADS];
|
||||
extern int ps_numdrawnodes[MAX_RENDER_THREADS];
|
||||
extern int ps_numpolyobjects[MAX_RENDER_THREADS];
|
||||
|
||||
//
|
||||
// REFRESH - the actual rendering functions.
|
||||
|
@ -131,6 +135,8 @@ void R_SkyboxFrame(player_t *player);
|
|||
boolean R_ViewpointHasChasecam(player_t *player);
|
||||
boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox);
|
||||
|
||||
void R_StopThreads(void);
|
||||
|
||||
// Called by D_Display.
|
||||
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;
|
||||
} 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
|
||||
{
|
||||
visplane_t *plane;
|
||||
struct visplane_s *plane;
|
||||
fixed_t height;
|
||||
fixed_t f_pos; // F for Front sector
|
||||
fixed_t b_pos; // B for Back sector
|
||||
|
@ -117,10 +74,36 @@ typedef struct planemgr_s
|
|||
|
||||
struct ffloor_s *ffloor;
|
||||
polyobj_t *polyobj;
|
||||
} visffloor_t;
|
||||
} planemgr_t;
|
||||
|
||||
extern visffloor_t ffloor[MAXFFLOORS];
|
||||
extern INT32 numffloors;
|
||||
// Visplane related.
|
||||
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
|
||||
|
|
101
src/r_portal.c
101
src/r_portal.c
|
@ -14,27 +14,17 @@
|
|||
#include "r_portal.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_main.h"
|
||||
#include "r_context.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_spec.h" // Skybox viewpoints
|
||||
#include "z_zone.h"
|
||||
#include "r_things.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
|
||||
|
||||
// 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)
|
||||
void Portal_InitList (bspcontext_t *bspcontext)
|
||||
{
|
||||
portalrender = 0;
|
||||
portal_base = portal_cap = NULL;
|
||||
bspcontext->portalrender = 0;
|
||||
bspcontext->portal_base = bspcontext->portal_cap = NULL;
|
||||
}
|
||||
|
||||
/** 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
|
||||
* lines into portals.
|
||||
*/
|
||||
void Portal_ClipRange (portal_t* portal)
|
||||
void Portal_ClipRange (planecontext_t *planecontext, portal_t* portal)
|
||||
{
|
||||
INT32 start = portal->start;
|
||||
INT32 end = portal->end;
|
||||
|
@ -54,18 +44,18 @@ void Portal_ClipRange (portal_t* portal)
|
|||
INT32 i;
|
||||
for (i = 0; i < end-start; i++)
|
||||
{
|
||||
*ceil = ceilingclip[start+i];
|
||||
*ceil = planecontext->ceilingclip[start+i];
|
||||
ceil++;
|
||||
*floor = floorclip[start+i];
|
||||
*floor = planecontext->floorclip[start+i];
|
||||
floor++;
|
||||
*scale = frontscale[start+i];
|
||||
*scale = planecontext->frontscale[start+i];
|
||||
scale++;
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 start = portal->start;
|
||||
|
@ -76,28 +66,28 @@ void Portal_ClipApply (const portal_t* portal)
|
|||
|
||||
for (i = 0; i < end-start; i++)
|
||||
{
|
||||
ceilingclip[start+i] = *ceil;
|
||||
planecontext->ceilingclip[start+i] = *ceil;
|
||||
ceil++;
|
||||
floorclip[start+i] = *floor;
|
||||
planecontext->floorclip[start+i] = *floor;
|
||||
floor++;
|
||||
frontscale[start+i] = *scale;
|
||||
planecontext->frontscale[start+i] = *scale;
|
||||
scale++;
|
||||
}
|
||||
|
||||
// HACKS FOLLOW
|
||||
for (i = 0; i < start; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
planecontext->floorclip[i] = -1;
|
||||
planecontext->ceilingclip[i] = (INT16)viewheight;
|
||||
}
|
||||
for (i = end; i < vid.width; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
planecontext->floorclip[i] = -1;
|
||||
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);
|
||||
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);
|
||||
|
||||
// Linked list.
|
||||
if (!portal_base)
|
||||
if (!context->portal_base)
|
||||
{
|
||||
portal_base = portal;
|
||||
portal_cap = portal;
|
||||
context->portal_base = portal;
|
||||
context->portal_cap = portal;
|
||||
}
|
||||
else
|
||||
{
|
||||
portal_cap->next = portal;
|
||||
portal_cap = portal;
|
||||
context->portal_cap->next = portal;
|
||||
context->portal_cap = portal;
|
||||
}
|
||||
portal->next = NULL;
|
||||
|
||||
|
@ -125,14 +115,14 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
|||
portal->end = x2;
|
||||
|
||||
// Increase recursion level.
|
||||
portal->pass = portalrender+1;
|
||||
portal->pass = context->portalrender+1;
|
||||
|
||||
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->floorclip);
|
||||
Z_Free(portal->frontscale);
|
||||
|
@ -149,9 +139,10 @@ void Portal_Remove (portal_t* portal)
|
|||
* When the portal renders, it will create the illusion of
|
||||
* 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
|
||||
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.y = (dest->v1->y + dest->v2->y) / 2;
|
||||
|
||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
||||
angtopoint = R_PointToAngle2(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, context->viewcontext.x, context->viewcontext.y);
|
||||
angtopoint += dangle;
|
||||
|
||||
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
portal->viewangle = viewangle + dangle;
|
||||
portal->viewz = context->viewcontext.z + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
portal->viewangle = context->viewcontext.angle + dangle;
|
||||
|
||||
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.
|
||||
|
@ -256,7 +247,7 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
|
|||
* Applies the necessary offsets and rotation to give
|
||||
* 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;
|
||||
mapheader_t *mh;
|
||||
|
@ -265,14 +256,14 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
if (TrimVisplaneBounds(plane, &start, &end))
|
||||
return;
|
||||
|
||||
portal = Portal_Add(start, end);
|
||||
portal = Portal_Add(bspcontext, start, end);
|
||||
|
||||
Portal_ClipVisplane(plane, portal);
|
||||
|
||||
portal->viewx = skyboxmo[0]->x;
|
||||
portal->viewy = skyboxmo[0]->y;
|
||||
portal->viewz = skyboxmo[0]->z;
|
||||
portal->viewangle = viewangle + skyboxmo[0]->angle;
|
||||
portal->viewangle = viewcontext->angle + skyboxmo[0]->angle;
|
||||
|
||||
mh = mapheaderinfo[gamemap-1];
|
||||
|
||||
|
@ -283,14 +274,14 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT;
|
||||
|
||||
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)
|
||||
x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||
x = (viewcontext->x - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||
|
||||
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)
|
||||
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.
|
||||
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)
|
||||
portal->viewz += viewz / mh->skybox_scalez;
|
||||
portal->viewz += viewcontext->z / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
portal->viewz += viewz * -mh->skybox_scalez;
|
||||
portal->viewz += viewcontext->z * -mh->skybox_scalez;
|
||||
|
||||
portal->clipline = -1;
|
||||
}
|
||||
|
@ -308,7 +299,7 @@ void Portal_AddSkybox (const visplane_t* plane)
|
|||
/** Creates portals for the currently existing sky visplanes.
|
||||
* The visplanes are also removed and cleared from the list.
|
||||
*/
|
||||
void Portal_AddSkyboxPortals (void)
|
||||
void Portal_AddSkyboxPortals (rendercontext_t *context)
|
||||
{
|
||||
visplane_t *pl;
|
||||
INT32 i;
|
||||
|
@ -316,11 +307,11 @@ void Portal_AddSkyboxPortals (void)
|
|||
|
||||
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)
|
||||
{
|
||||
Portal_AddSkybox(pl);
|
||||
Portal_AddSkybox(&context->bspcontext, &context->viewcontext, pl);
|
||||
|
||||
pl->minx = 0;
|
||||
pl->maxx = -1;
|
||||
|
|
|
@ -41,21 +41,19 @@ typedef struct portal_s
|
|||
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
|
||||
} portal_t;
|
||||
|
||||
extern portal_t* portal_base;
|
||||
extern portal_t* portal_cap;
|
||||
extern UINT8 portalrender;
|
||||
struct bspcontext_s;
|
||||
struct planecontext_s;
|
||||
struct rendercontext_s;
|
||||
struct viewcontext_s;
|
||||
|
||||
extern line_t *portalclipline;
|
||||
extern sector_t *portalcullsector;
|
||||
extern INT32 portalclipstart, portalclipend;
|
||||
void Portal_InitList (struct bspcontext_s *bspcontext);
|
||||
void Portal_Remove (struct bspcontext_s *context, portal_t* portal);
|
||||
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_Remove (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 (struct planecontext_s *planecontext, portal_t* portal);
|
||||
void Portal_ClipApply (struct planecontext_s *planecontext, const portal_t* portal);
|
||||
|
||||
void Portal_ClipRange (portal_t* portal);
|
||||
void Portal_ClipApply (const portal_t* portal);
|
||||
|
||||
void Portal_AddSkyboxPortals (void);
|
||||
void Portal_AddSkyboxPortals (struct rendercontext_s *context);
|
||||
#endif
|
||||
|
|
1707
src/r_segs.c
1707
src/r_segs.c
File diff suppressed because it is too large
Load diff
|
@ -18,9 +18,12 @@
|
|||
#pragma interface
|
||||
#endif
|
||||
|
||||
struct rendercontext_s;
|
||||
struct wallcontext_s;
|
||||
|
||||
transnum_t R_GetLinedefTransTable(fixed_t alpha);
|
||||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
|
||||
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
|
||||
void R_StoreWallRange(INT32 start, INT32 stop);
|
||||
void R_RenderMaskedSegRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2);
|
||||
void R_RenderThickSideRange(struct rendercontext_s *context, drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
|
||||
void R_StoreWallRange(struct rendercontext_s *context, struct wallcontext_s *wallcontext, INT32 start, INT32 stop);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,9 +54,6 @@ INT32 globallevelskynum;
|
|||
|
||||
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
|
||||
*/
|
||||
void R_SetupSkyDraw(void)
|
||||
|
|
158
src/r_splats.c
158
src/r_splats.c
|
@ -13,38 +13,23 @@
|
|||
#include "r_draw.h"
|
||||
#include "r_main.h"
|
||||
#include "r_splats.h"
|
||||
#include "r_context.h"
|
||||
#include "r_bsp.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
struct rastery_s *prastertab; // for ASM code
|
||||
|
||||
static struct rastery_s rastertab[MAXVIDHEIGHT];
|
||||
static void prepare_rastertab(void);
|
||||
static void prepare_rastertab(planecontext_t *planecontext);
|
||||
|
||||
// ==========================================================================
|
||||
// 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
|
||||
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)
|
||||
static void rasterize_segment_tex(planecontext_t *planecontext, 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 dx0, dx1;
|
||||
|
||||
|
@ -66,9 +51,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
rastertab[y1].maxx = xs;
|
||||
rastertab[y1].tx2 = xe;
|
||||
rastertab[y1].ty2 = tc;
|
||||
planecontext->rastertab[y1].maxx = xs;
|
||||
planecontext->rastertab[y1].tx2 = xe;
|
||||
planecontext->rastertab[y1].ty2 = tc;
|
||||
|
||||
xs += dx0;
|
||||
xe += dx1;
|
||||
|
@ -81,9 +66,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
rastertab[y1].maxx = xs;
|
||||
rastertab[y1].tx2 = tc;
|
||||
rastertab[y1].ty2 = xe;
|
||||
planecontext->rastertab[y1].maxx = xs;
|
||||
planecontext->rastertab[y1].tx2 = tc;
|
||||
planecontext->rastertab[y1].ty2 = xe;
|
||||
|
||||
xs += dx0;
|
||||
xe += dx1;
|
||||
|
@ -108,9 +93,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
rastertab[y2].minx = xs;
|
||||
rastertab[y2].tx1 = xe;
|
||||
rastertab[y2].ty1 = tc;
|
||||
planecontext->rastertab[y2].minx = xs;
|
||||
planecontext->rastertab[y2].tx1 = xe;
|
||||
planecontext->rastertab[y2].ty1 = tc;
|
||||
|
||||
xs += dx0;
|
||||
xe += dx1;
|
||||
|
@ -123,9 +108,9 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
rastertab[y2].minx = xs;
|
||||
rastertab[y2].tx1 = tc;
|
||||
rastertab[y2].ty1 = xe;
|
||||
planecontext->rastertab[y2].minx = xs;
|
||||
planecontext->rastertab[y2].tx1 = tc;
|
||||
planecontext->rastertab[y2].ty1 = xe;
|
||||
|
||||
xs += dx0;
|
||||
xe += dx1;
|
||||
|
@ -135,10 +120,9 @@ 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;
|
||||
mobj_t *mobj = spr->mobj;
|
||||
|
@ -308,7 +292,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
|
|||
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
|
||||
// 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
|
||||
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 step;
|
||||
|
||||
planecontext_t *planecontext = &context->planecontext;
|
||||
|
||||
colcontext_t *dc = &context->colcontext;
|
||||
spancontext_t *ds = &context->spancontext;
|
||||
int spanfunctype = SPANDRAWFUNC_SPRITE;
|
||||
|
||||
prepare_rastertab();
|
||||
prepare_rastertab(planecontext);
|
||||
|
||||
#define RASTERPARAMS(vnum1, vnum2, tv1, tv2, tc, dir) \
|
||||
x1 = verts[vnum1].x; \
|
||||
|
@ -372,7 +360,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
} \
|
||||
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) \
|
||||
miny = ry1; \
|
||||
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
|
||||
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
|
||||
|
||||
ds_source = (UINT8 *)pSplat->pic;
|
||||
ds_flatwidth = pSplat->width;
|
||||
ds_flatheight = pSplat->height;
|
||||
ds->source = (UINT8 *)pSplat->pic;
|
||||
ds->flatwidth = pSplat->width;
|
||||
ds->flatheight = pSplat->height;
|
||||
|
||||
if (R_CheckPowersOfTwo())
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (R_CheckPowersOfTwo(ds->flatwidth, ds->flatheight))
|
||||
R_CheckFlatLength(ds, ds->flatwidth * ds->flatheight);
|
||||
|
||||
if (pSplat->slope)
|
||||
{
|
||||
R_SetTiltedSpan(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_CalculateSlopeVectors();
|
||||
R_SetTiltedSpan(ds, 0);
|
||||
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(ds);
|
||||
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
planeheight = abs(pSplat->z - vis->viewpoint.z);
|
||||
planecontext->planeheight = abs(pSplat->z - vis->viewpoint.z);
|
||||
|
||||
if (pSplat->angle)
|
||||
{
|
||||
memset(cachedheight, 0, sizeof(cachedheight));
|
||||
memset(planecontext->cachedheight, 0, sizeof(planecontext->cachedheight));
|
||||
|
||||
// Add the view offset, rotated by the plane angle.
|
||||
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_translation = R_GetSpriteTranslation(vis);
|
||||
if (ds_translation == NULL)
|
||||
ds_translation = colormaps;
|
||||
ds->colormap = vis->colormap;
|
||||
ds->translation = R_GetSpriteTranslation(vis);
|
||||
if (ds->translation == NULL)
|
||||
ds->translation = colormaps;
|
||||
|
||||
if (vis->extra_colormap)
|
||||
{
|
||||
if (!ds_colormap)
|
||||
ds_colormap = vis->extra_colormap->colormap;
|
||||
if (!ds->colormap)
|
||||
ds->colormap = vis->extra_colormap->colormap;
|
||||
else
|
||||
ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps];
|
||||
ds->colormap = &vis->extra_colormap->colormap[ds->colormap - colormaps];
|
||||
}
|
||||
|
||||
if (vis->transmap)
|
||||
{
|
||||
ds_transmap = vis->transmap;
|
||||
ds->transmap = vis->transmap;
|
||||
|
||||
if (pSplat->slope)
|
||||
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
|
||||
|
@ -446,12 +434,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
|
||||
}
|
||||
else
|
||||
ds_transmap = NULL;
|
||||
ds->transmap = NULL;
|
||||
|
||||
if (ds_powersoftwo)
|
||||
spanfunc = spanfuncs[spanfunctype];
|
||||
if (ds->powersoftwo)
|
||||
ds->func = spanfuncs[spanfunctype];
|
||||
else
|
||||
spanfunc = spanfuncs_npo2[spanfunctype];
|
||||
ds->func = spanfuncs_npo2[spanfunctype];
|
||||
|
||||
if (maxy >= vid.height)
|
||||
maxy = vid.height-1;
|
||||
|
@ -460,8 +448,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
{
|
||||
boolean cliptab[MAXVIDWIDTH+1];
|
||||
|
||||
x1 = rastertab[y].minx>>FRACBITS;
|
||||
x2 = rastertab[y].maxx>>FRACBITS;
|
||||
x1 = planecontext->rastertab[y].minx>>FRACBITS;
|
||||
x2 = planecontext->rastertab[y].maxx>>FRACBITS;
|
||||
|
||||
if (x1 > x2)
|
||||
{
|
||||
|
@ -482,7 +470,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
continue;
|
||||
|
||||
for (i = x1; i <= x2; i++)
|
||||
cliptab[i] = (y >= mfloorclip[i]);
|
||||
cliptab[i] = (y >= dc->mfloorclip[i]);
|
||||
|
||||
// clip left
|
||||
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 planesin = FINESINE(angle);
|
||||
|
||||
if (planeheight != cachedheight[y])
|
||||
if (planecontext->planeheight != planecontext->cachedheight[y])
|
||||
{
|
||||
cachedheight[y] = planeheight;
|
||||
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
||||
planecontext->cachedheight[y] = planeheight;
|
||||
distance = planecontext->cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
||||
span = abs(centery - y);
|
||||
|
||||
if (span) // Don't divide by zero
|
||||
|
@ -530,43 +518,43 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
else
|
||||
xstep = ystep = FRACUNIT;
|
||||
|
||||
cachedxstep[y] = xstep;
|
||||
cachedystep[y] = ystep;
|
||||
planecontext->cachedxstep[y] = xstep;
|
||||
planecontext->cachedystep[y] = ystep;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = cacheddistance[y];
|
||||
xstep = cachedxstep[y];
|
||||
ystep = cachedystep[y];
|
||||
distance = planecontext->cacheddistance[y];
|
||||
xstep = planecontext->cachedxstep[y];
|
||||
ystep = planecontext->cachedystep[y];
|
||||
}
|
||||
|
||||
ds_xstep = FixedDiv(xstep, pSplat->xscale);
|
||||
ds_ystep = FixedDiv(ystep, pSplat->yscale);
|
||||
ds->xstep = FixedDiv(xstep, pSplat->xscale);
|
||||
ds->ystep = FixedDiv(ystep, pSplat->yscale);
|
||||
|
||||
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->xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
|
||||
ds->yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
spanfunc();
|
||||
ds->y = y;
|
||||
ds->x1 = x1;
|
||||
ds->x2 = x2;
|
||||
ds->func(ds);
|
||||
|
||||
rastertab[y].minx = INT32_MAX;
|
||||
rastertab[y].maxx = INT32_MIN;
|
||||
planecontext->rastertab[y].minx = INT32_MAX;
|
||||
planecontext->rastertab[y].maxx = INT32_MIN;
|
||||
}
|
||||
|
||||
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;
|
||||
prastertab = rastertab;
|
||||
planecontext->prastertab = planecontext->rastertab;
|
||||
for (i = 0; i < vid.height; i++)
|
||||
{
|
||||
rastertab[i].minx = INT32_MAX;
|
||||
rastertab[i].maxx = INT32_MIN;
|
||||
planecontext->rastertab[i].minx = INT32_MAX;
|
||||
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 tx2, ty2; // end points in texture at this line
|
||||
};
|
||||
extern struct rastery_s *prastertab; // for ASM code
|
||||
|
||||
typedef struct floorsplat_s
|
||||
{
|
||||
|
@ -41,6 +40,8 @@ typedef struct floorsplat_s
|
|||
mobj_t *mobj; // Mobj it is tied to
|
||||
} 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__*/
|
||||
|
|
|
@ -90,6 +90,8 @@ extern sector_t *viewsector;
|
|||
extern player_t *viewplayer;
|
||||
extern mobj_t *r_viewmobj;
|
||||
|
||||
extern consvar_t cv_numthreads;
|
||||
|
||||
extern consvar_t cv_allowmlook;
|
||||
extern consvar_t cv_maxportals;
|
||||
|
||||
|
@ -99,10 +101,4 @@ extern angle_t doubleclipangle;
|
|||
extern INT32 viewangletox[FINEANGLES/2];
|
||||
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
|
||||
|
|
130
src/r_textures.c
130
src/r_textures.c
|
@ -34,6 +34,15 @@
|
|||
|
||||
#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
|
||||
// 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)
|
||||
{
|
||||
Lock_state();
|
||||
if (!texturecache[tex])
|
||||
R_GenerateTexture(tex);
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -525,9 +536,11 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col)
|
|||
else
|
||||
col &= (width - 1);
|
||||
|
||||
Lock_state();
|
||||
data = texturecache[tex];
|
||||
if (!data)
|
||||
data = R_GenerateTexture(tex);
|
||||
Unlock_state();
|
||||
|
||||
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.
|
||||
//
|
||||
void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||
void *R_GetLevelFlat(levelflat_t *levelflat, UINT16 *flatwidth, UINT16 *flatheight)
|
||||
{
|
||||
boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
|
||||
texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL);
|
||||
|
@ -555,8 +568,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
if (texture->flat)
|
||||
{
|
||||
flatdata = texture->flat;
|
||||
ds_flatwidth = texture->width;
|
||||
ds_flatheight = texture->height;
|
||||
*flatwidth = texture->width;
|
||||
*flatheight = texture->height;
|
||||
texturechanged = false;
|
||||
}
|
||||
else
|
||||
|
@ -566,12 +579,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
// If the texture changed, or the flat wasn't generated, convert.
|
||||
if (levelflat->picture == NULL || texturechanged)
|
||||
{
|
||||
Lock_state();
|
||||
|
||||
// Level texture
|
||||
if (isleveltexture)
|
||||
{
|
||||
levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num);
|
||||
ds_flatwidth = levelflat->width = texture->width;
|
||||
ds_flatheight = levelflat->height = texture->height;
|
||||
*flatwidth = levelflat->width = texture->width;
|
||||
*flatheight = levelflat->height = texture->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -584,8 +599,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
levelflat->width = (UINT16)pngwidth;
|
||||
levelflat->height = (UINT16)pngheight;
|
||||
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
*flatwidth = levelflat->width;
|
||||
*flatheight = levelflat->height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -595,8 +610,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
size_t size;
|
||||
softwarepatch_t *patch = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
||||
|
||||
levelflat->width = ds_flatwidth = SHORT(patch->width);
|
||||
levelflat->height = ds_flatheight = SHORT(patch->height);
|
||||
levelflat->width = *flatwidth = SHORT(patch->width);
|
||||
levelflat->height = *flatheight = SHORT(patch->height);
|
||||
|
||||
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);
|
||||
|
@ -604,11 +619,13 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
Z_Free(converted);
|
||||
}
|
||||
}
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
else
|
||||
{
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
*flatwidth = levelflat->width;
|
||||
*flatheight = levelflat->height;
|
||||
}
|
||||
|
||||
levelflat->u.texture.lastnum = levelflat->u.texture.num;
|
||||
|
@ -621,23 +638,14 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
//
|
||||
// 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 hpow2 = (!(ds_flatheight & (ds_flatheight - 1)));
|
||||
boolean wpow2 = (!(flatwidth & (flatwidth - 1)));
|
||||
boolean hpow2 = (!(flatheight & (flatheight - 1)));
|
||||
|
||||
// Initially, the flat isn't powers-of-two-sized.
|
||||
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;
|
||||
return ((flatwidth == flatheight) && (wpow2 && hpow2));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -645,58 +653,58 @@ boolean R_CheckPowersOfTwo(void)
|
|||
//
|
||||
// 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)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
nflatmask = 0x3FF800;
|
||||
nflatxshift = 21;
|
||||
nflatyshift = 10;
|
||||
nflatshiftup = 5;
|
||||
ds_flatwidth = ds_flatheight = 2048;
|
||||
ds->nflatmask = 0x3FF800;
|
||||
ds->nflatxshift = 21;
|
||||
ds->nflatyshift = 10;
|
||||
ds->nflatshiftup = 5;
|
||||
ds->flatwidth = ds->flatheight = 2048;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
nflatmask = 0xFFC00;
|
||||
nflatxshift = 22;
|
||||
nflatyshift = 12;
|
||||
nflatshiftup = 6;
|
||||
ds_flatwidth = ds_flatheight = 1024;
|
||||
ds->nflatmask = 0xFFC00;
|
||||
ds->nflatxshift = 22;
|
||||
ds->nflatyshift = 12;
|
||||
ds->nflatshiftup = 6;
|
||||
ds->flatwidth = ds->flatheight = 1024;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
nflatmask = 0x3FE00;
|
||||
nflatxshift = 23;
|
||||
nflatyshift = 14;
|
||||
nflatshiftup = 7;
|
||||
ds_flatwidth = ds_flatheight = 512;
|
||||
ds->nflatmask = 0x3FE00;
|
||||
ds->nflatxshift = 23;
|
||||
ds->nflatyshift = 14;
|
||||
ds->nflatshiftup = 7;
|
||||
ds->flatwidth = ds->flatheight = 512;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
nflatmask = 0xFF00;
|
||||
nflatxshift = 24;
|
||||
nflatyshift = 16;
|
||||
nflatshiftup = 8;
|
||||
ds_flatwidth = ds_flatheight = 256;
|
||||
ds->nflatmask = 0xFF00;
|
||||
ds->nflatxshift = 24;
|
||||
ds->nflatyshift = 16;
|
||||
ds->nflatshiftup = 8;
|
||||
ds->flatwidth = ds->flatheight = 256;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
nflatmask = 0x3F80;
|
||||
nflatxshift = 25;
|
||||
nflatyshift = 18;
|
||||
nflatshiftup = 9;
|
||||
ds_flatwidth = ds_flatheight = 128;
|
||||
ds->nflatmask = 0x3F80;
|
||||
ds->nflatxshift = 25;
|
||||
ds->nflatyshift = 18;
|
||||
ds->nflatshiftup = 9;
|
||||
ds->flatwidth = ds->flatheight = 128;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
nflatmask = 0x3E0;
|
||||
nflatxshift = 27;
|
||||
nflatyshift = 22;
|
||||
nflatshiftup = 11;
|
||||
ds_flatwidth = ds_flatheight = 32;
|
||||
ds->nflatmask = 0x3E0;
|
||||
ds->nflatxshift = 27;
|
||||
ds->nflatyshift = 22;
|
||||
ds->nflatshiftup = 11;
|
||||
ds->flatwidth = ds->flatheight = 32;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
nflatmask = 0xFC0;
|
||||
nflatxshift = 26;
|
||||
nflatyshift = 20;
|
||||
nflatshiftup = 10;
|
||||
ds_flatwidth = ds_flatheight = 64;
|
||||
ds->nflatmask = 0xFC0;
|
||||
ds->nflatxshift = 26;
|
||||
ds->nflatyshift = 20;
|
||||
ds->nflatshiftup = 10;
|
||||
ds->flatwidth = ds->flatheight = 64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "r_state.h"
|
||||
#include "p_setup.h" // levelflats
|
||||
#include "r_data.h"
|
||||
#include "r_draw.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
|
@ -86,12 +87,12 @@ void R_CheckTextureCache(INT32 tex);
|
|||
void R_ClearTextureNumCache(boolean btell);
|
||||
|
||||
// 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);
|
||||
void *R_GetFlat(lumpnum_t flatnum);
|
||||
|
||||
boolean R_CheckPowersOfTwo(void);
|
||||
void R_CheckFlatLength(size_t size);
|
||||
boolean R_CheckPowersOfTwo(UINT16 flatwidth, UINT16 flatheight);
|
||||
void R_CheckFlatLength(spancontext_t *ds, size_t size);
|
||||
|
||||
// Returns the texture number for the texture 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
|
||||
|
||||
void R_InitSprites(void);
|
||||
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
|
||||
|
@ -37,23 +38,16 @@ void R_AddSpriteDefs(UINT16 wadnum);
|
|||
// MASKED COLUMN DRAWING
|
||||
// ---------------------
|
||||
|
||||
// vars for R_DrawMaskedColumn
|
||||
extern INT16 *mfloorclip;
|
||||
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);
|
||||
void R_DrawMaskedColumn(colcontext_t *dc, column_t *column);
|
||||
void R_DrawFlippedMaskedColumn(colcontext_t *dc, column_t *column);
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
// ----------------
|
||||
|
||||
struct rendercontext_s;
|
||||
struct spritecontext_s;
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
|
@ -62,17 +56,18 @@ extern INT16 screenheightarray[MAXVIDWIDTH];
|
|||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
//SoM: 6/5/2000: Light sprites correctly!
|
||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
void R_InitSprites(void);
|
||||
void R_ClearSprites(void);
|
||||
void R_AddSprites(struct rendercontext_s *context, sector_t *sec, INT32 lightlevel);
|
||||
void R_ClearSprites(struct spritecontext_s *spritecontext);
|
||||
|
||||
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 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);
|
||||
|
||||
boolean R_ThingHorizontallyFlipped (mobj_t *thing);
|
||||
|
@ -99,7 +94,7 @@ typedef struct
|
|||
sector_t* viewsector;
|
||||
} maskcount_t;
|
||||
|
||||
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
|
||||
void R_DrawMasked(struct rendercontext_s *context, maskcount_t *masks, UINT8 nummasks);
|
||||
|
||||
// ----------
|
||||
// VISSPRITES
|
||||
|
@ -210,10 +205,7 @@ typedef struct vissprite_s
|
|||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
} vissprite_t;
|
||||
|
||||
extern UINT32 visspritecount;
|
||||
|
||||
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);
|
||||
void R_ClipSprites(struct rendercontext_s *context, drawseg_t* dsstart, portal_t* portal);
|
||||
|
||||
boolean R_SpriteIsFlashing(vissprite_t *vis);
|
||||
UINT8 *R_GetSpriteTranslation(vissprite_t *vis);
|
||||
|
@ -236,7 +228,7 @@ typedef struct drawnode_s
|
|||
struct drawnode_s *prev;
|
||||
} drawnode_t;
|
||||
|
||||
void R_InitDrawNodes(void);
|
||||
void R_InitDrawNodes(drawnode_t *nodebankhead);
|
||||
|
||||
// -----------------------
|
||||
// SPRITE FRAME CHARACTERS
|
||||
|
|
63
src/screen.c
63
src/screen.c
|
@ -39,20 +39,13 @@
|
|||
#include "hardware/hw_model.h"
|
||||
#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
|
||||
// --------------------------------------------
|
||||
void (*colfunc)(void);
|
||||
void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
||||
colfunc_t colfuncs[COLDRAWFUNC_MAX];
|
||||
|
||||
void (*spanfunc)(void);
|
||||
void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
||||
void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
||||
spanfunc_t spanfuncs[SPANDRAWFUNC_MAX];
|
||||
spanfunc_t spanfuncs_npo2[SPANDRAWFUNC_MAX];
|
||||
|
||||
// ------------------
|
||||
// global video state
|
||||
|
@ -106,17 +99,10 @@ boolean R_SSE2 = false;
|
|||
|
||||
void SCR_SetDrawFuncs(void)
|
||||
{
|
||||
//
|
||||
// setup the right draw routines for either 8bpp or 16bpp
|
||||
//
|
||||
if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code?
|
||||
{
|
||||
// Always run in 8bpp. todo: remove all 16bpp code?
|
||||
colfuncs[BASEDRAWFUNC] = R_DrawColumn_8;
|
||||
spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8;
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
spanfunc = spanfuncs[BASEDRAWFUNC];
|
||||
|
||||
colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_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_WATER] = R_DrawTranslucentWaterSpan_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)
|
||||
|
|
52
src/screen.h
52
src/screen.h
|
@ -112,58 +112,6 @@ typedef struct vmode_s
|
|||
#define NUMSPECIALMODES 4
|
||||
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
|
||||
// -----
|
||||
|
|
|
@ -128,11 +128,9 @@ if(${SDL2_FOUND})
|
|||
if(${SRB2_CONFIG_YASM})
|
||||
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER})
|
||||
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT})
|
||||
set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM)
|
||||
else()
|
||||
set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER})
|
||||
set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT})
|
||||
set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ static char returnWadPath[256];
|
|||
#include "../screen.h" //vid.WndParent
|
||||
#include "../d_net.h"
|
||||
#include "../g_game.h"
|
||||
#include "../r_main.h"
|
||||
#include "../filesrch.h"
|
||||
#include "endtxt.h"
|
||||
#include "sdlmain.h"
|
||||
|
@ -2272,6 +2273,7 @@ INT32 I_StartupSystem(void)
|
|||
#ifdef HAVE_THREADS
|
||||
I_start_threads();
|
||||
I_AddExitFunc(I_stop_threads);
|
||||
I_AddExitFunc(R_StopThreads);
|
||||
#endif
|
||||
I_StartupConsole();
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
|
|
|
@ -155,7 +155,7 @@ Worker (
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
I_thread_handle
|
||||
I_spawn_thread (
|
||||
const char * name,
|
||||
I_thread_fn entry,
|
||||
|
@ -189,6 +189,7 @@ I_spawn_thread (
|
|||
}
|
||||
}
|
||||
I_unlock_mutex(i_thread_pool_mutex);
|
||||
return (I_thread_handle)th;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -354,3 +355,18 @@ I_wake_all_cond (
|
|||
if (SDL_CondBroadcast(cond) == -1)
|
||||
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
|
||||
#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
|
||||
{
|
||||
|
@ -1922,6 +1930,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
if (!TestValidLump(wad,lump))
|
||||
return NULL;
|
||||
|
||||
Lock_state();
|
||||
|
||||
lumpcache = wadfiles[wad]->lumpcache;
|
||||
if (!lumpcache[lump])
|
||||
{
|
||||
|
@ -1931,6 +1941,8 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
else
|
||||
Z_ChangeTag(lumpcache[lump], tag);
|
||||
|
||||
Unlock_state();
|
||||
|
||||
return lumpcache[lump];
|
||||
}
|
||||
|
||||
|
@ -1955,9 +1967,13 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag)
|
|||
if (!TestValidLump(wad,lump))
|
||||
return NULL;
|
||||
|
||||
Lock_state();
|
||||
|
||||
ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, NULL);
|
||||
W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full
|
||||
|
||||
Unlock_state();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -1975,15 +1991,23 @@ static inline boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
|||
if (!TestValidLump(wad, lump))
|
||||
return false;
|
||||
|
||||
Lock_state();
|
||||
|
||||
lcache = wadfiles[wad]->lumpcache[lump];
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr == lcache)
|
||||
if (ptr == lcache) {
|
||||
Unlock_state();
|
||||
return true;
|
||||
}
|
||||
else if (lcache)
|
||||
}
|
||||
else if (lcache) {
|
||||
Unlock_state();
|
||||
return true;
|
||||
}
|
||||
|
||||
Unlock_state();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2007,15 +2031,23 @@ static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
|||
if (!TestValidLump(wad, lump))
|
||||
return false;
|
||||
|
||||
Lock_state();
|
||||
|
||||
lcache = wadfiles[wad]->patchcache[lump];
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr == lcache)
|
||||
if (ptr == lcache) {
|
||||
Unlock_state();
|
||||
return true;
|
||||
}
|
||||
else if (lcache)
|
||||
}
|
||||
else if (lcache) {
|
||||
Unlock_state();
|
||||
return true;
|
||||
}
|
||||
|
||||
Unlock_state();
|
||||
|
||||
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
|
||||
//
|
||||
|
||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
static void *W_CacheSoftwarePatch(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
{
|
||||
lumpcache_t *lumpcache = NULL;
|
||||
|
||||
|
@ -2082,11 +2114,6 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
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)
|
||||
{
|
||||
patch_t *patch;
|
||||
|
@ -2094,16 +2121,23 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
|
||||
patch = W_CacheSoftwarePatchNumPwad(wad, lump, tag);
|
||||
Lock_state();
|
||||
|
||||
patch = W_CacheSoftwarePatch(wad, lump, tag);
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Software-only compile cache the data without conversion
|
||||
if (rendermode == render_soft || rendermode == render_none)
|
||||
#endif
|
||||
{
|
||||
Unlock_state();
|
||||
return (void *)patch;
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
Patch_CreateGL(patch);
|
||||
Unlock_state();
|
||||
|
||||
return (void *)patch;
|
||||
#endif
|
||||
}
|
||||
|
@ -2118,6 +2152,8 @@ void W_UnlockCachedPatch(void *patch)
|
|||
if (!patch)
|
||||
return;
|
||||
|
||||
Lock_state();
|
||||
|
||||
// The hardware code does its own memory management, as its patches
|
||||
// have different lifetimes from software's.
|
||||
#ifdef HWRENDER
|
||||
|
@ -2126,6 +2162,8 @@ void W_UnlockCachedPatch(void *patch)
|
|||
else
|
||||
#endif
|
||||
Z_Unlock(patch);
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
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_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_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
|
||||
#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
|
||||
#include "valgrind.h"
|
||||
static boolean Z_calloc = false;
|
||||
|
@ -203,6 +212,8 @@ void Z_Free(void *ptr)
|
|||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
Lock_state();
|
||||
|
||||
#ifdef ZDEBUG2
|
||||
CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line);
|
||||
#endif
|
||||
|
@ -237,6 +248,8 @@ void Z_Free(void *ptr)
|
|||
block->prev->next = block->next;
|
||||
block->next->prev = block->prev;
|
||||
free(block);
|
||||
|
||||
Unlock_state();
|
||||
}
|
||||
|
||||
/** malloc() that doesn't accept failure.
|
||||
|
@ -295,6 +308,8 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
|||
void *given;
|
||||
size_t blocksize = extrabytes + sizeof *hdr + size;
|
||||
|
||||
Lock_state();
|
||||
|
||||
#ifdef ZDEBUG2
|
||||
CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line);
|
||||
#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 "
|
||||
"(size %s) with no user", sizeu1(size));
|
||||
|
||||
Unlock_state();
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
void *mem;
|
||||
Lock_state();
|
||||
#ifdef VALGRIND_MEMPOOL_ALLOC
|
||||
Z_calloc = true;
|
||||
#endif
|
||||
#ifdef ZDEBUG
|
||||
return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size);
|
||||
mem = Z_Malloc2 (size, tag, user, alignbits, file, line);
|
||||
#else
|
||||
return memset(Z_MallocAlign(size, tag, user, alignbits ), 0, size);
|
||||
mem = Z_MallocAlign(size, tag, user, alignbits );
|
||||
#endif
|
||||
memset(mem, 0, size);
|
||||
Unlock_state();
|
||||
return mem;
|
||||
}
|
||||
|
||||
/** The Z_ReallocAlign function.
|
||||
|
|
Loading…
Reference in a new issue