[renderer] Move to using dynamic frame buffers

For now, OpenGL and Vulkan renderers are broken as I focused on getting
the software renderer working (which was quite tricky to get right).

This fixes a couple of issues: the segfault when warping the screen (due
to the scene rendering move invalidating the warp buffer), and warp
always having 320x200 resolution. There's still the problem of the
effect being too subtle at high resolution, but that's just a matter of
updating the tables and tweaking the code in D_WarpScreen.

Another issue is the Draw functions should probably write directly to
the main frame buffer or even one passed in as a parameter. This would
remove the need for binding the main buffer at the beginning and end of
the frame.
This commit is contained in:
Bill Currie 2022-03-24 12:22:27 +09:00
parent 4a917449b7
commit 0c437492b4
40 changed files with 362 additions and 241 deletions

View file

@ -115,6 +115,9 @@ typedef struct vid_render_funcs_s {
void (*set_2d) (int scaled);
void (*end_frame) (void);
struct framebuffer_s *(*create_frame_buffer) (int width, int height);
void (*bind_framebuffer) (struct framebuffer_s *framebuffer);
vid_model_funcs_t *model_funcs;
} vid_render_funcs_t;

View file

@ -191,6 +191,16 @@ typedef union refframe_s {
};
} refframe_t;
/** Generic frame buffer object.
*
* For attaching scene cameras to render targets.
*/
typedef struct framebuffer_s {
unsigned width;
unsigned height;
void *buffer; ///< renderer-specific frame buffer data
} framebuffer_t;
// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct {
vrect_t vrect; // subwindow in video for refresh

View file

@ -41,6 +41,7 @@
typedef struct camera_s {
struct scene_s *scene; ///< owning scene
struct framebuffer_s *framebuffer;
int32_t id; ///< id in scene
int32_t transform;
float field_of_view;

View file

@ -37,9 +37,6 @@
typedef struct {
qboolean initialized;
qboolean is8bit;
void *buffer; // invisible buffer
short *zbuffer;
void *surfcache;
byte *gammatable; // 256
const byte *basepal; // 256 * 3
byte *palette; // 256 * 3
@ -48,7 +45,6 @@ typedef struct {
unsigned short *colormap16; // 256 * VID_GRADES size
unsigned int *colormap32; // 256 * VID_GRADES size
int fullbright; // index of first fullbright color
int rowbytes; // may be > width if displayed in a window
unsigned width;
unsigned height;
int numpages;

View file

@ -226,6 +226,4 @@ extern float r_skytime;
extern int c_surf;
extern byte *r_warpbuffer;
#endif // _D_IFACE_H

View file

@ -104,8 +104,13 @@ void D_PolysetAff8Start (void);
void D_PolysetAff8End (void);
#endif
extern byte *d_viewbuffer;
extern int d_rowbytes;
extern unsigned d_height;
extern short *d_zbuffer;
extern int d_zrowbytes, d_zwidth;
extern int d_zrowbytes;
extern unsigned d_zwidth;
extern int *d_pscantable;
extern int d_scantable[];
@ -114,8 +119,6 @@ extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
extern int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift;
extern byte *d_viewbuffer;
extern short *zspantable[];
extern int d_minmip;

View file

@ -93,7 +93,7 @@
.extern C(d_pix_min)
.extern C(d_pix_max)
.extern C(d_y_aspect_shift)
.extern C(screenwidth)
.extern C(d_rowbytes)
.extern C(r_leftclipped)
.extern C(r_leftenter)
.extern C(r_rightclipped)

View file

@ -270,8 +270,6 @@ extern edge_t *r_edges, *edge_p, *edge_max;
extern edge_t *newedges[MAXHEIGHT];
extern edge_t *removeedges[MAXHEIGHT];
extern int screenwidth;
extern int r_bmodelactive;
extern vrect_t *pconupdate;

View file

@ -54,7 +54,6 @@ extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1);
extern int cachewidth;
extern byte *cacheblock;
extern int screenwidth;
extern int r_init;
extern float pixelAspect;

View file

@ -19,6 +19,12 @@ typedef struct gl_ctx_s {
int alias_polys;
} gl_ctx_t;
typedef struct gl_framebuffer_s {
unsigned handle;
unsigned color;
unsigned depth;
} gl_framebuffer_t;
extern gl_ctx_t *gl_ctx;
extern gl_ctx_t *glsl_ctx;

View file

@ -1,14 +1,23 @@
#ifndef __vid_sw_h
#define __vid_sw_h
#include "QF/qtypes.h"
struct vrect_s;
typedef struct sw_ctx_s {
void (*choose_visual) (struct sw_ctx_s *ctx);
void (*create_context) (struct sw_ctx_s *ctx);
void (*set_palette) (struct sw_ctx_s *ctx, const byte *palette);
void (*update) (struct sw_ctx_s *ctx, struct vrect_s *rects);
struct framebuffer_s *framebuffer;
} sw_ctx_t;
typedef struct sw_framebuffer_s {
byte *color;
short *depth;
int rowbytes;
} sw_framebuffer_t;
extern sw_ctx_t *sw_ctx;
struct tex_s *sw_SCR_CaptureBGR (void);

View file

@ -45,6 +45,7 @@
#include "r_internal.h"
qboolean r_dowarp, r_dowarpold;
qboolean r_inhibit_viewmodel;
qboolean r_force_fullscreen;
qboolean r_paused;

View file

@ -66,6 +66,7 @@ static qboolean scr_initialized;// ready to draw
static qpic_t *scr_ram;
static qpic_t *scr_turtle;
static framebuffer_t *warp_buffer;
static void
set_vrect (const vrect_t *vrectin, vrect_t *vrect, int lineadj)
{
@ -197,11 +198,21 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
if (refdef->worldmodel) {
vec4f_t position = refdef->frame.position;
refdef->viewleaf = Mod_PointInLeaf (&position[0], refdef->worldmodel);
r_dowarpold = r_dowarp;
if (r_waterwarp->int_val) {
r_dowarp = refdef->viewleaf->contents <= CONTENTS_WATER;
}
if (r_dowarp && !warp_buffer) {
warp_buffer = r_funcs->create_frame_buffer (r_data->vid->width, r_data->vid->height);
}
}
R_MarkLeaves ();
R_PushDlights (vec3_origin);
r_funcs->begin_frame ();
if (r_dowarp) {
r_funcs->bind_framebuffer (warp_buffer);
}
r_funcs->render_view ();
r_funcs->draw_entities (r_ent_queue);
r_funcs->draw_particles (&r_psystem);

View file

@ -194,7 +194,7 @@ LSpanLoop:
movl C(tadjust),%edx
movl C(sadjust),%esi
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
movl C(d_scantable)(,%eax,4),%edi // v * d_rowbytes
addl %ecx,%edi
movl espan_t_u(%ebx),%ecx
addl %ecx,%edi // pdest = &pdestspan[scans->u];

View file

@ -81,7 +81,7 @@ D_DrawSolidSurface (surf_t *surf, int color)
pix = (color << 24) | (color << 16) | (color << 8) | color;
for (span = surf->spans; span; span = span->pnext) {
pdest = d_viewbuffer + screenwidth * span->v;
pdest = d_viewbuffer + d_rowbytes * span->v;
u = span->u;
u2 = span->u + span->count - 1;
((byte *) pdest)[u] = pix;

View file

@ -45,6 +45,7 @@ float d_scalemip[NUM_MIPS - 1];
static float basemip[NUM_MIPS - 1] = { 1.0, 0.5 * 0.8, 0.25 * 0.8 };
static byte *surfcache;
void (*d_drawspans) (espan_t *pspan);
@ -60,29 +61,16 @@ D_Init (void)
vid->vid_internal->flush_caches = D_FlushCaches;
int buffersize = vid->rowbytes * vid->height;
int zbuffersize = vid->width * vid->height * sizeof (*vid->zbuffer);
int cachesize = D_SurfaceCacheForRes (vid->width, vid->height);
if (vid->zbuffer) {
free (vid->zbuffer);
vid->zbuffer = 0;
if (surfcache) {
D_FlushCaches (vid->vid_internal->data);
free (surfcache);
surfcache = 0;
}
if (vid->surfcache) {
D_FlushCaches (0);
free (vid->surfcache);
vid->surfcache = 0;
}
if (vid->vid_internal->init_buffers) {
vid->vid_internal->init_buffers (vid->vid_internal->data);
} else {
free (vid->buffer);
vid->buffer = calloc (buffersize, 1);
}
vid->zbuffer = calloc (zbuffersize, 1);
vid->surfcache = calloc (cachesize, 1);
D_InitCaches (vid->surfcache, cachesize);
surfcache = calloc (cachesize, 1);
vid->vid_internal->init_buffers (vid->vid_internal->data);
D_InitCaches (surfcache, cachesize);
}
void
@ -96,16 +84,6 @@ D_SetupFrame (void)
{
int i;
if (r_dowarp)
d_viewbuffer = r_warpbuffer;
else
d_viewbuffer = vid.buffer;
if (r_dowarp)
screenwidth = WARP_WIDTH;
else
screenwidth = vid.rowbytes;
d_roverwrapped = false;
d_initial_rover = sc_rover;

View file

@ -65,20 +65,10 @@ D_Patch (void)
void
D_ViewChanged (void)
{
int rowpixels;
if (r_dowarp)
rowpixels = WARP_WIDTH;
else
rowpixels = vid.rowbytes;
scale_for_mip = xscale;
if (yscale > xscale)
scale_for_mip = yscale;
d_zrowbytes = vid.width * 2;
d_zwidth = vid.width;
d_pix_min = r_refdef.vrect.width / 320;
if (d_pix_min < 1)
d_pix_min = 1;
@ -99,14 +89,5 @@ D_ViewChanged (void)
d_vrectbottom_particle =
r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift);
{
unsigned i;
for (i = 0; i < vid.height; i++) {
d_scantable[i] = i * rowpixels;
zspantable[i] = d_zbuffer + i * d_zwidth;
}
}
D_Patch ();
}

View file

@ -81,7 +81,7 @@ D_DrawParticle (particle_t *pparticle)
switch (pix) {
case 1:
count = 1 << d_y_aspect_shift;
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
for (; count; count--, pz += d_zwidth, pdest += d_rowbytes) {
if (pz[0] <= izi) {
pz[0] = izi;
pdest[0] = pparticle->icolor;
@ -91,7 +91,7 @@ D_DrawParticle (particle_t *pparticle)
case 2:
count = 2 << d_y_aspect_shift;
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
for (; count; count--, pz += d_zwidth, pdest += d_rowbytes) {
if (pz[0] <= izi) {
pz[0] = izi;
pdest[0] = pparticle->icolor;
@ -106,7 +106,7 @@ D_DrawParticle (particle_t *pparticle)
case 3:
count = 3 << d_y_aspect_shift;
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
for (; count; count--, pz += d_zwidth, pdest += d_rowbytes) {
if (pz[0] <= izi) {
pz[0] = izi;
pdest[0] = pparticle->icolor;
@ -126,7 +126,7 @@ D_DrawParticle (particle_t *pparticle)
case 4:
count = 4 << d_y_aspect_shift;
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
for (; count; count--, pz += d_zwidth, pdest += d_rowbytes) {
if (pz[0] <= izi) {
pz[0] = izi;
pdest[0] = pparticle->icolor;
@ -151,7 +151,7 @@ D_DrawParticle (particle_t *pparticle)
default:
count = pix << d_y_aspect_shift;
for (; count; count--, pz += d_zwidth, pdest += screenwidth) {
for (; count; count--, pz += d_zwidth, pdest += d_rowbytes) {
for (i = 0; i < pix; i++) {
if (pz[i] <= izi) {
pz[i] = izi;

View file

@ -245,7 +245,7 @@ C(DP_1x1):
.globl C(DP_2x2)
C(DP_2x2):
pushl %esi
movl C(screenwidth),%ebx
movl C(d_rowbytes),%ebx
movl C(d_zrowbytes),%esi
cmpw %bp,(%edx)
@ -276,7 +276,7 @@ L2x2_4:
.globl C(DP_3x3)
C(DP_3x3):
pushl %esi
movl C(screenwidth),%ebx
movl C(d_rowbytes),%ebx
movl C(d_zrowbytes),%esi
cmpw %bp,(%edx)
@ -335,7 +335,7 @@ L3x3_9:
.globl C(DP_4x4)
C(DP_4x4):
pushl %esi
movl C(screenwidth),%ebx
movl C(d_rowbytes),%ebx
movl C(d_zrowbytes),%esi
cmpw %bp,(%edx)
@ -438,7 +438,7 @@ LDefault:
movb C(d_y_aspect_shift),%cl
shll %cl,%ebx
// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
// for ( ; count ; count--, pz += d_zwidth, pdest += d_rowbytes)
// {
// for (i=0 ; i<pix ; i++)
// {
@ -463,7 +463,7 @@ LGSkip:
jnz LGenColLoop
addl C(d_zrowbytes),%edx
addl C(screenwidth),%edi
addl C(d_rowbytes),%edi
decl %ebx // --count
jnz LGenRowLoop

View file

@ -699,9 +699,9 @@ D_RasterizeAliasPolySmooth (void)
d_light = plefttop[4];
d_zi = plefttop[5];
d_pdestbasestep = screenwidth + ubasestep;
d_pdestbasestep = d_rowbytes + ubasestep;
d_pdestextrastep = d_pdestbasestep + 1;
d_pdest = (byte *) d_viewbuffer + ystart * screenwidth + plefttop[0];
d_pdest = d_viewbuffer + ystart * d_rowbytes + plefttop[0];
d_pz = d_zbuffer + ystart * d_zwidth + plefttop[0];
// TODO: can reuse partial expressions here
@ -765,9 +765,9 @@ D_RasterizeAliasPolySmooth (void)
d_light = plefttop[4];
d_zi = plefttop[5];
d_pdestbasestep = screenwidth + ubasestep;
d_pdestbasestep = d_rowbytes + ubasestep;
d_pdestextrastep = d_pdestbasestep + 1;
d_pdest = d_viewbuffer + ystart * screenwidth + plefttop[0];
d_pdest = d_viewbuffer + ystart * d_rowbytes + plefttop[0];
#ifdef USE_INTEL_ASM
d_pzbasestep = (d_zwidth + ubasestep) << 1;
d_pzextrastep = d_pzbasestep + 2;

View file

@ -33,6 +33,7 @@
#include "d_local.h"
#include "r_internal.h"
#include "vid_sw.h"
byte *r_turb_pbase;
byte *r_turb_pdest;
@ -49,6 +50,7 @@ int r_turb_spancount;
void
D_WarpScreen (void)
{
sw_framebuffer_t *_swfb = sw_ctx->framebuffer->buffer;
int w, h;
int u, v;
int scr_x = vr_data.scr_view->xpos;
@ -59,6 +61,8 @@ D_WarpScreen (void)
int *turb;
int *col;
byte **row;
byte *color = _swfb->color;
int rowbytes = _swfb->rowbytes;
/* FIXME: allocate these arrays properly */
byte *rowptr[MAXHEIGHT + AMP2 * 2];
@ -72,8 +76,8 @@ D_WarpScreen (void)
hratio = h / (float) scr_h;
for (v = 0; v < scr_h + AMP2 * 2; v++) {
rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
(screenwidth * (int) ((float) v * hratio * h / (h + AMP2 * 2)));
rowptr[v] = d_viewbuffer + (0*r_refdef.vrect.y * d_rowbytes) +
(d_rowbytes * (int) ((float) v * hratio * h / (h + AMP2 * 2)));
}
for (u = 0; u < scr_w + AMP2 * 2; u++) {
@ -82,9 +86,9 @@ D_WarpScreen (void)
}
turb = intsintable + ((int) (vr_data.realtime * SPEED) & (CYCLE - 1));
dest = ((byte*)vid.buffer) + scr_y * vid.rowbytes + scr_x;
dest = color + scr_y * rowbytes + scr_x;
for (v = 0; v < scr_h; v++, dest += vid.rowbytes) {
for (v = 0; v < scr_h; v++, dest += rowbytes) {
col = &column[turb[v]];
row = &rowptr[v];
for (u = 0; u < scr_w; u += 4) {
@ -141,7 +145,7 @@ Turbulent (espan_t *pspan)
zi16stepu = d_zistepu * 16;
do {
r_turb_pdest = d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
r_turb_pdest = d_viewbuffer + (d_rowbytes * pspan->v) + pspan->u;
count = pspan->count;
@ -265,7 +269,7 @@ D_DrawSpans8 (espan_t *pspan)
zi8stepu = d_zistepu * 8;
do {
pdest = d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
pdest = d_viewbuffer + (d_rowbytes * pspan->v) + pspan->u;
count = pspan->count;

View file

@ -78,7 +78,7 @@ D_DrawSkyScans (espan_t *pspan)
tnext = 0; // ditto
do {
pdest = d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
pdest = d_viewbuffer + (d_rowbytes * pspan->v) + pspan->u;
count = pspan->count;

View file

@ -223,7 +223,7 @@ LSpanLoop:
pushl %ebx // preserve spans pointer
movl C(tadjust),%edx
movl C(sadjust),%esi
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
movl C(d_scantable)(,%eax,4),%edi // v * d_rowbytes
addl %ebp,%edi
movl sspan_t_u(%ebx),%ebp
addl %ebp,%edi // pdest = &pdestspan[scans->u];

View file

@ -69,7 +69,7 @@ D_SpriteDrawSpans (sspan_t *pspan)
izistep = (int) (d_zistepu * 0x8000 * 0x10000);
do {
pdest = d_viewbuffer + (screenwidth * pspan->v) + pspan->u;
pdest = d_viewbuffer + (d_rowbytes * pspan->v) + pspan->u;
pz = d_zbuffer + (d_zwidth * pspan->v) + pspan->u;
count = pspan->count;

View file

@ -108,8 +108,6 @@ D_InitCaches (void *buffer, int size)
sc_base->owner = NULL;
sc_base->size = sc_size;
d_zbuffer = vid.zbuffer;
D_ClearCacheGuard ();
}

View file

@ -54,7 +54,9 @@ byte *cacheblock;
int cachewidth;
byte *d_viewbuffer;
short *d_zbuffer;
int d_rowbytes;
int d_zrowbytes;
int d_zwidth;
int d_height;
#endif // !USE_INTEL_ASM

View file

@ -80,6 +80,8 @@ C(bbextentt): .long 0
.globl C(cacheblock)
.globl C(d_viewbuffer)
.globl C(d_rowbytes)
.globl C(d_height)
.globl C(cachewidth)
.globl C(d_zbuffer)
.globl C(d_zrowbytes)
@ -87,6 +89,8 @@ C(bbextentt): .long 0
C(cacheblock): .long 0
C(cachewidth): .long 0
C(d_viewbuffer): .long 0
C(d_rowbytes): .long 0
C(d_height): .long 0
C(d_zbuffer): .long 0
C(d_zrowbytes): .long 0
C(d_zwidth): .long 0

View file

@ -45,6 +45,7 @@
#include "QF/ui/view.h"
#include "d_iface.h"
#include "d_local.h"
#include "r_internal.h"
#include "vid_internal.h"
@ -279,7 +280,7 @@ Draw_Character (int x, int y, unsigned int chr)
} else
drawline = 8;
dest = ((byte*)vid.buffer) + y * vid.rowbytes + x;
dest = d_viewbuffer + y * d_rowbytes + x;
while (drawline--) {
if (source[0])
@ -299,7 +300,7 @@ Draw_Character (int x, int y, unsigned int chr)
if (source[7])
dest[7] = source[7];
source += 128;
dest += vid.rowbytes;
dest += d_rowbytes;
}
}
@ -339,7 +340,7 @@ Draw_Pixel (int x, int y, byte color)
{
byte *dest;
dest = ((byte*)vid.buffer) + y * vid.rowbytes + x;
dest = d_viewbuffer + y * d_rowbytes + x;
*dest = color;
}
@ -493,7 +494,7 @@ Draw_Pic (int x, int y, qpic_t *pic)
source = pic->data;
dest = ((byte*)vid.buffer) + y * vid.rowbytes + x;
dest = d_viewbuffer + y * d_rowbytes + x;
if (pic->width & 7) { // general
for (v = 0; v < pic->height; v++) {
@ -501,7 +502,7 @@ Draw_Pic (int x, int y, qpic_t *pic)
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
dest += vid.rowbytes;
dest += d_rowbytes;
source += pic->width;
}
} else { // unwound
@ -524,7 +525,7 @@ Draw_Pic (int x, int y, qpic_t *pic)
if ((tbyte = source[u + 7]) != TRANSPARENT_COLOR)
dest[u + 7] = tbyte;
}
dest += vid.rowbytes;
dest += d_rowbytes;
source += pic->width;
}
}
@ -571,7 +572,7 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
source = pic->data + srcy * pic->width + srcx;
dest = ((byte*)vid.buffer) + y * vid.rowbytes + x;
dest = d_viewbuffer + y * d_rowbytes + x;
if (width & 7) { // general
for (v = 0; v < height; v++) {
@ -579,7 +580,7 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
dest += vid.rowbytes;
dest += d_rowbytes;
source += pic->width;
}
} else { // unwound
@ -602,7 +603,7 @@ Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
if ((tbyte = source[u + 7]) != TRANSPARENT_COLOR)
dest[u + 7] = tbyte;
}
dest += vid.rowbytes;
dest += d_rowbytes;
source += pic->width;
}
}
@ -620,9 +621,9 @@ Draw_ConsoleBackground (int lines, byte alpha)
conback = Draw_CachePic ("gfx/conback.lmp", false);
// draw the pic
dest = vid.buffer;
dest = d_viewbuffer;
for (y = 0; y < lines; y++, dest += vid.rowbytes) {
for (y = 0; y < lines; y++, dest += d_rowbytes) {
v = (vid.conview->ylen - lines + y) * 200 / vid.conview->ylen;
src = conback->data + v * 320;
if (vid.conview->xlen == 320)
@ -654,10 +655,10 @@ R_DrawRect (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
int i, j, srcdelta, destdelta;
byte *pdest;
pdest = ((byte*)vid.buffer) + (prect->y * vid.rowbytes) + prect->x;
pdest = d_viewbuffer + (prect->y * d_rowbytes) + prect->x;
srcdelta = rowbytes - prect->width;
destdelta = vid.rowbytes - prect->width;
destdelta = d_rowbytes - prect->width;
if (transparent) {
for (i = 0; i < prect->height; i++) {
@ -678,7 +679,7 @@ R_DrawRect (vrect_t *prect, int rowbytes, byte * psrc, int transparent)
for (i = 0; i < prect->height; i++) {
memcpy (pdest, psrc, prect->width);
psrc += rowbytes;
pdest += vid.rowbytes;
pdest += d_rowbytes;
}
}
}
@ -754,8 +755,8 @@ Draw_Fill (int x, int y, int w, int h, int c)
}
CLIP (x, y, w, h, (int) vid.width, (int) vid.height);
dest = ((byte*)vid.buffer) + y * vid.rowbytes + x;
for (v = 0; v < h; v++, dest += vid.rowbytes)
dest = d_viewbuffer + y * d_rowbytes + x;
for (v = 0; v < h; v++, dest += d_rowbytes)
for (u = 0; u < w; u++)
dest[u] = c;
}
@ -774,7 +775,7 @@ Draw_FadeScreen (void)
for (y = 0; y < height; y++) {
uint32_t mask;
pbuf = (uint32_t *) ((byte *)vid.buffer + vid.rowbytes * y);
pbuf = (uint32_t *) (d_viewbuffer + d_rowbytes * y);
mask = 0xff << ((y & 1) << 4);
for (x = 0; x < width; x++) {

View file

@ -45,24 +45,27 @@ sw_SCR_CaptureBGR (void)
tex_t *tex;
const byte *src;
byte *dst;
framebuffer_t *fb = sw_ctx->framebuffer;
count = vid.width * vid.height;
count = fb->width * fb->height;
tex = malloc (sizeof (tex_t) + count * 3);
tex->data = (byte *) (tex + 1);
SYS_CHECKMEM (tex);
tex->width = vid.width;
tex->height = vid.height;
tex->width = fb->width;
tex->height = fb->height;
tex->format = tex_rgb;
tex->palette = 0;
src = vid.buffer;
src = ((sw_framebuffer_t *) fb->buffer)->color;
int rowbytes = ((sw_framebuffer_t *) fb->buffer)->rowbytes;
for (y = 0; y < tex->height; y++) {
dst = tex->data + (tex->height - 1 - y) * tex->width * 3;
for (x = 0; x < tex->width; x++) {
*dst++ = vid.basepal[*src * 3 + 2]; // blue
*dst++ = vid.basepal[*src * 3 + 1]; // green
*dst++ = vid.basepal[*src * 3 + 0]; // red
src++;
byte c = src[x];
*dst++ = vid.basepal[c * 3 + 2]; // blue
*dst++ = vid.basepal[c * 3 + 1]; // green
*dst++ = vid.basepal[c * 3 + 0]; // red
}
src += rowbytes;
}
return tex;
}

View file

@ -33,6 +33,7 @@
#include "QF/render.h"
#include "r_internal.h"
#include "vid_sw.h"
/*
R_LineGraph
@ -44,12 +45,13 @@ R_LineGraph (int x, int y, int *h_vals, int count, int height)
{
int h, i, s, color;
byte *dest;
sw_framebuffer_t *fb = sw_ctx->framebuffer->buffer;
// FIXME: disable on no-buffer adapters, or put in the driver
s = height;
while (count--) {
dest = ((byte*)vid.buffer) + vid.rowbytes * y + x++;
dest = fb->color + fb->rowbytes * y + x++;
h = *h_vals++;
@ -65,7 +67,7 @@ R_LineGraph (int x, int y, int *h_vals, int count, int height)
if (h > s)
h = s;
for (i = 0; i < h; i++, dest -= vid.rowbytes) {
for (i = 0; i < h; i++, dest -= fb->rowbytes) {
dest[0] = color;
}
}

View file

@ -29,6 +29,7 @@
#endif
#include <stdlib.h>
#include <string.h>
#include "QF/image.h"
#include "QF/render.h"

View file

@ -54,6 +54,7 @@
#include "mod_internal.h"
#include "r_internal.h"
#include "vid_internal.h"
#include "vid_sw.h"
#ifdef PIC
# undef USE_INTEL_ASM //XXX asm pic hack
@ -70,7 +71,7 @@ float r_aliasuvscale = 1.0;
int r_outofsurfaces;
int r_outofedges;
qboolean r_dowarp, r_dowarpold, r_viewchanged;
qboolean r_viewchanged;
int c_surf;
int r_maxsurfsseen, r_maxedgesseen;
@ -78,8 +79,6 @@ static int r_cnumsurfs;
static qboolean r_surfsonstack;
int r_clipflags;
byte *r_warpbuffer;
static byte *r_stack_start;
// screen size info
@ -689,16 +688,12 @@ R_EdgeDrawing (entqueue_t *queue)
static void
R_RenderView_ (void)
{
byte warpbuffer[WARP_WIDTH * WARP_HEIGHT];
if (r_norefresh->int_val)
return;
if (!r_refdef.worldmodel) {
return;
}
r_warpbuffer = warpbuffer;
R_SetupFrame ();
// make FDIV fast. This reduces timing precision after we've been running for a
@ -711,9 +706,6 @@ R_RenderView_ (void)
R_DrawViewModel ();
if (r_dowarp)
D_WarpScreen ();
if (r_aliasstats->int_val)
R_PrintAliasStats ();
@ -739,7 +731,7 @@ R_RenderView (void)
if ((intptr_t) (&dummy) & 3)
Sys_Error ("Stack is missaligned");
if ((intptr_t) (&r_warpbuffer) & 3)
if ((intptr_t) (&colormap) & 3)
Sys_Error ("Globals are missaligned");
if (!scr_fisheye->int_val)
R_RenderView_ ();
@ -765,7 +757,7 @@ R_InitTurb (void)
#define BOX_LEFT 3
#define BOX_TOP 4
#define BOX_BOTTOM 5
#if 0
static mat4f_t box_rotations[] = {
{ { 1, 0, 0, 0}, // front
{ 0, 1, 0, 0},
@ -792,7 +784,7 @@ static mat4f_t box_rotations[] = {
{ 1, 0, 0, 0},
{ 0, 0, 0, 1} },
};
#endif
static int sw_cube_map_size;
static void
@ -848,7 +840,7 @@ fisheyelookuptable (byte **buf, int width, int height, byte *scrp, double fov)
}
}
}
#if 0
static void
rendercopy (void *dest)
{
@ -901,16 +893,18 @@ renderside (byte *bufs, int side)
memcpy (r_refdef.camera, camera, sizeof (camera));
memcpy (r_refdef.camera_inverse, camera_inverse, sizeof (camera_inverse));
}
#endif
static void
renderlookup (byte **offs, byte* bufs)
{
byte *p = (byte*)vid.buffer;
unsigned x, y;
for (y = 0; y < vid.height; y++) {
for (x = 0; x < vid.width; x++, offs++)
framebuffer_t *fb = sw_ctx->framebuffer;
sw_framebuffer_t *swfb = fb->buffer;
byte *p = swfb->color;
unsigned x, y;
for (y = 0; y < fb->height; y++) {
for (x = 0; x < fb->width; x++, offs++)
p[x] = **offs;
p += vid.rowbytes;
p += swfb->rowbytes;
}
}
@ -950,7 +944,7 @@ R_RenderViewFishEye (void)
pviews = views;
memset (scrbufs, 0, scrsize*6);
}
#if 0
switch (views) {
case 6: renderside (scrbufs + scrsize * BOX_BEHIND, BOX_BEHIND);
case 5: renderside (scrbufs + scrsize * BOX_BOTTOM, BOX_BOTTOM);
@ -959,6 +953,7 @@ R_RenderViewFishEye (void)
case 2: renderside (scrbufs + scrsize * BOX_RIGHT, BOX_RIGHT);
default: renderside (scrbufs + scrsize * BOX_FRONT, BOX_FRONT);
}
#endif
#if 0
memset (scrbufs + scrsize*0, 31, sw_cube_map_size);
memset (scrbufs + scrsize*1, 31, sw_cube_map_size);

View file

@ -173,9 +173,6 @@ R_SetUpFrustumIndexes (void)
void
R_SetupFrame (void)
{
vrect_t vrect;
float w, h;
numbtofpolys = 0;
// build the transformation matrix for the given view angles
@ -185,62 +182,6 @@ R_SetupFrame (void)
VectorCopy (r_refdef.frame.forward, vfwd);
VectorCopy (r_refdef.frame.up, vup);
r_dowarpold = r_dowarp;
r_dowarp = r_waterwarp->int_val && (r_refdef.viewleaf->contents <=
CONTENTS_WATER);
if (scr_fisheye->int_val) {
//FIXME this shouldn't be necessary, but warp doesn't work well in
//fisheye, aand allowing the non-warp code to mess with vrect messes
//things up for the cube map rendering. This whole frame setup path
//needs to be redesigned
r_dowarp = r_viewchanged = 0;
}
if ((r_dowarp != r_dowarpold) || r_viewchanged) {
if (r_dowarp) {
if ((vid.width <= WARP_WIDTH)
&& (vid.height <= WARP_HEIGHT)) {
vrect.x = 0;
vrect.y = 0;
vrect.width = vid.width;
vrect.height = vid.height;
R_SetVrect (&vrect, &r_refdef.vrect, vr_data.lineadj);
R_ViewChanged ();
} else {
w = vid.width;
h = vid.height;
if (w > WARP_WIDTH) {
h *= (float) WARP_WIDTH / w;
w = WARP_WIDTH;
}
if (h > WARP_HEIGHT) {
h = WARP_HEIGHT;
w *= (float) WARP_HEIGHT / h;
}
vrect.x = 0;
vrect.y = 0;
vrect.width = (int) w;
vrect.height = (int) h;
R_SetVrect (&vrect, &r_refdef.vrect,
(int) ((float) vr_data.lineadj *
(h / (float) vid.height)));
R_ViewChanged ();
}
} else {
r_refdef.vrect.x = vr_data.scr_view->xpos;
r_refdef.vrect.y = vr_data.scr_view->ypos;
r_refdef.vrect.width = vr_data.scr_view->xlen;
r_refdef.vrect.height = vr_data.scr_view->ylen;
R_ViewChanged ();
}
r_viewchanged = false;
}
// start off with just the four screen edge clip planes
R_TransformFrustum ();

View file

@ -300,6 +300,17 @@ gl_end_frame (void)
}
}
static framebuffer_t *
gl_create_frame_buffer (int width, int height)
{
Sys_Error ("not implemented");
}
static void
gl_bind_framebuffer (framebuffer_t *framebuffer)
{
}
vid_render_funcs_t gl_vid_render_funcs = {
gl_vid_render_init,
gl_Draw_Character,
@ -339,6 +350,10 @@ vid_render_funcs_t gl_vid_render_funcs = {
gl_draw_transparent,
gl_set_2d,
gl_end_frame,
gl_create_frame_buffer,
gl_bind_framebuffer,
&model_funcs
};

View file

@ -244,6 +244,17 @@ glsl_end_frame (void)
qfeglFlush ();
}
static framebuffer_t *
glsl_create_frame_buffer (int width, int height)
{
Sys_Error ("not implemented");
}
static void
glsl_bind_framebuffer (framebuffer_t *framebuffer)
{
}
vid_render_funcs_t glsl_vid_render_funcs = {
glsl_vid_render_init,
glsl_Draw_Character,
@ -283,6 +294,10 @@ vid_render_funcs_t glsl_vid_render_funcs = {
glsl_draw_transparent,
glsl_set_2d,
glsl_end_frame,
glsl_create_frame_buffer,
glsl_bind_framebuffer,
&model_funcs
};

View file

@ -28,6 +28,8 @@
# include "config.h"
#endif
#include <string.h>
#include "QF/cvar.h"
#include "QF/plugin/general.h"
@ -35,6 +37,7 @@
#include "QF/ui/view.h"
#include "d_local.h"
#include "mod_internal.h"
#include "r_internal.h"
#include "vid_internal.h"
@ -108,6 +111,8 @@ sw_vid_render_shutdown (void)
{
}
static void sw_bind_framebuffer (framebuffer_t *framebuffer);
static void
sw_begin_frame (void)
{
@ -131,6 +136,8 @@ sw_begin_frame (void)
r_numallocatededges, r_maxedgesseen);
}
sw_bind_framebuffer (0);
// do 3D refresh drawing, and then update the screen
if (vr_data.scr_fullupdate++ < vid.numpages) {
vr_data.scr_copyeverything = 1;
@ -152,6 +159,10 @@ sw_draw_transparent (void)
static void
sw_set_2d (int scaled)
{
if (!scaled && r_dowarp) {
D_WarpScreen ();
sw_bind_framebuffer (0);
}
}
static void
@ -187,6 +198,68 @@ sw_end_frame (void)
sw_ctx->update (sw_ctx, &vrect);
}
static framebuffer_t *
sw_create_frame_buffer (int width, int height)
{
size_t pixels = width * height;
size_t size = sizeof (framebuffer_t);
size += sizeof (sw_framebuffer_t);
size += pixels; // color buffer
size += pixels * sizeof (short); // depth buffer
framebuffer_t *fb = malloc (size);
fb->width = width;
fb->height = height;
__auto_type buffer = (sw_framebuffer_t *) &fb[1];
fb->buffer = buffer;
buffer->color = (byte *) &buffer[1];
buffer->depth = (short *) (buffer->color + pixels);
buffer->rowbytes = width;
return fb;
}
static void
sw_bind_framebuffer (framebuffer_t *framebuffer)
{
int changed = 0;
if (!framebuffer) {
framebuffer = sw_ctx->framebuffer;
}
sw_framebuffer_t *fb = framebuffer->buffer;
if (!fb->depth) {
fb->depth = malloc (framebuffer->width * framebuffer->height
* sizeof (short));
}
if (d_zbuffer != fb->depth
|| d_zwidth != framebuffer->width || d_height != framebuffer->height) {
d_zwidth = framebuffer->width;
d_zrowbytes = d_zwidth * sizeof (short);
for (unsigned i = 0; i < framebuffer->height; i++) {
zspantable[i] = fb->depth + i * d_zwidth;
}
changed = 1;
}
if (d_rowbytes != fb->rowbytes || d_height != framebuffer->height) {
d_rowbytes = fb->rowbytes;
d_height = framebuffer->height;
for (unsigned i = 0; i < framebuffer->height; i++) {
d_scantable[i] = i * d_rowbytes;
}
changed = 1;
}
d_viewbuffer = fb->color;
d_zbuffer = fb->depth;
if (changed) {
vrect_t r = { 0, 0, framebuffer->width, framebuffer->height };
R_SetVrect (&r, &r_refdef.vrect, 0);
R_ViewChanged ();
}
}
vid_render_funcs_t sw_vid_render_funcs = {
sw_vid_render_init,
Draw_Character,
@ -226,6 +299,10 @@ vid_render_funcs_t sw_vid_render_funcs = {
sw_draw_transparent,
sw_set_2d,
sw_end_frame,
sw_create_frame_buffer,
sw_bind_framebuffer,
&model_funcs
};

View file

@ -418,6 +418,17 @@ vulkan_end_frame (void)
vulkan_ctx->curFrame %= vulkan_ctx->frames.size;
}
static framebuffer_t *
vulkan_create_frame_buffer (int width, int height)
{
Sys_Error ("not implemented");
}
static void
vulkan_bind_framebuffer (framebuffer_t *framebuffer)
{
}
static int
is_bgr (VkFormat format)
{
@ -696,6 +707,10 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
vulkan_draw_transparent,
vulkan_set_2d,
vulkan_end_frame,
vulkan_create_frame_buffer,
vulkan_bind_framebuffer,
&model_funcs
};

View file

@ -39,11 +39,14 @@
static vid_internal_t vid_internal;
#if 0
static byte backingbuf[48 * 24];
#endif
void
D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
{
#if 0
int i, j, reps = 1, repshift = 0;
vrect_t rect;
@ -72,12 +75,14 @@ D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
rect.next = NULL;
win_sw_context->update (win_sw_context, &rect);
#endif
}
void
D_EndDirectRect (int x, int y, int width, int height)
{
#if 0
int i, j, reps = 1, repshift = 0;
vrect_t rect;
@ -102,6 +107,7 @@ D_EndDirectRect (int x, int y, int width, int height)
rect.next = NULL;
win_sw_context->update (win_sw_context, &rect);
#endif
}
static void

View file

@ -72,6 +72,9 @@ static ddCreateProc_t ddCreate;
static int dd_window_width = 640;
static int dd_window_height = 480;
static sw_framebuffer_t swfb;
static framebuffer_t fb = { .buffer = &swfb };
static void
DD_UpdateRects (int width, int height)
{
@ -94,8 +97,10 @@ VID_CreateDDrawDriver (int width, int height)
dd_window_width = width;
dd_window_height = height;
viddef.buffer = malloc (width * height);
viddef.rowbytes = width;
fb.width = width;
fb.height = height;
swfb.color = malloc (width * height);
swfb.rowbytes = width;
if (!(hInstDDraw = LoadLibrary ("ddraw.dll"))) {
return;
@ -162,7 +167,7 @@ VID_CreateDDrawDriver (int width, int height)
}
static void
VID_CreateGDIDriver (int width, int height, const byte *palette, void **buffer,
VID_CreateGDIDriver (int width, int height, const byte *palette, byte **buffer,
int *rowbytes)
{
// common bitmap definition
@ -235,10 +240,13 @@ void
Win_UnloadAllDrivers (void)
{
// shut down ddraw
if (viddef.buffer) {
free (viddef.buffer);
*(int *)0xdb = 0;
viddef.buffer = 0;
if (swfb.color) {
free (swfb.color);
swfb.color = 0;
}
if (swfb.depth) {
free (swfb.depth);
swfb.depth = 0;
}
if (dd_Clipper) {
@ -303,13 +311,17 @@ Win_CreateDriver (void)
Win_UnloadAllDrivers ();
VID_CreateGDIDriver (viddef.width, viddef.height, viddef.palette,
&viddef.buffer, &viddef.rowbytes);
&swfb.color, &swfb.rowbytes);
}
}
static void
win_init_bufers (void *data)
{
sw_ctx_t *ctx = data;
ctx->framebuffer = &fb;
Win_UnloadAllDrivers ();
Win_CreateDriver ();
}
@ -372,13 +384,13 @@ dd_blit_rect (vrect_t *rect)
// convert pitch to 32-bit addressable
ddsd.lPitch >>= 2;
byte *src = viddef.buffer + rect->y * viddef.rowbytes + rect->x;
byte *src = swfb.color + rect->y * swfb.rowbytes + rect->x;
unsigned *dst = ddsd.lpSurface;
for (int y = rect->height; y-- > 0; ) {
for (int x = rect->width; x-- > 0; ) {
*dst++ = st2d_8to32table[*src++].value;
}
src += viddef.rowbytes - rect->width;
src += swfb.rowbytes - rect->width;
dst += ddsd.lPitch - rect->width;
}

View file

@ -219,17 +219,18 @@ x11_set_palette (sw_ctx_t *ctx, const byte *palette)
}
static void
st2_fixup (XImage *framebuf, int x, int y, int width, int height)
st2_fixup (sw_ctx_t *ctx, XImage *framebuf, int x, int y, int width, int height)
{
int xi, yi;
unsigned char *src;
PIXEL16 *dest;
sw_framebuffer_t *fb = ctx->framebuffer->buffer;
if (x < 0 || y < 0)
return;
for (yi = y; yi < (y + height); yi++) {
src = &((byte *)viddef.buffer)[yi * viddef.width];
src = &fb->color[yi * fb->rowbytes];
dest = (PIXEL16 *) &framebuf->data[yi * framebuf->bytes_per_line];
for (xi = x; xi < x + width; xi++) {
dest[xi] = st2d_8to16table[src[xi]];
@ -238,18 +239,19 @@ st2_fixup (XImage *framebuf, int x, int y, int width, int height)
}
static void
st3_fixup (XImage * framebuf, int x, int y, int width, int height)
st3_fixup (sw_ctx_t *ctx, XImage *framebuf, int x, int y, int width, int height)
{
int yi;
unsigned char *src;
PIXEL24 *dest;
sw_framebuffer_t *fb = ctx->framebuffer->buffer;
register int count, n;
if (x < 0 || y < 0)
return;
for (yi = y; yi < (y + height); yi++) {
src = &((byte *)viddef.buffer)[yi * viddef.width + x];
src = &fb->color[yi * fb->rowbytes + x];
dest = (PIXEL24 *) &framebuf->data[yi * framebuf->bytes_per_line + x];
// Duff's Device
@ -280,13 +282,13 @@ st3_fixup (XImage * framebuf, int x, int y, int width, int height)
}
static void
x11_put_image (vrect_t *rects)
x11_put_image (vrect_t *rect)
{
if (doShm) {
if (!XShmPutImage (x_disp, x_win, x_gc,
x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->x, rects->y,
rects->width, rects->height, True)) {
rect->x, rect->y, rect->x, rect->y,
rect->width, rect->height, True)) {
Sys_Error ("VID_Update: XShmPutImage failed");
}
oktodraw = false;
@ -296,8 +298,8 @@ x11_put_image (vrect_t *rects)
current_framebuffer = !current_framebuffer;
} else {
if (XPutImage (x_disp, x_win, x_gc, x_framebuffer[0],
rects->x, rects->y, rects->x, rects->y,
rects->width, rects->height)) {
rect->x, rect->y, rect->x, rect->y,
rect->width, rect->height)) {
Sys_Error ("VID_Update: XPutImage failed");
}
}
@ -309,33 +311,46 @@ x11_put_image (vrect_t *rects)
static void
x11_sw8_8_update (sw_ctx_t *ctx, vrect_t *rects)
{
while (rects) {
switch (x_visinfo->depth) {
case 16:
st2_fixup (x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
break;
case 24:
st3_fixup (x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
break;
}
x11_put_image (rects);
vrect_t urect = *rects;
while (rects->next) {
rects = rects->next;
int minx = min (VRect_MinX (&urect), VRect_MinX (rects));
int miny = min (VRect_MinY (&urect), VRect_MinY (rects));
int maxx = max (VRect_MaxX (&urect), VRect_MaxX (rects));
int maxy = max (VRect_MaxY (&urect), VRect_MaxY (rects));
urect.x = minx;
urect.y = miny;
urect.width = maxx - minx;
urect.height = maxy - miny;
}
x11_put_image (&urect);
XSync (x_disp, False);
r_data->scr_fullupdate = 0;
sw_framebuffer_t *fb = ctx->framebuffer->buffer;
fb->color = (byte *) x_framebuffer[current_framebuffer]->data;
}
static void
x11_sw8_16_update (sw_ctx_t *ctx, vrect_t *rects)
{
while (rects) {
st2_fixup (x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
x11_put_image (rects);
vrect_t urect = *rects;
st2_fixup (ctx, x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
while (rects->next) {
rects = rects->next;
st2_fixup (ctx, x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
int minx = min (VRect_MinX (&urect), VRect_MinX (rects));
int miny = min (VRect_MinY (&urect), VRect_MinY (rects));
int maxx = max (VRect_MaxX (&urect), VRect_MaxX (rects));
int maxy = max (VRect_MaxY (&urect), VRect_MaxY (rects));
urect.x = minx;
urect.y = miny;
urect.width = maxx - minx;
urect.height = maxy - miny;
}
x11_put_image (&urect);
XSync (x_disp, False);
r_data->scr_fullupdate = 0;
}
@ -343,12 +358,23 @@ x11_sw8_16_update (sw_ctx_t *ctx, vrect_t *rects)
static void
x11_sw8_24_update (sw_ctx_t *ctx, vrect_t *rects)
{
while (rects) {
st3_fixup (x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
x11_put_image (rects);
vrect_t urect = *rects;
st3_fixup (ctx, x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
while (rects->next) {
rects = rects->next;
st3_fixup (ctx, x_framebuffer[current_framebuffer],
rects->x, rects->y, rects->width, rects->height);
int minx = min (VRect_MinX (&urect), VRect_MinX (rects));
int miny = min (VRect_MinY (&urect), VRect_MinY (rects));
int maxx = max (VRect_MaxX (&urect), VRect_MaxX (rects));
int maxy = max (VRect_MaxY (&urect), VRect_MaxY (rects));
urect.x = minx;
urect.y = miny;
urect.width = maxx - minx;
urect.height = maxy - miny;
}
x11_put_image (&urect);
XSync (x_disp, False);
r_data->scr_fullupdate = 0;
}
@ -592,9 +618,16 @@ ResetSharedFrameBuffers (void)
}
}
static sw_framebuffer_t swfb;
static framebuffer_t fb = { .buffer = &swfb };
static void
x11_init_buffers (void *data)
{
sw_ctx_t *ctx = data;
ctx->framebuffer = &fb;
if (doShm)
ResetSharedFrameBuffers ();
else
@ -602,15 +635,18 @@ x11_init_buffers (void *data)
current_framebuffer = 0;
viddef.rowbytes = viddef.width;
fb.width = viddef.width;
fb.height = viddef.height;
if (x_visinfo->depth != 8) {
if (viddef.buffer)
free (viddef.buffer);
viddef.buffer = calloc (viddef.rowbytes, viddef.height);
if (!viddef.buffer)
if (swfb.color)
free (swfb.color);
swfb.rowbytes = viddef.width;
swfb.color = calloc (swfb.rowbytes, viddef.height);
if (!swfb.color)
Sys_Error ("Not enough memory for video mode");
} else {
viddef.buffer = x_framebuffer[current_framebuffer]->data;
swfb.rowbytes = x_framebuffer[current_framebuffer]->bytes_per_line;
swfb.color = (byte *) x_framebuffer[current_framebuffer]->data;
}
}