Removal of the software renderer, part 2.

This commit is contained in:
nashmuhandes 2016-04-27 20:06:05 +08:00
parent 69a5ecd788
commit d4a1043aa2
24 changed files with 2 additions and 22199 deletions

View file

@ -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

View file

@ -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"

View file

@ -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--;
}

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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__

File diff suppressed because it is too large Load diff

View file

@ -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__

File diff suppressed because it is too large Load diff

View file

@ -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__

File diff suppressed because it is too large Load diff

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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