mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 15:12:11 +00:00
Removal of the software renderer, part 2.
This commit is contained in:
parent
69a5ecd788
commit
d4a1043aa2
24 changed files with 2 additions and 22199 deletions
|
@ -381,9 +381,6 @@ endif()
|
|||
# Start defining source files for ZDoom
|
||||
set( PLAT_WIN32_SOURCES
|
||||
win32/eaxedit.cpp
|
||||
win32/fb_d3d9.cpp
|
||||
win32/fb_d3d9_wipe.cpp
|
||||
win32/fb_ddraw.cpp
|
||||
win32/hardware.cpp
|
||||
win32/helperthread.cpp
|
||||
win32/i_cd.cpp
|
||||
|
@ -671,15 +668,7 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
)
|
||||
|
||||
set( FASTMATH_PCH_SOURCES
|
||||
r_3dfloors.cpp
|
||||
r_bsp.cpp
|
||||
r_draw.cpp
|
||||
r_drawt.cpp
|
||||
r_main.cpp
|
||||
r_plane.cpp
|
||||
r_segs.cpp
|
||||
r_sky.cpp
|
||||
r_things.cpp
|
||||
s_advsound.cpp
|
||||
s_environment.cpp
|
||||
s_playlist.cpp
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
#include "p_local.h"
|
||||
#include "p_blockmap.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "r_bsp.h"
|
||||
#include "r_segs.h"
|
||||
#include "c_cvars.h"
|
||||
#include "m_bbox.h"
|
||||
#include "p_tags.h"
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
** r_3dfloors.cpp
|
||||
** software 3D floors addon
|
||||
**
|
||||
** by kgsws
|
||||
*/
|
||||
|
||||
#include "templates.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "r_local.h"
|
||||
#include "r_bsp.h"
|
||||
#include "r_plane.h"
|
||||
#include "c_cvars.h"
|
||||
#include "r_3dfloors.h"
|
||||
|
||||
// external variables
|
||||
int fake3D;
|
||||
F3DFloor *fakeFloor;
|
||||
fixed_t fakeHeight;
|
||||
fixed_t fakeAlpha;
|
||||
int fakeActive = 0;
|
||||
double sclipBottom;
|
||||
double sclipTop;
|
||||
HeightLevel *height_top = NULL;
|
||||
HeightLevel *height_cur = NULL;
|
||||
int CurrentMirror = 0;
|
||||
int CurrentSkybox = 0;
|
||||
|
||||
CVAR(Int, r_3dfloors, true, 0);
|
||||
|
||||
// private variables
|
||||
int height_max = -1;
|
||||
TArray<HeightStack> toplist;
|
||||
ClipStack *clip_top = NULL;
|
||||
ClipStack *clip_cur = NULL;
|
||||
|
||||
void R_3D_DeleteHeights()
|
||||
{
|
||||
height_cur = height_top;
|
||||
while(height_cur) {
|
||||
height_top = height_cur;
|
||||
height_cur = height_cur->next;
|
||||
M_Free(height_top);
|
||||
}
|
||||
height_max = -1;
|
||||
height_top = height_cur = NULL;
|
||||
}
|
||||
|
||||
void R_3D_AddHeight(secplane_t *add, sector_t *sec)
|
||||
{
|
||||
HeightLevel *near;
|
||||
HeightLevel *curr;
|
||||
|
||||
double fheight = add->ZatPoint(ViewPos);
|
||||
if(fheight >= sec->CenterCeiling()) return;
|
||||
if(fheight <= sec->CenterFloor()) return;
|
||||
|
||||
fixed_t height = FLOAT2FIXED(fheight);
|
||||
fakeActive = 1;
|
||||
|
||||
if(height_max >= 0) {
|
||||
near = height_top;
|
||||
while(near && near->height < height) near = near->next;
|
||||
if(near) {
|
||||
if(near->height == height) return;
|
||||
curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
|
||||
curr->height = height;
|
||||
curr->prev = near->prev;
|
||||
curr->next = near;
|
||||
if(near->prev) near->prev->next = curr;
|
||||
else height_top = curr;
|
||||
near->prev = curr;
|
||||
} else {
|
||||
curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
|
||||
curr->height = height;
|
||||
curr->prev = height_cur;
|
||||
curr->next = NULL;
|
||||
height_cur->next = curr;
|
||||
height_cur = curr;
|
||||
}
|
||||
} else {
|
||||
height_top = height_cur = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
|
||||
height_top->height = height;
|
||||
height_top->prev = NULL;
|
||||
height_top->next = NULL;
|
||||
}
|
||||
height_max++;
|
||||
}
|
||||
|
||||
void R_3D_NewClip()
|
||||
{
|
||||
ClipStack *curr;
|
||||
// extern short floorclip[MAXWIDTH];
|
||||
// extern short ceilingclip[MAXWIDTH];
|
||||
|
||||
curr = (ClipStack*)M_Malloc(sizeof(ClipStack));
|
||||
curr->next = 0;
|
||||
memcpy(curr->floorclip, floorclip, sizeof(short) * MAXWIDTH);
|
||||
memcpy(curr->ceilingclip, ceilingclip, sizeof(short) * MAXWIDTH);
|
||||
curr->ffloor = fakeFloor;
|
||||
assert(fakeFloor->floorclip == NULL);
|
||||
assert(fakeFloor->ceilingclip == NULL);
|
||||
fakeFloor->floorclip = curr->floorclip;
|
||||
fakeFloor->ceilingclip = curr->ceilingclip;
|
||||
if(clip_top) {
|
||||
clip_cur->next = curr;
|
||||
clip_cur = curr;
|
||||
} else {
|
||||
clip_top = clip_cur = curr;
|
||||
}
|
||||
}
|
||||
|
||||
void R_3D_ResetClip()
|
||||
{
|
||||
clip_cur = clip_top;
|
||||
while(clip_cur)
|
||||
{
|
||||
assert(clip_cur->ffloor->floorclip != NULL);
|
||||
assert(clip_cur->ffloor->ceilingclip != NULL);
|
||||
clip_cur->ffloor->ceilingclip = clip_cur->ffloor->floorclip = NULL;
|
||||
clip_top = clip_cur;
|
||||
clip_cur = clip_cur->next;
|
||||
M_Free(clip_top);
|
||||
}
|
||||
clip_cur = clip_top = NULL;
|
||||
}
|
||||
|
||||
void R_3D_EnterSkybox()
|
||||
{
|
||||
HeightStack current;
|
||||
|
||||
current.height_top = height_top;
|
||||
current.height_cur = height_cur;
|
||||
current.height_max = height_max;
|
||||
|
||||
toplist.Push(current);
|
||||
|
||||
height_top = NULL;
|
||||
height_cur = NULL;
|
||||
height_max = -1;
|
||||
|
||||
CurrentSkybox++;
|
||||
}
|
||||
|
||||
void R_3D_LeaveSkybox()
|
||||
{
|
||||
HeightStack current;
|
||||
|
||||
current.height_top = NULL;
|
||||
current.height_cur = NULL;
|
||||
current.height_max = -1;
|
||||
|
||||
toplist.Pop(current);
|
||||
|
||||
height_top = current.height_top;
|
||||
height_cur = current.height_cur;
|
||||
height_max = current.height_max;
|
||||
|
||||
CurrentSkybox--;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
#ifndef SOFT_FAKE3D_H
|
||||
#define SOFT_FAKE3D_H
|
||||
|
||||
#include "p_3dfloors.h"
|
||||
|
||||
// special types
|
||||
|
||||
struct HeightLevel
|
||||
{
|
||||
double height;
|
||||
struct HeightLevel *prev;
|
||||
struct HeightLevel *next;
|
||||
};
|
||||
|
||||
struct HeightStack
|
||||
{
|
||||
HeightLevel *height_top;
|
||||
HeightLevel *height_cur;
|
||||
int height_max;
|
||||
};
|
||||
|
||||
struct ClipStack
|
||||
{
|
||||
short floorclip[MAXWIDTH];
|
||||
short ceilingclip[MAXWIDTH];
|
||||
F3DFloor *ffloor;
|
||||
ClipStack *next;
|
||||
};
|
||||
|
||||
// external varialbes
|
||||
|
||||
// fake3D flags:
|
||||
enum
|
||||
{
|
||||
// BSP stage:
|
||||
FAKE3D_FAKEFLOOR = 1, // fake floor, mark seg as FAKE
|
||||
FAKE3D_FAKECEILING = 2, // fake ceiling, mark seg as FAKE
|
||||
FAKE3D_FAKEBACK = 4, // R_AddLine with fake backsector, mark seg as FAKE
|
||||
FAKE3D_FAKEMASK = 7,
|
||||
FAKE3D_CLIPBOTFRONT = 8, // use front sector clipping info (bottom)
|
||||
FAKE3D_CLIPTOPFRONT = 16, // use front sector clipping info (top)
|
||||
|
||||
// sorting stage:
|
||||
FAKE3D_CLIPBOTTOM = 1, // clip bottom
|
||||
FAKE3D_CLIPTOP = 2, // clip top
|
||||
FAKE3D_REFRESHCLIP = 4, // refresh clip info
|
||||
FAKE3D_DOWN2UP = 8, // rendering from down to up (floors)
|
||||
};
|
||||
|
||||
extern int fake3D;
|
||||
extern F3DFloor *fakeFloor;
|
||||
extern fixed_t fakeAlpha;
|
||||
extern int fakeActive;
|
||||
extern double sclipBottom;
|
||||
extern double sclipTop;
|
||||
extern HeightLevel *height_top;
|
||||
extern HeightLevel *height_cur;
|
||||
extern int CurrentMirror;
|
||||
extern int CurrentSkybox;
|
||||
EXTERN_CVAR(Int, r_3dfloors);
|
||||
|
||||
// functions
|
||||
void R_3D_DeleteHeights();
|
||||
void R_3D_AddHeight(secplane_t *add, sector_t *sec);
|
||||
void R_3D_NewClip();
|
||||
void R_3D_ResetClip();
|
||||
void R_3D_EnterSkybox();
|
||||
void R_3D_LeaveSkybox();
|
||||
|
||||
#endif
|
1389
src/r_bsp.cpp
1389
src/r_bsp.cpp
File diff suppressed because it is too large
Load diff
123
src/r_bsp.h
123
src/r_bsp.h
|
@ -1,123 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Refresh module, BSP traversal and handling.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_BSP__
|
||||
#define __R_BSP__
|
||||
|
||||
#include "tarray.h"
|
||||
#include <stddef.h>
|
||||
#include "r_defs.h"
|
||||
|
||||
// The 3072 below is just an arbitrary value picked to avoid
|
||||
// drawing lines the player is too close to that would overflow
|
||||
// the texture calculations.
|
||||
#define TOO_CLOSE_Z (3072.0 / (1<<12))
|
||||
|
||||
struct FWallCoords
|
||||
{
|
||||
FVector2 tleft; // coords at left of wall in view space rx1,ry1
|
||||
FVector2 tright; // coords at right of wall in view space rx2,ry2
|
||||
|
||||
float sz1, sz2; // depth at left, right of wall in screen space yb1,yb2
|
||||
short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2
|
||||
|
||||
bool Init(const DVector2 &pt1, const DVector2 &pt2, double too_close);
|
||||
};
|
||||
|
||||
struct FWallTmapVals
|
||||
{
|
||||
float UoverZorg, UoverZstep;
|
||||
float InvZorg, InvZstep;
|
||||
|
||||
void InitFromWallCoords(const FWallCoords *wallc);
|
||||
void InitFromLine(const DVector2 &left, const DVector2 &right);
|
||||
};
|
||||
|
||||
extern FWallCoords WallC;
|
||||
extern FWallTmapVals WallT;
|
||||
|
||||
enum
|
||||
{
|
||||
FAKED_Center,
|
||||
FAKED_BelowFloor,
|
||||
FAKED_AboveCeiling
|
||||
};
|
||||
|
||||
struct drawseg_t
|
||||
{
|
||||
seg_t* curline;
|
||||
float light, lightstep;
|
||||
float iscale, iscalestep;
|
||||
short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg
|
||||
short sx1, sx2; // left, right of parent seg on screen
|
||||
float sz1, sz2; // z for left, right of parent seg on screen
|
||||
float siz1, siz2; // 1/z for left, right of parent seg on screen
|
||||
float cx, cy, cdx, cdy;
|
||||
float yscale;
|
||||
BYTE silhouette; // 0=none, 1=bottom, 2=top, 3=both
|
||||
BYTE bFogBoundary;
|
||||
BYTE bFakeBoundary; // for fake walls
|
||||
int shade;
|
||||
// Pointers to lists for sprite clipping,
|
||||
// all three adjusted so [x1] is first value.
|
||||
ptrdiff_t sprtopclip; // type short
|
||||
ptrdiff_t sprbottomclip; // type short
|
||||
ptrdiff_t maskedtexturecol; // type short
|
||||
ptrdiff_t swall; // type float
|
||||
int fake; // ident fake drawseg, don't draw and clip sprites
|
||||
// backups
|
||||
ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures
|
||||
FWallTmapVals tmapvals;
|
||||
int CurrentPortalUniq; // [ZZ] to identify the portal that this drawseg is in. used for sprite clipping.
|
||||
};
|
||||
|
||||
|
||||
extern seg_t* curline;
|
||||
extern side_t* sidedef;
|
||||
extern line_t* linedef;
|
||||
extern sector_t* frontsector;
|
||||
extern sector_t* backsector;
|
||||
|
||||
extern drawseg_t *drawsegs;
|
||||
extern drawseg_t *firstdrawseg;
|
||||
extern drawseg_t* ds_p;
|
||||
|
||||
extern TArray<size_t> InterestingDrawsegs; // drawsegs that have something drawn on them
|
||||
extern size_t FirstInterestingDrawseg;
|
||||
|
||||
extern int WindowLeft, WindowRight;
|
||||
extern WORD MirrorFlags;
|
||||
|
||||
typedef void (*drawfunc_t) (int start, int stop);
|
||||
|
||||
EXTERN_CVAR (Bool, r_drawflat) // [RH] Don't texture segs?
|
||||
|
||||
// BSP?
|
||||
void R_ClearClipSegs (short left, short right);
|
||||
void R_ClearDrawSegs ();
|
||||
void R_RenderBSPNode (void *node);
|
||||
|
||||
// killough 4/13/98: fake floors/ceilings for deep water / fake ceilings:
|
||||
sector_t *R_FakeFlat(sector_t *, sector_t *, int *, int *, bool);
|
||||
|
||||
|
||||
#endif
|
2489
src/r_draw.cpp
2489
src/r_draw.cpp
File diff suppressed because it is too large
Load diff
296
src/r_draw.h
296
src/r_draw.h
|
@ -1,296 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System specific interface stuff.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_DRAW__
|
||||
#define __R_DRAW__
|
||||
|
||||
#include "r_defs.h"
|
||||
|
||||
extern "C" int ylookup[MAXHEIGHT];
|
||||
|
||||
extern "C" int dc_pitch; // [RH] Distance between rows
|
||||
|
||||
extern "C" lighttable_t*dc_colormap;
|
||||
extern "C" int dc_x;
|
||||
extern "C" int dc_yl;
|
||||
extern "C" int dc_yh;
|
||||
extern "C" fixed_t dc_iscale;
|
||||
extern double dc_texturemid;
|
||||
extern "C" fixed_t dc_texturefrac;
|
||||
extern "C" int dc_color; // [RH] For flat colors (no texturing)
|
||||
extern "C" DWORD dc_srccolor;
|
||||
extern "C" DWORD *dc_srcblend;
|
||||
extern "C" DWORD *dc_destblend;
|
||||
|
||||
// first pixel in a column
|
||||
extern "C" const BYTE* dc_source;
|
||||
|
||||
extern "C" BYTE *dc_dest, *dc_destorg;
|
||||
extern "C" int dc_count;
|
||||
|
||||
extern "C" DWORD vplce[4];
|
||||
extern "C" DWORD vince[4];
|
||||
extern "C" BYTE* palookupoffse[4];
|
||||
extern "C" const BYTE* bufplce[4];
|
||||
|
||||
// [RH] Temporary buffer for column drawing
|
||||
extern "C" BYTE *dc_temp;
|
||||
extern "C" unsigned int dc_tspans[4][MAXHEIGHT];
|
||||
extern "C" unsigned int *dc_ctspan[4];
|
||||
extern "C" unsigned int horizspans[4];
|
||||
|
||||
|
||||
// [RH] Pointers to the different column and span drawers...
|
||||
|
||||
// The span blitting interface.
|
||||
// Hook in assembler or system specific BLT here.
|
||||
extern void (*R_DrawColumn)(void);
|
||||
|
||||
extern DWORD (*dovline1) ();
|
||||
extern DWORD (*doprevline1) ();
|
||||
#ifdef X64_ASM
|
||||
#define dovline4 vlinetallasm4
|
||||
extern "C" void vlinetallasm4();
|
||||
#else
|
||||
extern void (*dovline4) ();
|
||||
#endif
|
||||
extern void setupvline (int);
|
||||
|
||||
extern DWORD (*domvline1) ();
|
||||
extern void (*domvline4) ();
|
||||
extern void setupmvline (int);
|
||||
|
||||
extern void setuptmvline (int);
|
||||
|
||||
// The Spectre/Invisibility effect.
|
||||
extern void (*R_DrawFuzzColumn)(void);
|
||||
|
||||
// [RH] Draw shaded column
|
||||
extern void (*R_DrawShadedColumn)(void);
|
||||
|
||||
// Draw with color translation tables, for player sprite rendering,
|
||||
// Green/Red/Blue/Indigo shirts.
|
||||
extern void (*R_DrawTranslatedColumn)(void);
|
||||
|
||||
// Span drawing for rows, floor/ceiling. No Spectre effect needed.
|
||||
extern void (*R_DrawSpan)(void);
|
||||
void R_SetupSpanBits(FTexture *tex);
|
||||
void R_SetSpanColormap(BYTE *colormap);
|
||||
void R_SetSpanSource(const BYTE *pixels);
|
||||
|
||||
// Span drawing for masked textures.
|
||||
extern void (*R_DrawSpanMasked)(void);
|
||||
|
||||
// Span drawing for translucent textures.
|
||||
extern void (*R_DrawSpanTranslucent)(void);
|
||||
|
||||
// Span drawing for masked, translucent textures.
|
||||
extern void (*R_DrawSpanMaskedTranslucent)(void);
|
||||
|
||||
// Span drawing for translucent, additive textures.
|
||||
extern void (*R_DrawSpanAddClamp)(void);
|
||||
|
||||
// Span drawing for masked, translucent, additive textures.
|
||||
extern void (*R_DrawSpanMaskedAddClamp)(void);
|
||||
|
||||
// [RH] Span blit into an interleaved intermediate buffer
|
||||
extern void (*R_DrawColumnHoriz)(void);
|
||||
void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *spans);
|
||||
|
||||
// [RH] Initialize the above pointers
|
||||
void R_InitColumnDrawers ();
|
||||
|
||||
// [RH] Moves data from the temporary buffer to the screen.
|
||||
extern "C"
|
||||
{
|
||||
void rt_copy1col_c (int hx, int sx, int yl, int yh);
|
||||
void rt_copy4cols_c (int sx, int yl, int yh);
|
||||
|
||||
void rt_shaded1col (int hx, int sx, int yl, int yh);
|
||||
void rt_shaded4cols_c (int sx, int yl, int yh);
|
||||
void rt_shaded4cols_asm (int sx, int yl, int yh);
|
||||
|
||||
void rt_map1col_c (int hx, int sx, int yl, int yh);
|
||||
void rt_add1col (int hx, int sx, int yl, int yh);
|
||||
void rt_addclamp1col (int hx, int sx, int yl, int yh);
|
||||
void rt_subclamp1col (int hx, int sx, int yl, int yh);
|
||||
void rt_revsubclamp1col (int hx, int sx, int yl, int yh);
|
||||
|
||||
void rt_tlate1col (int hx, int sx, int yl, int yh);
|
||||
void rt_tlateadd1col (int hx, int sx, int yl, int yh);
|
||||
void rt_tlateaddclamp1col (int hx, int sx, int yl, int yh);
|
||||
void rt_tlatesubclamp1col (int hx, int sx, int yl, int yh);
|
||||
void rt_tlaterevsubclamp1col (int hx, int sx, int yl, int yh);
|
||||
|
||||
void rt_map4cols_c (int sx, int yl, int yh);
|
||||
void rt_add4cols_c (int sx, int yl, int yh);
|
||||
void rt_addclamp4cols_c (int sx, int yl, int yh);
|
||||
void rt_subclamp4cols (int sx, int yl, int yh);
|
||||
void rt_revsubclamp4cols (int sx, int yl, int yh);
|
||||
|
||||
void rt_tlate4cols (int sx, int yl, int yh);
|
||||
void rt_tlateadd4cols (int sx, int yl, int yh);
|
||||
void rt_tlateaddclamp4cols (int sx, int yl, int yh);
|
||||
void rt_tlatesubclamp4cols (int sx, int yl, int yh);
|
||||
void rt_tlaterevsubclamp4cols (int sx, int yl, int yh);
|
||||
|
||||
void rt_copy1col_asm (int hx, int sx, int yl, int yh);
|
||||
void rt_map1col_asm (int hx, int sx, int yl, int yh);
|
||||
|
||||
void rt_copy4cols_asm (int sx, int yl, int yh);
|
||||
void rt_map4cols_asm1 (int sx, int yl, int yh);
|
||||
void rt_map4cols_asm2 (int sx, int yl, int yh);
|
||||
void rt_add4cols_asm (int sx, int yl, int yh);
|
||||
void rt_addclamp4cols_asm (int sx, int yl, int yh);
|
||||
}
|
||||
|
||||
extern void (*rt_map4cols)(int sx, int yl, int yh);
|
||||
|
||||
#ifdef X86_ASM
|
||||
#define rt_copy1col rt_copy1col_asm
|
||||
#define rt_copy4cols rt_copy4cols_asm
|
||||
#define rt_map1col rt_map1col_asm
|
||||
#define rt_shaded4cols rt_shaded4cols_asm
|
||||
#define rt_add4cols rt_add4cols_asm
|
||||
#define rt_addclamp4cols rt_addclamp4cols_asm
|
||||
#else
|
||||
#define rt_copy1col rt_copy1col_c
|
||||
#define rt_copy4cols rt_copy4cols_c
|
||||
#define rt_map1col rt_map1col_c
|
||||
#define rt_shaded4cols rt_shaded4cols_c
|
||||
#define rt_add4cols rt_add4cols_c
|
||||
#define rt_addclamp4cols rt_addclamp4cols_c
|
||||
#endif
|
||||
|
||||
void rt_draw4cols (int sx);
|
||||
|
||||
// [RH] Preps the temporary horizontal buffer.
|
||||
void rt_initcols (BYTE *buffer=NULL);
|
||||
|
||||
void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip);
|
||||
|
||||
|
||||
#ifdef X86_ASM
|
||||
|
||||
extern "C" void R_DrawColumnP_Unrolled (void);
|
||||
extern "C" void R_DrawColumnHorizP_ASM (void);
|
||||
extern "C" void R_DrawColumnP_ASM (void);
|
||||
extern "C" void R_DrawFuzzColumnP_ASM (void);
|
||||
void R_DrawTranslatedColumnP_C (void);
|
||||
void R_DrawShadedColumnP_C (void);
|
||||
extern "C" void R_DrawSpanP_ASM (void);
|
||||
extern "C" void R_DrawSpanMaskedP_ASM (void);
|
||||
|
||||
#else
|
||||
|
||||
void R_DrawColumnHorizP_C (void);
|
||||
void R_DrawColumnP_C (void);
|
||||
void R_DrawFuzzColumnP_C (void);
|
||||
void R_DrawTranslatedColumnP_C (void);
|
||||
void R_DrawShadedColumnP_C (void);
|
||||
void R_DrawSpanP_C (void);
|
||||
void R_DrawSpanMaskedP_C (void);
|
||||
|
||||
#endif
|
||||
|
||||
void R_DrawSpanTranslucentP_C (void);
|
||||
void R_DrawSpanMaskedTranslucentP_C (void);
|
||||
|
||||
void R_DrawTlatedLucentColumnP_C (void);
|
||||
#define R_DrawTlatedLucentColumn R_DrawTlatedLucentColumnP_C
|
||||
|
||||
void R_FillColumnP (void);
|
||||
void R_FillColumnHorizP (void);
|
||||
void R_FillSpan (void);
|
||||
|
||||
#ifdef X86_ASM
|
||||
#define R_SetupDrawSlab R_SetupDrawSlabA
|
||||
#define R_DrawSlab R_DrawSlabA
|
||||
#else
|
||||
#define R_SetupDrawSlab R_SetupDrawSlabC
|
||||
#define R_DrawSlab R_DrawSlabC
|
||||
#endif
|
||||
|
||||
extern "C" void R_SetupDrawSlab(const BYTE *colormap);
|
||||
extern "C" void R_DrawSlab(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *vptr, BYTE *p);
|
||||
|
||||
extern "C" int ds_y;
|
||||
extern "C" int ds_x1;
|
||||
extern "C" int ds_x2;
|
||||
|
||||
extern "C" lighttable_t* ds_colormap;
|
||||
|
||||
extern "C" dsfixed_t ds_xfrac;
|
||||
extern "C" dsfixed_t ds_yfrac;
|
||||
extern "C" dsfixed_t ds_xstep;
|
||||
extern "C" dsfixed_t ds_ystep;
|
||||
extern "C" int ds_xbits;
|
||||
extern "C" int ds_ybits;
|
||||
extern "C" fixed_t ds_alpha;
|
||||
|
||||
// start of a 64*64 tile image
|
||||
extern "C" const BYTE* ds_source;
|
||||
|
||||
extern "C" int ds_color; // [RH] For flat color (no texturing)
|
||||
|
||||
extern BYTE shadetables[/*NUMCOLORMAPS*16*256*/];
|
||||
extern FDynamicColormap ShadeFakeColormap[16];
|
||||
extern BYTE identitymap[256];
|
||||
extern BYTE *dc_translation;
|
||||
|
||||
// [RH] Added for muliresolution support
|
||||
void R_InitShadeMaps();
|
||||
void R_InitFuzzTable (int fuzzoff);
|
||||
|
||||
// [RH] Consolidate column drawer selection
|
||||
enum ESPSResult
|
||||
{
|
||||
DontDraw, // not useful to draw this
|
||||
DoDraw0, // draw this as if r_columnmethod is 0
|
||||
DoDraw1, // draw this as if r_columnmethod is 1
|
||||
};
|
||||
ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color);
|
||||
inline ESPSResult R_SetPatchStyle(FRenderStyle style, float alpha, int translation, DWORD color)
|
||||
{
|
||||
return R_SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color);
|
||||
}
|
||||
|
||||
// Call this after finished drawing the current thing, in case its
|
||||
// style was STYLE_Shade
|
||||
void R_FinishSetPatchStyle ();
|
||||
|
||||
// transmaskwallscan calls this to find out what column drawers to use
|
||||
bool R_GetTransMaskDrawers (fixed_t (**tmvline1)(), void (**tmvline4)());
|
||||
|
||||
// Retrieve column data for wallscan. Should probably be removed
|
||||
// to just use the texture's GetColumn() method. It just exists
|
||||
// for double-layer skies.
|
||||
const BYTE *R_GetColumn (FTexture *tex, int col);
|
||||
void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||
|
||||
// maskwallscan is exactly like wallscan but does not draw anything where the texture is color 0.
|
||||
void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||
|
||||
// transmaskwallscan is like maskwallscan, but it can also blend to the background
|
||||
void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int col)=R_GetColumn);
|
||||
|
||||
#endif
|
1203
src/r_drawt.cpp
1203
src/r_drawt.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,41 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Refresh (R_*) module, global header.
|
||||
// All the rendering/drawing stuff is here.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __R_LOCAL_H__
|
||||
#define __R_LOCAL_H__
|
||||
|
||||
// Binary Angles, sine/cosine/atan lookups.
|
||||
#include "tables.h"
|
||||
|
||||
// Screen size related parameters.
|
||||
#include "doomdef.h"
|
||||
|
||||
// Include the refresh/render data structs.
|
||||
|
||||
//
|
||||
// Separate header file for each module.
|
||||
//
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
#include "r_draw.h"
|
||||
|
||||
#endif // __R_LOCAL_H__
|
1112
src/r_main.cpp
1112
src/r_main.cpp
File diff suppressed because it is too large
Load diff
146
src/r_main.h
146
src/r_main.h
|
@ -1,146 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System specific interface stuff.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_MAIN_H__
|
||||
#define __R_MAIN_H__
|
||||
|
||||
#include "r_utility.h"
|
||||
#include "d_player.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
|
||||
typedef BYTE lighttable_t; // This could be wider for >8 bit display.
|
||||
|
||||
//
|
||||
// POV related.
|
||||
//
|
||||
extern bool bRenderingToCanvas;
|
||||
extern double ViewCos;
|
||||
extern double ViewSin;
|
||||
extern fixed_t viewingrangerecip;
|
||||
extern double FocalLengthX, FocalLengthY;
|
||||
extern double InvZtoScale;
|
||||
|
||||
extern double WallTMapScale2;
|
||||
|
||||
extern int viewwindowx;
|
||||
extern int viewwindowy;
|
||||
|
||||
extern double CenterX;
|
||||
extern double CenterY;
|
||||
extern double YaspectMul;
|
||||
extern double IYaspectMul;
|
||||
|
||||
extern FDynamicColormap*basecolormap; // [RH] Colormap for sector currently being drawn
|
||||
|
||||
extern int linecount;
|
||||
extern int loopcount;
|
||||
|
||||
extern bool r_dontmaplines;
|
||||
|
||||
//
|
||||
// Lighting.
|
||||
//
|
||||
// [RH] This has changed significantly from Doom, which used lookup
|
||||
// tables based on 1/z for walls and z for flats and only recognized
|
||||
// 16 discrete light levels. The terminology I use is borrowed from Build.
|
||||
//
|
||||
|
||||
// The size of a single colormap, in bits
|
||||
#define COLORMAPSHIFT 8
|
||||
|
||||
// Convert a light level into an unbounded colormap index (shade). Result is
|
||||
// fixed point. Why the +12? I wish I knew, but experimentation indicates it
|
||||
// is necessary in order to best reproduce Doom's original lighting.
|
||||
#define LIGHT2SHADE(l) ((NUMCOLORMAPS*2*FRACUNIT)-(((l)+12)*(FRACUNIT*NUMCOLORMAPS/128)))
|
||||
|
||||
// MAXLIGHTSCALE from original DOOM, divided by 2.
|
||||
#define MAXLIGHTVIS (24.0)
|
||||
|
||||
// Convert a shade and visibility to a clamped colormap index.
|
||||
// Result is not fixed point.
|
||||
// Change R_CalcTiltedLighting() when this changes.
|
||||
#define GETPALOOKUP(vis,shade) (clamp<int> (((shade)-FLOAT2FIXED(MIN(MAXLIGHTVIS,double(vis))))>>FRACBITS, 0, NUMCOLORMAPS-1))
|
||||
|
||||
extern double GlobVis;
|
||||
|
||||
void R_SetVisibility(double visibility);
|
||||
double R_GetVisibility();
|
||||
|
||||
extern double r_BaseVisibility;
|
||||
extern double r_WallVisibility;
|
||||
extern double r_FloorVisibility;
|
||||
extern float r_TiltVisibility;
|
||||
extern double r_SpriteVisibility;
|
||||
|
||||
extern int r_actualextralight;
|
||||
extern bool foggy;
|
||||
extern int fixedlightlev;
|
||||
extern lighttable_t* fixedcolormap;
|
||||
extern FSpecialColormap*realfixedcolormap;
|
||||
|
||||
|
||||
//
|
||||
// Function pointers to switch refresh/drawing functions.
|
||||
// Used to select shadow mode etc.
|
||||
//
|
||||
extern void (*colfunc) (void);
|
||||
extern void (*basecolfunc) (void);
|
||||
extern void (*fuzzcolfunc) (void);
|
||||
extern void (*transcolfunc) (void);
|
||||
// No shadow effects on floors.
|
||||
extern void (*spanfunc) (void);
|
||||
|
||||
// [RH] Function pointers for the horizontal column drawers.
|
||||
extern void (*hcolfunc_pre) (void);
|
||||
extern void (*hcolfunc_post1) (int hx, int sx, int yl, int yh);
|
||||
extern void (*hcolfunc_post2) (int hx, int sx, int yl, int yh);
|
||||
extern void (*hcolfunc_post4) (int sx, int yl, int yh);
|
||||
|
||||
|
||||
void R_InitTextureMapping ();
|
||||
|
||||
|
||||
//
|
||||
// REFRESH - the actual rendering functions.
|
||||
//
|
||||
|
||||
// Called by G_Drawer.
|
||||
void R_RenderActorView (AActor *actor, bool dontmaplines = false);
|
||||
void R_SetupBuffer ();
|
||||
|
||||
void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines = false);
|
||||
|
||||
// [RH] Initialize multires stuff for renderer
|
||||
void R_MultiresInit (void);
|
||||
|
||||
|
||||
extern int stacked_extralight;
|
||||
extern double stacked_visibility;
|
||||
extern DVector3 stacked_viewpos;
|
||||
extern DAngle stacked_angle;
|
||||
|
||||
extern void R_CopyStackedViewParameters();
|
||||
|
||||
|
||||
#endif // __R_MAIN_H__
|
1836
src/r_plane.cpp
1836
src/r_plane.cpp
File diff suppressed because it is too large
Load diff
117
src/r_plane.h
117
src/r_plane.h
|
@ -1,117 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Refresh, visplane stuff (floor, ceilings).
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_PLANE_H__
|
||||
#define __R_PLANE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
class ASkyViewpoint;
|
||||
|
||||
//
|
||||
// The infamous visplane
|
||||
//
|
||||
struct visplane_s
|
||||
{
|
||||
struct visplane_s *next; // Next visplane in hash chain -- killough
|
||||
|
||||
secplane_t height;
|
||||
FTextureID picnum;
|
||||
int lightlevel;
|
||||
fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats
|
||||
int left, right;
|
||||
FDynamicColormap *colormap; // [RH] Support multiple colormaps
|
||||
fixed_t xscale, yscale; // [RH] Support flat scaling
|
||||
angle_t angle; // [RH] Support flat rotation
|
||||
int sky;
|
||||
FSectorPortal *portal; // [RH] Support sky boxes
|
||||
|
||||
// [RH] This set of variables copies information from the time when the
|
||||
// visplane is created. They are only used by stacks so that you can
|
||||
// have stacked sectors inside a skybox. If the visplane is not for a
|
||||
// stack, then they are unused.
|
||||
int extralight;
|
||||
double visibility;
|
||||
DVector3 viewpos;
|
||||
DAngle viewangle;
|
||||
fixed_t Alpha;
|
||||
bool Additive;
|
||||
|
||||
// kg3D - keep track of mirror and skybox owner
|
||||
int CurrentSkybox;
|
||||
int CurrentPortalUniq; // mirror counter, counts all of them
|
||||
int MirrorFlags; // this is not related to CurrentMirror
|
||||
|
||||
unsigned short *bottom; // [RH] bottom and top arrays are dynamically
|
||||
unsigned short pad; // allocated immediately after the
|
||||
unsigned short top[]; // visplane.
|
||||
};
|
||||
typedef struct visplane_s visplane_t;
|
||||
|
||||
|
||||
|
||||
// Visplane related.
|
||||
extern ptrdiff_t lastopening; // type short
|
||||
|
||||
|
||||
typedef void (*planefunction_t) (int top, int bottom);
|
||||
|
||||
extern planefunction_t floorfunc;
|
||||
extern planefunction_t ceilingfunc_t;
|
||||
|
||||
extern short floorclip[MAXWIDTH];
|
||||
extern short ceilingclip[MAXWIDTH];
|
||||
|
||||
extern fixed_t yslope[MAXHEIGHT];
|
||||
|
||||
void R_InitPlanes ();
|
||||
void R_DeinitPlanes ();
|
||||
void R_ClearPlanes (bool fullclear);
|
||||
|
||||
int R_DrawPlanes ();
|
||||
void R_DrawPortals ();
|
||||
void R_DrawSkyPlane (visplane_t *pl);
|
||||
void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||
void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked);
|
||||
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1));
|
||||
|
||||
visplane_t *R_FindPlane
|
||||
( const secplane_t &height,
|
||||
FTextureID picnum,
|
||||
int lightlevel,
|
||||
double alpha,
|
||||
bool additive,
|
||||
const FTransform &xform,
|
||||
int sky,
|
||||
FSectorPortal *portal);
|
||||
|
||||
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
|
||||
|
||||
|
||||
// [RH] Added for multires support
|
||||
bool R_PlaneInitData (void);
|
||||
|
||||
|
||||
extern visplane_t* floorplane;
|
||||
extern visplane_t* ceilingplane;
|
||||
|
||||
#endif // __R_PLANE_H__
|
3311
src/r_segs.cpp
3311
src/r_segs.cpp
File diff suppressed because it is too large
Load diff
73
src/r_segs.h
73
src/r_segs.h
|
@ -1,73 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Refresh module, drawing LineSegs from BSP.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_SEGS_H__
|
||||
#define __R_SEGS_H__
|
||||
|
||||
struct drawseg_t;
|
||||
|
||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2);
|
||||
|
||||
extern short *openings;
|
||||
extern ptrdiff_t lastopening;
|
||||
extern size_t maxopenings;
|
||||
|
||||
int OWallMost (short *mostbuf, double z, const FWallCoords *wallc);
|
||||
int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc);
|
||||
void PrepWall (float *swall, fixed_t *lwall, double walxrepeat, int x1, int x2);
|
||||
void PrepLWall (fixed_t *lwall, double walxrepeat, int x1, int x2);
|
||||
|
||||
ptrdiff_t R_NewOpening (ptrdiff_t len);
|
||||
|
||||
void R_CheckDrawSegs ();
|
||||
|
||||
void R_RenderSegLoop ();
|
||||
|
||||
extern float swall[MAXWIDTH];
|
||||
extern fixed_t lwall[MAXWIDTH];
|
||||
extern float rw_light; // [RH] Scale lights with viewsize adjustments
|
||||
extern float rw_lightstep;
|
||||
extern float rw_lightleft;
|
||||
extern fixed_t rw_offset;
|
||||
|
||||
/* portal structure, this is used in r_ code in order to store drawsegs with portals (and mirrors) */
|
||||
struct PortalDrawseg
|
||||
{
|
||||
line_t* src; // source line (the one drawn) this doesn't change over render loops
|
||||
line_t* dst; // destination line (the one that the portal is linked with, equals 'src' for mirrors)
|
||||
|
||||
int x1; // drawseg x1
|
||||
int x2; // drawseg x2
|
||||
|
||||
int len;
|
||||
TArray<short> ceilingclip;
|
||||
TArray<short> floorclip;
|
||||
|
||||
bool mirror; // true if this is a mirror (src should equal dst)
|
||||
};
|
||||
|
||||
extern PortalDrawseg* CurrentPortal;
|
||||
extern int CurrentPortalUniq;
|
||||
extern bool CurrentPortalInSkybox;
|
||||
extern TArray<PortalDrawseg> WallPortals;
|
||||
|
||||
#endif
|
3202
src/r_things.cpp
3202
src/r_things.cpp
File diff suppressed because it is too large
Load diff
145
src/r_things.h
145
src/r_things.h
|
@ -1,145 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Rendering of moving objects, sprites.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __R_THINGS__
|
||||
#define __R_THINGS__
|
||||
|
||||
#include "r_bsp.h"
|
||||
|
||||
// A vissprite_t is a thing
|
||||
// that will be drawn during a refresh.
|
||||
// I.e. a sprite object that is partly visible.
|
||||
|
||||
struct vissprite_t
|
||||
{
|
||||
struct posang
|
||||
{
|
||||
FVector3 vpos; // view origin
|
||||
FAngle vang; // view angle
|
||||
};
|
||||
|
||||
short x1, x2;
|
||||
FVector3 gpos; // origin in world coordinates
|
||||
union
|
||||
{
|
||||
float gzb, gzt; // global bottom / top for silhouette clipping
|
||||
int y1, y2; // top / bottom of particle on screen
|
||||
};
|
||||
angle_t angle;
|
||||
fixed_t xscale;
|
||||
float yscale;
|
||||
float depth;
|
||||
float idepth; // 1/z
|
||||
float deltax, deltay;
|
||||
DWORD FillColor;
|
||||
double floorclip;
|
||||
union
|
||||
{
|
||||
FTexture *pic;
|
||||
struct FVoxel *voxel;
|
||||
};
|
||||
union
|
||||
{
|
||||
// Used by face sprites
|
||||
struct
|
||||
{
|
||||
double texturemid;
|
||||
fixed_t startfrac; // horizontal position of x1
|
||||
fixed_t xiscale; // negative if flipped
|
||||
};
|
||||
// Used by wall sprites
|
||||
FWallCoords wallc;
|
||||
// Used by voxels
|
||||
posang pa;
|
||||
};
|
||||
sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling
|
||||
sector_t *sector; // [RH] sector this sprite is in
|
||||
F3DFloor *fakefloor;
|
||||
F3DFloor *fakeceiling;
|
||||
BYTE bIsVoxel:1; // [RH] Use voxel instead of pic
|
||||
BYTE bWallSprite:1; // [RH] This is a wall sprite
|
||||
BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg
|
||||
BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror
|
||||
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
|
||||
BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer)
|
||||
short renderflags;
|
||||
DWORD Translation; // [RH] for color translation
|
||||
visstyle_t Style;
|
||||
int CurrentPortalUniq; // [ZZ] to identify the portal that this thing is in. used for clipping.
|
||||
|
||||
vissprite_t() {}
|
||||
};
|
||||
|
||||
struct particle_t;
|
||||
|
||||
void R_DrawParticle (vissprite_t *);
|
||||
void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);
|
||||
|
||||
extern int MaxVisSprites;
|
||||
|
||||
extern vissprite_t **vissprites, **firstvissprite;
|
||||
extern vissprite_t **vissprite_p;
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern short zeroarray[MAXWIDTH];
|
||||
extern short screenheightarray[MAXWIDTH];
|
||||
|
||||
// vars for R_DrawMaskedColumn
|
||||
extern short* mfloorclip;
|
||||
extern short* mceilingclip;
|
||||
extern double spryscale;
|
||||
extern double sprtopscreen;
|
||||
extern bool sprflipvert;
|
||||
|
||||
extern double pspritexscale;
|
||||
extern double pspritexiscale;
|
||||
extern double pspriteyscale;
|
||||
|
||||
extern FTexture *WallSpriteTile;
|
||||
|
||||
|
||||
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans);
|
||||
void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans));
|
||||
|
||||
void R_CacheSprite (spritedef_t *sprite);
|
||||
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
||||
void R_AddSprites (sector_t *sec, int lightlevel, int fakeside);
|
||||
void R_AddPSprites ();
|
||||
void R_DrawSprites ();
|
||||
void R_ClearSprites ();
|
||||
void R_DrawMasked ();
|
||||
void R_DrawRemainingPlayerSprites ();
|
||||
|
||||
void R_CheckOffscreenBuffer(int width, int height, bool spansonly);
|
||||
|
||||
enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
|
||||
|
||||
void R_DrawVoxel(const FVector3 &viewpos, FAngle viewangle,
|
||||
const FVector3 &sprpos, angle_t dasprang,
|
||||
fixed_t daxscale, fixed_t dayscale, struct FVoxel *voxobj,
|
||||
lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags);
|
||||
|
||||
void R_ClipVisSprite (vissprite_t *vis, int xl, int xh);
|
||||
|
||||
|
||||
#endif
|
|
@ -32,7 +32,7 @@
|
|||
**
|
||||
*/
|
||||
|
||||
// #define NO_SWRENDER // set this if you want to exclude the software renderer. Without software renderer the base implementations of DrawTextureV and FillSimplePoly need to be disabled because they depend on it.
|
||||
#define NO_SWRENDER // set this if you want to exclude the software renderer. Without software renderer the base implementations of DrawTextureV and FillSimplePoly need to be disabled because they depend on it.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -42,11 +42,6 @@
|
|||
#include "m_swap.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_utility.h"
|
||||
#ifndef NO_SWRENDER
|
||||
#include "r_draw.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
#endif
|
||||
#include "r_data/r_translate.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_palette.h"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,658 +0,0 @@
|
|||
/*
|
||||
** fb_d3d9_wipe.cpp
|
||||
** Implements the different screen wipes using Direct3D calls.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define D3D_DEBUG_INFO
|
||||
#endif
|
||||
#define DIRECT3D_VERSION 0x0900
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define USE_WINDOWS_DWORD
|
||||
#include "doomtype.h"
|
||||
#include "f_wipe.h"
|
||||
#include "win32iface.h"
|
||||
#include "templates.h"
|
||||
#include "m_random.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class D3DFB::Wiper_Crossfade : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Crossfade();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
int Clock;
|
||||
};
|
||||
|
||||
class D3DFB::Wiper_Melt : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Melt();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
// Match the strip sizes that oldschool Doom used.
|
||||
static const int WIDTH = 160, HEIGHT = 200;
|
||||
int y[WIDTH];
|
||||
};
|
||||
|
||||
class D3DFB::Wiper_Burn : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Burn(D3DFB *fb);
|
||||
~Wiper_Burn();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
static const int WIDTH = 64, HEIGHT = 64;
|
||||
BYTE BurnArray[WIDTH * (HEIGHT + 5)];
|
||||
IDirect3DTexture9 *BurnTexture;
|
||||
int Density;
|
||||
int BurnTime;
|
||||
|
||||
struct BURNVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw;
|
||||
FLOAT tu0, tv0;
|
||||
FLOAT tu1, tv1;
|
||||
};
|
||||
#define D3DFVF_BURNVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX2)
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
|
||||
// is visible on screen right now.
|
||||
//
|
||||
// In windowed mode, we can't do that because we'll get the whole desktop.
|
||||
// Instead, we can conveniently use the TempRenderTexture, which is normally
|
||||
// used for gamma-correcting copying the image to the back buffer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::WipeStartScreen(int type)
|
||||
{
|
||||
IDirect3DSurface9 *tsurf;
|
||||
D3DSURFACE_DESC desc;
|
||||
|
||||
if (!Accel2D)
|
||||
{
|
||||
return Super::WipeStartScreen(type);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case wipe_Melt:
|
||||
ScreenWipe = new Wiper_Melt;
|
||||
break;
|
||||
|
||||
case wipe_Burn:
|
||||
ScreenWipe = new Wiper_Burn(this);
|
||||
break;
|
||||
|
||||
case wipe_Fade:
|
||||
ScreenWipe = new Wiper_Crossfade;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT);
|
||||
|
||||
// Create another texture to copy the final wipe screen to so
|
||||
// we can still gamma correct the wipe. Since this is just for
|
||||
// gamma correction, it's okay to fail (though not desirable.)
|
||||
if (PixelDoubling || Windowed)
|
||||
{
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
|
||||
{
|
||||
if (FAILED(tsurf->GetDesc(&desc)) ||
|
||||
FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height,
|
||||
1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT,
|
||||
&FinalWipeScreen, NULL)))
|
||||
{
|
||||
(FinalWipeScreen = TempRenderTexture)->AddRef();
|
||||
}
|
||||
tsurf->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(FinalWipeScreen = TempRenderTexture)->AddRef();
|
||||
}
|
||||
|
||||
// Make even fullscreen model render to the TempRenderTexture, so
|
||||
// we can have a copy of the new screen readily available.
|
||||
GatheringWipeScreen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn. This function is
|
||||
// called in place of Update(), so it has not been Presented yet.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeEndScreen()
|
||||
{
|
||||
if (!Accel2D)
|
||||
{
|
||||
Super::WipeEndScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't do anything if there is no starting point.
|
||||
if (InitialWipeScreen == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the whole screen was drawn without 2D accel, get it in to
|
||||
// video memory now.
|
||||
if (!In2D)
|
||||
{
|
||||
Begin2D(true);
|
||||
}
|
||||
|
||||
EndBatch(); // Make sure all batched primitives have been drawn.
|
||||
|
||||
// Don't do anything if there is no ending point.
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If these are different, reverse their roles so we don't need to
|
||||
// waste time copying from TempRenderTexture to FinalWipeScreen.
|
||||
if (FinalWipeScreen != TempRenderTexture)
|
||||
{
|
||||
swapvalues(RenderTexture[CurrRenderTexture], FinalWipeScreen);
|
||||
TempRenderTexture = RenderTexture[CurrRenderTexture];
|
||||
}
|
||||
|
||||
// At this point, InitialWipeScreen holds the screen we are wiping from.
|
||||
// FinalWipeScreen holds the screen we are wiping to, which may be the
|
||||
// same texture as TempRenderTexture.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeDo
|
||||
//
|
||||
// Perform the actual wipe animation. The number of tics since the last
|
||||
// time this function was called is passed in. Returns true when the wipe
|
||||
// is over. The first time this function has been called, the screen is
|
||||
// still locked from before and EndScene() still has not been called.
|
||||
// Successive times need to call BeginScene().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::WipeDo(int ticks)
|
||||
{
|
||||
if (!Accel2D)
|
||||
{
|
||||
return Super::WipeDo(ticks);
|
||||
}
|
||||
|
||||
// Sanity checks.
|
||||
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (GatheringWipeScreen)
|
||||
{ // This is the first time we've been called for this wipe.
|
||||
GatheringWipeScreen = false;
|
||||
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
||||
}
|
||||
else
|
||||
{ // This is the second or later time we've been called for this wipe.
|
||||
D3DDevice->BeginScene();
|
||||
InScene = true;
|
||||
}
|
||||
SAFE_RELEASE( OldRenderTarget );
|
||||
if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen)
|
||||
{
|
||||
IDirect3DSurface9 *targetsurf;
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
|
||||
{
|
||||
if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)))
|
||||
{
|
||||
if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
|
||||
{
|
||||
// Setting the render target failed.
|
||||
}
|
||||
}
|
||||
targetsurf->Release();
|
||||
}
|
||||
}
|
||||
In2D = 3;
|
||||
|
||||
EnableAlphaTest(FALSE);
|
||||
bool done = ScreenWipe->Run(ticks, this);
|
||||
DrawLetterbox();
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeCleanup()
|
||||
{
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
ScreenWipe = NULL;
|
||||
}
|
||||
SAFE_RELEASE( InitialWipeScreen );
|
||||
SAFE_RELEASE( FinalWipeScreen );
|
||||
GatheringWipeScreen = false;
|
||||
if (!Accel2D)
|
||||
{
|
||||
Super::WipeCleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper::~Wiper()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper :: DrawScreen
|
||||
//
|
||||
// Draw either the initial or target screen completely to the screen.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
|
||||
D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1)
|
||||
{
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, false, color0, color1);
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
fb->SetTexture(0, tex);
|
||||
fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
}
|
||||
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Crossfade Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Crossfade::Wiper_Crossfade()
|
||||
: Clock(0)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Crossfade :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
Clock += ticks;
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Draw the new screen on top of it.
|
||||
DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD,
|
||||
D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
|
||||
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
||||
// WIPE: MELT --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Melt Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Melt::Wiper_Melt()
|
||||
{
|
||||
int i, r;
|
||||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < WIDTH; ++i)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Melt :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
// Draw the new screen on the bottom.
|
||||
DrawScreen(fb, fb->FinalWipeScreen);
|
||||
|
||||
int i, dy;
|
||||
int fbwidth = fb->Width;
|
||||
int fbheight = fb->Height;
|
||||
bool done = true;
|
||||
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
done = true;
|
||||
for (i = 0; i < WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < HEIGHT)
|
||||
{
|
||||
dy = (y[i] < 16) ? y[i]+1 : 8;
|
||||
y[i] = MIN(y[i] + dy, HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{ // Only draw for the final tick.
|
||||
RECT rect;
|
||||
POINT dpt;
|
||||
|
||||
dpt.x = i * fbwidth / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * fbwidth / WIDTH;
|
||||
rect.bottom = fbheight - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
fb->CheckQuadBatch();
|
||||
|
||||
BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos];
|
||||
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
|
||||
WORD *index = &fb->IndexData[fb->IndexPos];
|
||||
|
||||
quad->Group1 = 0;
|
||||
quad->Flags = BQF_DisableAlphaTest;
|
||||
quad->ShaderNum = BQS_Plain;
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = fb->InitialWipeScreen;
|
||||
quad->NumVerts = 4;
|
||||
quad->NumTris = 2;
|
||||
|
||||
// Fill the vertex buffer.
|
||||
float u0 = rect.left / float(fb->FBWidth);
|
||||
float v0 = 0;
|
||||
float u1 = rect.right / float(fb->FBWidth);
|
||||
float v1 = (rect.bottom - rect.top) / float(fb->FBHeight);
|
||||
|
||||
float x0 = float(rect.left) - 0.5f;
|
||||
float x1 = float(rect.right) - 0.5f;
|
||||
float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f;
|
||||
float y1 = float(fbheight + fb->LBOffsetI) - 0.5f;
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
vert[0].z = 0;
|
||||
vert[0].rhw = 1;
|
||||
vert[0].color0 = 0;
|
||||
vert[0].color1 = 0xFFFFFFF;
|
||||
vert[0].tu = u0;
|
||||
vert[0].tv = v0;
|
||||
|
||||
vert[1].x = x1;
|
||||
vert[1].y = y0;
|
||||
vert[1].z = 0;
|
||||
vert[1].rhw = 1;
|
||||
vert[1].color0 = 0;
|
||||
vert[1].color1 = 0xFFFFFFF;
|
||||
vert[1].tu = u1;
|
||||
vert[1].tv = v0;
|
||||
|
||||
vert[2].x = x1;
|
||||
vert[2].y = y1;
|
||||
vert[2].z = 0;
|
||||
vert[2].rhw = 1;
|
||||
vert[2].color0 = 0;
|
||||
vert[2].color1 = 0xFFFFFFF;
|
||||
vert[2].tu = u1;
|
||||
vert[2].tv = v1;
|
||||
|
||||
vert[3].x = x0;
|
||||
vert[3].y = y1;
|
||||
vert[3].z = 0;
|
||||
vert[3].rhw = 1;
|
||||
vert[3].color0 = 0;
|
||||
vert[3].color1 = 0xFFFFFFF;
|
||||
vert[3].tu = u0;
|
||||
vert[3].tv = v1;
|
||||
|
||||
// Fill the vertex index buffer.
|
||||
index[0] = fb->VertexPos;
|
||||
index[1] = fb->VertexPos + 1;
|
||||
index[2] = fb->VertexPos + 2;
|
||||
index[3] = fb->VertexPos;
|
||||
index[4] = fb->VertexPos + 2;
|
||||
index[5] = fb->VertexPos + 3;
|
||||
|
||||
// Batch the quad.
|
||||
fb->QuadBatchPos++;
|
||||
fb->VertexPos += 4;
|
||||
fb->IndexPos += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fb->EndQuadBatch();
|
||||
return done;
|
||||
}
|
||||
|
||||
// WIPE: BURN --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Burn::Wiper_Burn(D3DFB *fb)
|
||||
{
|
||||
Density = 4;
|
||||
BurnTime = 0;
|
||||
memset(BurnArray, 0, sizeof(BurnArray));
|
||||
if (fb->Shaders[SHADER_BurnWipe] == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1,
|
||||
D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &BurnTexture, NULL)))
|
||||
{
|
||||
BurnTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Burn::~Wiper_Burn()
|
||||
{
|
||||
SAFE_RELEASE( BurnTexture );
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn :: Run
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
bool done;
|
||||
|
||||
BurnTime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
|
||||
done = (Density < 0);
|
||||
}
|
||||
|
||||
// Update the burn texture with the new burn data
|
||||
D3DLOCKED_RECT lrect;
|
||||
if (SUCCEEDED(BurnTexture->LockRect(0, &lrect, NULL, D3DLOCK_DISCARD)))
|
||||
{
|
||||
const BYTE *src = BurnArray;
|
||||
BYTE *dest = (BYTE *)lrect.pBits;
|
||||
for (int y = HEIGHT; y != 0; --y)
|
||||
{
|
||||
for (int x = WIDTH; x != 0; --x)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
dest += lrect.Pitch - WIDTH;
|
||||
}
|
||||
BurnTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
float top = fb->LBOffset - 0.5f;
|
||||
float right = float(fb->Width) - 0.5f;
|
||||
float bot = float(fb->Height) + top;
|
||||
float texright = float(fb->Width) / float(fb->FBWidth);
|
||||
float texbot = float(fb->Height) / float(fb->FBHeight);
|
||||
|
||||
BURNVERTEX verts[4] =
|
||||
{
|
||||
{ -0.5f, top, 0.5f, 1.f, 0.f, 0.f, 0, 0 },
|
||||
{ right, top, 0.5f, 1.f, texright, 0.f, 1, 0 },
|
||||
{ right, bot, 0.5f, 1.f, texright, texbot, 1, 1 },
|
||||
{ -0.5f, bot, 0.5f, 1.f, 0.f, texbot, 0, 1 }
|
||||
};
|
||||
|
||||
fb->D3DDevice->SetFVF(D3DFVF_BURNVERTEX);
|
||||
fb->SetTexture(0, fb->FinalWipeScreen);
|
||||
fb->SetTexture(1, BurnTexture);
|
||||
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]);
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
if (fb->SM14)
|
||||
{
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(BURNVERTEX));
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
if (fb->SM14)
|
||||
{
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
}
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
return done || (BurnTime > 40);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -131,8 +131,7 @@ void I_InitGraphics ()
|
|||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||
|
||||
//currentrenderer = vid_renderer;
|
||||
if (currentrenderer==1) Video = gl_CreateVideo();
|
||||
else Video = new Win32Video (0);
|
||||
Video = gl_CreateVideo();
|
||||
|
||||
if (Video == NULL)
|
||||
I_FatalError ("Failed to initialize display");
|
||||
|
|
|
@ -140,604 +140,6 @@ FILE *dbg;
|
|||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
Win32Video::Win32Video (int parm)
|
||||
: m_Modes (NULL),
|
||||
m_IsFullscreen (false),
|
||||
m_Adapter (D3DADAPTER_DEFAULT)
|
||||
{
|
||||
I_SetWndProc();
|
||||
if (!InitD3D9())
|
||||
{
|
||||
InitDDraw();
|
||||
}
|
||||
}
|
||||
|
||||
Win32Video::~Win32Video ()
|
||||
{
|
||||
FreeModes ();
|
||||
|
||||
if (DDraw != NULL)
|
||||
{
|
||||
if (m_IsFullscreen)
|
||||
{
|
||||
DDraw->SetCooperativeLevel (NULL, DDSCL_NORMAL);
|
||||
}
|
||||
DDraw->Release();
|
||||
DDraw = NULL;
|
||||
}
|
||||
if (D3D != NULL)
|
||||
{
|
||||
D3D->Release();
|
||||
D3D = NULL;
|
||||
}
|
||||
|
||||
STOPLOG;
|
||||
}
|
||||
|
||||
bool Win32Video::InitD3D9 ()
|
||||
{
|
||||
DIRECT3DCREATE9FUNC direct3d_create_9;
|
||||
|
||||
if (vid_forceddraw)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the Direct3D 9 library.
|
||||
if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Obtain an IDirect3D interface.
|
||||
if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL)
|
||||
{
|
||||
goto closelib;
|
||||
}
|
||||
if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL)
|
||||
{
|
||||
goto closelib;
|
||||
}
|
||||
|
||||
// Select adapter.
|
||||
m_Adapter = (vid_adapter < 1 || (UINT)vid_adapter > D3D->GetAdapterCount())
|
||||
? D3DADAPTER_DEFAULT : (UINT)vid_adapter - 1u;
|
||||
|
||||
// Check that we have at least PS 1.4 available.
|
||||
D3DCAPS9 devcaps;
|
||||
if (FAILED(D3D->GetDeviceCaps (m_Adapter, D3DDEVTYPE_HAL, &devcaps)))
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104)
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES))
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
|
||||
// Enumerate available display modes.
|
||||
FreeModes ();
|
||||
AddD3DModes (m_Adapter, D3DFMT_X8R8G8B8);
|
||||
AddD3DModes (m_Adapter, D3DFMT_R5G6B5);
|
||||
if (Args->CheckParm ("-2"))
|
||||
{ // Force all modes to be pixel-doubled.
|
||||
ScaleModes (1);
|
||||
}
|
||||
else if (Args->CheckParm ("-4"))
|
||||
{ // Force all modes to be pixel-quadrupled.
|
||||
ScaleModes (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLowResModes ();
|
||||
}
|
||||
AddLetterboxModes ();
|
||||
if (m_Modes == NULL)
|
||||
{ // Too bad. We didn't find any modes for D3D9. We probably won't find any
|
||||
// for DDraw either...
|
||||
goto d3drelease;
|
||||
}
|
||||
return true;
|
||||
|
||||
d3drelease:
|
||||
D3D->Release();
|
||||
D3D = NULL;
|
||||
closelib:
|
||||
FreeLibrary (D3D9_dll);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Win32Video::InitDDraw ()
|
||||
{
|
||||
DIRECTDRAWCREATEFUNC directdraw_create;
|
||||
LPDIRECTDRAW ddraw1;
|
||||
STARTLOG;
|
||||
|
||||
HRESULT dderr;
|
||||
|
||||
// Load the DirectDraw library.
|
||||
if ((DDraw_dll = LoadLibraryA ("ddraw.dll")) == NULL)
|
||||
{
|
||||
I_FatalError ("Could not load ddraw.dll");
|
||||
}
|
||||
|
||||
// Obtain an IDirectDraw interface.
|
||||
if ((directdraw_create = (DIRECTDRAWCREATEFUNC)GetProcAddress (DDraw_dll, "DirectDrawCreate")) == NULL)
|
||||
{
|
||||
I_FatalError ("The system file ddraw.dll is missing the DirectDrawCreate export");
|
||||
}
|
||||
|
||||
dderr = directdraw_create (NULL, &ddraw1, NULL);
|
||||
|
||||
if (FAILED(dderr))
|
||||
I_FatalError ("Could not create DirectDraw object: %08lx", dderr);
|
||||
|
||||
dderr = ddraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&DDraw);
|
||||
if (FAILED(dderr))
|
||||
{
|
||||
ddraw1->Release ();
|
||||
DDraw = NULL;
|
||||
I_FatalError ("Could not initialize IDirectDraw2 interface: %08lx", dderr);
|
||||
}
|
||||
|
||||
// Okay, we have the IDirectDraw2 interface now, so we can release the
|
||||
// really old-fashioned IDirectDraw one.
|
||||
ddraw1->Release ();
|
||||
|
||||
DDraw->SetCooperativeLevel (Window, DDSCL_NORMAL);
|
||||
FreeModes ();
|
||||
dderr = DDraw->EnumDisplayModes (0, NULL, this, EnumDDModesCB);
|
||||
if (FAILED(dderr))
|
||||
{
|
||||
DDraw->Release ();
|
||||
DDraw = NULL;
|
||||
I_FatalError ("Could not enumerate display modes: %08lx", dderr);
|
||||
}
|
||||
if (m_Modes == NULL)
|
||||
{
|
||||
DDraw->Release ();
|
||||
DDraw = NULL;
|
||||
I_FatalError ("DirectDraw returned no display modes.\n\n"
|
||||
"If you started " GAMENAME " from a fullscreen DOS box, run it from "
|
||||
"a DOS window instead. If that does not work, you may need to reboot.");
|
||||
}
|
||||
if (Args->CheckParm ("-2"))
|
||||
{ // Force all modes to be pixel-doubled.
|
||||
ScaleModes(1);
|
||||
}
|
||||
else if (Args->CheckParm ("-4"))
|
||||
{ // Force all modes to be pixel-quadrupled.
|
||||
ScaleModes(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OSPlatform == os_Win95)
|
||||
{
|
||||
// Windows 95 will let us use Mode X. If we didn't find any linear
|
||||
// modes in the loop above, add the Mode X modes here.
|
||||
AddMode (320, 200, 8, 200, 0);
|
||||
AddMode (320, 240, 8, 240, 0);
|
||||
}
|
||||
AddLowResModes ();
|
||||
}
|
||||
AddLetterboxModes ();
|
||||
}
|
||||
|
||||
// Returns true if fullscreen, false otherwise
|
||||
bool Win32Video::GoFullscreen (bool yes)
|
||||
{
|
||||
static const char *const yestypes[2] = { "windowed", "fullscreen" };
|
||||
HRESULT hr[2];
|
||||
int count;
|
||||
|
||||
// FIXME: Do this right for D3D. (This function is only called by the movie player when using D3D.)
|
||||
if (D3D != NULL)
|
||||
{
|
||||
return yes;
|
||||
}
|
||||
|
||||
if (m_IsFullscreen == yes)
|
||||
return yes;
|
||||
|
||||
for (count = 0; count < 2; ++count)
|
||||
{
|
||||
LOG1 ("fullscreen: %d\n", yes);
|
||||
hr[count] = DDraw->SetCooperativeLevel (Window, !yes ? DDSCL_NORMAL :
|
||||
DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||
if (SUCCEEDED(hr[count]))
|
||||
{
|
||||
if (count != 0)
|
||||
{
|
||||
// Ack! Cannot print because the screen does not exist right now.
|
||||
// Printf ("Setting %s mode failed. Error %08lx\n",
|
||||
// yestypes[!yes], hr[0]);
|
||||
}
|
||||
m_IsFullscreen = yes;
|
||||
return yes;
|
||||
}
|
||||
yes = !yes;
|
||||
}
|
||||
|
||||
I_FatalError ("Could not set %s mode: %08lx\n"
|
||||
"Could not set %s mode: %08lx\n",
|
||||
yestypes[yes], hr[0], yestypes[!yes], hr[1]);
|
||||
|
||||
// Appease the compiler, even though we never return if we get here.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Flips to the GDI surface and clears it; used by the movie player
|
||||
void Win32Video::BlankForGDI ()
|
||||
{
|
||||
static_cast<BaseWinFB *> (screen)->Blank ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Win32Video :: DumpAdapters
|
||||
//
|
||||
// Dumps the list of display adapters to the console. Only meaningful for
|
||||
// Direct3D.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Win32Video::DumpAdapters()
|
||||
{
|
||||
if (D3D == NULL)
|
||||
{
|
||||
Printf("Multi-monitor support requires Direct3D.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
UINT num_adapters = D3D->GetAdapterCount();
|
||||
|
||||
for (UINT i = 0; i < num_adapters; ++i)
|
||||
{
|
||||
D3DADAPTER_IDENTIFIER9 ai;
|
||||
char moreinfo[64] = "";
|
||||
|
||||
if (FAILED(D3D->GetAdapterIdentifier(i, 0, &ai)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Strip trailing whitespace from adapter description.
|
||||
for (char *p = ai.Description + strlen(ai.Description) - 1;
|
||||
p >= ai.Description && isspace(*p);
|
||||
--p)
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
HMONITOR hm = D3D->GetAdapterMonitor(i);
|
||||
MONITORINFOEX mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
|
||||
TOptWin32Proc<BOOL(WINAPI*)(HMONITOR, LPMONITORINFO)> GetMonitorInfo("user32.dll", "GetMonitorInfoW");
|
||||
assert(GetMonitorInfo != NULL); // Missing in NT4, but so is D3D
|
||||
if (GetMonitorInfo.Call(hm, &mi))
|
||||
{
|
||||
mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s",
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
mi.rcMonitor.bottom - mi.rcMonitor.top,
|
||||
mi.rcMonitor.left, mi.rcMonitor.top,
|
||||
mi.dwFlags & MONITORINFOF_PRIMARY ? " (Primary)" : "");
|
||||
}
|
||||
Printf("%s%u. %s%s\n",
|
||||
i == m_Adapter ? TEXTCOLOR_BOLD : "",
|
||||
i + 1, ai.Description, moreinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Mode enumeration --------------------------------------------------------
|
||||
|
||||
HRESULT WINAPI Win32Video::EnumDDModesCB (LPDDSURFACEDESC desc, void *data)
|
||||
{
|
||||
((Win32Video *)data)->AddMode (desc->dwWidth, desc->dwHeight, 8, desc->dwHeight, 0);
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
void Win32Video::AddD3DModes (UINT adapter, D3DFORMAT format)
|
||||
{
|
||||
UINT modecount, i;
|
||||
D3DDISPLAYMODE mode;
|
||||
|
||||
modecount = D3D->GetAdapterModeCount (adapter, format);
|
||||
for (i = 0; i < modecount; ++i)
|
||||
{
|
||||
if (D3D_OK == D3D->EnumAdapterModes (adapter, format, i, &mode))
|
||||
{
|
||||
AddMode (mode.Width, mode.Height, 8, mode.Height, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Win32Video :: AddLowResModes
|
||||
//
|
||||
// Recent NVidia drivers no longer support resolutions below 640x480, even
|
||||
// if you try to add them as a custom resolution. With D3DFB, pixel doubling
|
||||
// is quite easy to do and hardware-accelerated. If you have 1280x800, then
|
||||
// you can have 320x200, but don't be surprised if it shows up as widescreen
|
||||
// on a widescreen monitor, since that's what it is.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Win32Video::AddLowResModes()
|
||||
{
|
||||
ModeInfo *mode, *nextmode;
|
||||
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*2 &&
|
||||
mode->height <= 480*2 &&
|
||||
mode->width >= 320*2 &&
|
||||
mode->width <= 640*2)
|
||||
{
|
||||
AddMode (mode->width / 2, mode->height / 2, mode->bits, mode->height / 2, 1);
|
||||
}
|
||||
}
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*4 &&
|
||||
mode->height <= 480*4 &&
|
||||
mode->width >= 320*4 &&
|
||||
mode->width <= 640*4)
|
||||
{
|
||||
AddMode (mode->width / 4, mode->height / 4, mode->bits, mode->height / 4, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add 16:9 and 16:10 resolutions you can use in a window or letterboxed
|
||||
void Win32Video::AddLetterboxModes ()
|
||||
{
|
||||
ModeInfo *mode, *nextmode;
|
||||
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height && mode->height * 4/3 == mode->width)
|
||||
{
|
||||
if (mode->width >= 360)
|
||||
{
|
||||
AddMode (mode->width, mode->width * 9/16, mode->bits, mode->height, mode->doubling);
|
||||
}
|
||||
if (mode->width > 640)
|
||||
{
|
||||
AddMode (mode->width, mode->width * 10/16, mode->bits, mode->height, mode->doubling);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Win32Video::AddMode (int x, int y, int bits, int y2, int doubling)
|
||||
{
|
||||
// Reject modes that do not meet certain criteria.
|
||||
if ((x & 1) != 0 ||
|
||||
y > MAXHEIGHT ||
|
||||
x > MAXWIDTH ||
|
||||
y < 200 ||
|
||||
x < 320)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModeInfo **probep = &m_Modes;
|
||||
ModeInfo *probe = m_Modes;
|
||||
|
||||
// This mode may have been already added to the list because it is
|
||||
// enumerated multiple times at different refresh rates. If it's
|
||||
// not present, add it to the right spot in the list; otherwise, do nothing.
|
||||
// Modes are sorted first by width, then by height, then by depth. In each
|
||||
// case the order is ascending.
|
||||
for (; probe != 0; probep = &probe->next, probe = probe->next)
|
||||
{
|
||||
if (probe->width > x) break;
|
||||
if (probe->width < x) continue;
|
||||
// Width is equal
|
||||
if (probe->height > y) break;
|
||||
if (probe->height < y) continue;
|
||||
// Height is equal
|
||||
if (probe->bits > bits) break;
|
||||
if (probe->bits < bits) continue;
|
||||
// Bits is equal
|
||||
return;
|
||||
}
|
||||
|
||||
*probep = new ModeInfo (x, y, bits, y2, doubling);
|
||||
(*probep)->next = probe;
|
||||
}
|
||||
|
||||
void Win32Video::FreeModes ()
|
||||
{
|
||||
ModeInfo *mode = m_Modes;
|
||||
|
||||
while (mode)
|
||||
{
|
||||
ModeInfo *tempmode = mode;
|
||||
mode = mode->next;
|
||||
delete tempmode;
|
||||
}
|
||||
m_Modes = NULL;
|
||||
}
|
||||
|
||||
// For every mode, set its scaling factor. Modes that end up with too
|
||||
// small a display area are discarded.
|
||||
|
||||
void Win32Video::ScaleModes (int doubling)
|
||||
{
|
||||
ModeInfo *mode, **prev;
|
||||
|
||||
prev = &m_Modes;
|
||||
mode = m_Modes;
|
||||
|
||||
while (mode != NULL)
|
||||
{
|
||||
assert(mode->doubling == 0);
|
||||
mode->width >>= doubling;
|
||||
mode->height >>= doubling;
|
||||
mode->realheight >>= doubling;
|
||||
mode->doubling = doubling;
|
||||
if ((mode->width & 7) != 0 || mode->width < 320 || mode->height < 200)
|
||||
{ // Mode became too small. Delete it.
|
||||
*prev = mode->next;
|
||||
delete mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &mode->next;
|
||||
}
|
||||
mode = *prev;
|
||||
}
|
||||
}
|
||||
|
||||
void Win32Video::StartModeIterator (int bits, bool fs)
|
||||
{
|
||||
m_IteratorMode = m_Modes;
|
||||
m_IteratorBits = bits;
|
||||
m_IteratorFS = fs;
|
||||
}
|
||||
|
||||
bool Win32Video::NextMode (int *width, int *height, bool *letterbox)
|
||||
{
|
||||
if (m_IteratorMode)
|
||||
{
|
||||
while (m_IteratorMode && m_IteratorMode->bits != m_IteratorBits)
|
||||
{
|
||||
m_IteratorMode = m_IteratorMode->next;
|
||||
}
|
||||
|
||||
if (m_IteratorMode)
|
||||
{
|
||||
*width = m_IteratorMode->width;
|
||||
*height = m_IteratorMode->height;
|
||||
if (letterbox != NULL) *letterbox = m_IteratorMode->realheight != m_IteratorMode->height;
|
||||
m_IteratorMode = m_IteratorMode->next;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old)
|
||||
{
|
||||
static int retry = 0;
|
||||
static int owidth, oheight;
|
||||
|
||||
BaseWinFB *fb;
|
||||
PalEntry flashColor;
|
||||
int flashAmount;
|
||||
|
||||
LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old);
|
||||
|
||||
if (old != NULL)
|
||||
{ // Reuse the old framebuffer if its attributes are the same
|
||||
BaseWinFB *fb = static_cast<BaseWinFB *> (old);
|
||||
if (fb->Width == width &&
|
||||
fb->Height == height &&
|
||||
fb->Windowed == !fullscreen)
|
||||
{
|
||||
return old;
|
||||
}
|
||||
old->GetFlash (flashColor, flashAmount);
|
||||
old->ObjectFlags |= OF_YesReallyDelete;
|
||||
if (old == screen) screen = NULL;
|
||||
delete old;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashColor = 0;
|
||||
flashAmount = 0;
|
||||
}
|
||||
|
||||
if (D3D != NULL)
|
||||
{
|
||||
fb = new D3DFB (m_Adapter, width, height, fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
fb = new DDrawFB (width, height, fullscreen);
|
||||
}
|
||||
LOG1 ("New fb created @ %p\n", fb);
|
||||
|
||||
// If we could not create the framebuffer, try again with slightly
|
||||
// different parameters in this order:
|
||||
// 1. Try with the closest size
|
||||
// 2. Try in the opposite screen mode with the original size
|
||||
// 3. Try in the opposite screen mode with the closest size
|
||||
// This is a somewhat confusing mass of recursion here.
|
||||
|
||||
while (fb == NULL || !fb->IsValid ())
|
||||
{
|
||||
static HRESULT hr;
|
||||
|
||||
if (fb != NULL)
|
||||
{
|
||||
if (retry == 0)
|
||||
{
|
||||
hr = fb->GetHR ();
|
||||
}
|
||||
fb->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete fb;
|
||||
|
||||
LOG1 ("fb is bad: %08lx\n", hr);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG ("Could not create fb at all\n");
|
||||
}
|
||||
screen = NULL;
|
||||
|
||||
LOG1 ("Retry number %d\n", retry);
|
||||
|
||||
switch (retry)
|
||||
{
|
||||
case 0:
|
||||
owidth = width;
|
||||
oheight = height;
|
||||
case 2:
|
||||
// Try a different resolution. Hopefully that will work.
|
||||
I_ClosestResolution (&width, &height, 8);
|
||||
LOG2 ("Retry with size %d,%d\n", width, height);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Try changing fullscreen mode. Maybe that will work.
|
||||
width = owidth;
|
||||
height = oheight;
|
||||
fullscreen = !fullscreen;
|
||||
LOG1 ("Retry with fullscreen %d\n", fullscreen);
|
||||
break;
|
||||
|
||||
default:
|
||||
// I give up!
|
||||
LOG3 ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr);
|
||||
I_FatalError ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr);
|
||||
}
|
||||
|
||||
++retry;
|
||||
fb = static_cast<DDrawFB *>(CreateFrameBuffer (width, height, fullscreen, NULL));
|
||||
}
|
||||
retry = 0;
|
||||
|
||||
fb->SetFlash (flashColor, flashAmount);
|
||||
return fb;
|
||||
}
|
||||
|
||||
void Win32Video::SetWindowedScale (float scale)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BaseWinFB :: ScaleCoordsFromWindow
|
||||
|
|
Loading…
Reference in a new issue