diff --git a/src/client/menu/videomenu.c b/src/client/menu/videomenu.c index 67076273..588f27f0 100644 --- a/src/client/menu/videomenu.c +++ b/src/client/menu/videomenu.c @@ -42,7 +42,7 @@ extern cvar_t *vid_gamma; extern cvar_t *vid_fullscreen; extern cvar_t *vid_renderer; static cvar_t *r_vsync; -static cvar_t *r_anisotropic; +static cvar_t *gl_anisotropic; static cvar_t *gl_msaa_samples; static menuframework_s s_opengl_menu; @@ -126,11 +126,11 @@ AnisotropicCallback(void *s) if (list->curvalue == 0) { - Cvar_SetValue("r_anisotropic", 0); + Cvar_SetValue("gl_anisotropic", 0); } else { - Cvar_SetValue("r_anisotropic", pow(2, list->curvalue)); + Cvar_SetValue("gl_anisotropic", pow(2, list->curvalue)); } } @@ -362,9 +362,9 @@ VID_MenuInit(void) r_vsync = Cvar_Get("r_vsync", "1", CVAR_ARCHIVE); } - if (!r_anisotropic) + if (!gl_anisotropic) { - r_anisotropic = Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); + gl_anisotropic = Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE); } if (!gl_msaa_samples) @@ -462,13 +462,13 @@ VID_MenuInit(void) s_af_list.generic.callback = AnisotropicCallback; s_af_list.itemnames = pow2_names; s_af_list.curvalue = 0; - if (r_anisotropic->value) + if (gl_anisotropic->value) { do { s_af_list.curvalue++; } while (pow2_names[s_af_list.curvalue] && - pow(2, s_af_list.curvalue) <= r_anisotropic->value); + pow(2, s_af_list.curvalue) <= gl_anisotropic->value); s_af_list.curvalue--; } diff --git a/src/client/refresh/gl1/gl1_image.c b/src/client/refresh/gl1/gl1_image.c index be9ac5b0..2734be84 100644 --- a/src/client/refresh/gl1/gl1_image.c +++ b/src/client/refresh/gl1/gl1_image.c @@ -202,18 +202,18 @@ R_TextureMode(char *string) /* clamp selected anisotropy */ if (gl_config.anisotropic) { - if (r_anisotropic->value > gl_config.max_anisotropy) + if (gl_anisotropic->value > gl_config.max_anisotropy) { - ri.Cvar_SetValue("r_anisotropic", gl_config.max_anisotropy); + ri.Cvar_SetValue("gl_anisotropic", gl_config.max_anisotropy); } - else if (r_anisotropic->value < 1.0) + else if (gl_anisotropic->value < 1.0) { - ri.Cvar_SetValue("r_anisotropic", 1.0); + ri.Cvar_SetValue("gl_anisotropic", 1.0); } } else { - ri.Cvar_SetValue("r_anisotropic", 0.0); + ri.Cvar_SetValue("gl_anisotropic", 0.0); } /* change all the existing mipmap texture objects */ @@ -228,10 +228,10 @@ R_TextureMode(char *string) gl_filter_max); /* Set anisotropic filter if supported and enabled */ - if (gl_config.anisotropic && r_anisotropic->value) + if (gl_config.anisotropic && gl_anisotropic->value) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - r_anisotropic->value); + gl_anisotropic->value); } } } @@ -788,10 +788,10 @@ R_Upload32(unsigned *data, int width, int height, qboolean mipmap) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } - if (mipmap && gl_config.anisotropic && r_anisotropic->value) + if (mipmap && gl_config.anisotropic && gl_anisotropic->value) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - r_anisotropic->value); + gl_anisotropic->value); } return res; } diff --git a/src/client/refresh/gl1/gl1_main.c b/src/client/refresh/gl1/gl1_main.c index c3c90dbe..ccef914d 100644 --- a/src/client/refresh/gl1/gl1_main.c +++ b/src/client/refresh/gl1/gl1_main.c @@ -124,7 +124,7 @@ cvar_t *r_vsync; cvar_t *gl_texturemode; cvar_t *gl1_texturealphamode; cvar_t *gl1_texturesolidmode; -cvar_t *r_anisotropic; +cvar_t *gl_anisotropic; cvar_t *r_lockpvs; cvar_t *gl_msaa_samples; @@ -425,7 +425,7 @@ R_DrawParticles2(int num_particles, const particle_t particles[], vec3_t up, right; float scale; byte color[4]; - + GLfloat vtx[3*num_particles*3]; GLfloat tex[2*num_particles*3]; GLfloat clr[4*num_particles*3]; @@ -433,7 +433,7 @@ R_DrawParticles2(int num_particles, const particle_t particles[], unsigned int index_tex = 0; unsigned int index_clr = 0; unsigned int j; - + R_Bind(r_particletexture->texnum); glDepthMask(GL_FALSE); /* no z buffering */ glEnable(GL_BLEND); @@ -505,7 +505,7 @@ R_DrawParticles2(int num_particles, const particle_t particles[], glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); - + glDisable(GL_BLEND); glColor4f(1, 1, 1, 1); glDepthMask(1); /* back to normal Z buffering */ @@ -523,12 +523,12 @@ R_DrawParticles(void) int i; unsigned char color[4]; const particle_t *p; - + GLfloat vtx[3*r_newrefdef.num_particles]; GLfloat clr[4*r_newrefdef.num_particles]; unsigned int index_vtx = 0; unsigned int index_clr = 0; - + glDepthMask(GL_FALSE); glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); @@ -1241,7 +1241,7 @@ R_Register(void) gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE); gl1_texturealphamode = ri.Cvar_Get("gl1_texturealphamode", "default", CVAR_ARCHIVE); gl1_texturesolidmode = ri.Cvar_Get("gl1_texturesolidmode", "default", CVAR_ARCHIVE); - r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); + gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE); r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", 0); gl1_palettedtexture = ri.Cvar_Get("gl1_palettedtexture", "0", CVAR_ARCHIVE); @@ -1676,11 +1676,11 @@ RI_BeginFrame(float camera_separation) } /* texturemode stuff */ - if (gl_texturemode->modified || (gl_config.anisotropic && r_anisotropic->modified)) + if (gl_texturemode->modified || (gl_config.anisotropic && gl_anisotropic->modified)) { R_TextureMode(gl_texturemode->string); gl_texturemode->modified = false; - r_anisotropic->modified = false; + gl_anisotropic->modified = false; } if (gl1_texturealphamode->modified) @@ -1751,11 +1751,11 @@ R_DrawBeam(entity_t *e) vec3_t direction, normalized_direction; vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS]; vec3_t oldorigin, origin; - + GLfloat vtx[3*NUM_BEAM_SEGS*4]; unsigned int index_vtx = 0; unsigned int pointb; - + oldorigin[0] = e->oldorigin[0]; oldorigin[1] = e->oldorigin[1]; oldorigin[2] = e->oldorigin[2]; diff --git a/src/client/refresh/gl1/header/local.h b/src/client/refresh/gl1/header/local.h index 6fd7e3b9..5d4a368f 100644 --- a/src/client/refresh/gl1/header/local.h +++ b/src/client/refresh/gl1/header/local.h @@ -215,7 +215,7 @@ extern cvar_t *gl1_flashblend; extern cvar_t *r_modulate; extern cvar_t *gl_drawbuffer; extern cvar_t *r_vsync; -extern cvar_t *r_anisotropic; +extern cvar_t *gl_anisotropic; extern cvar_t *gl_texturemode; extern cvar_t *gl1_texturealphamode; extern cvar_t *gl1_texturesolidmode; diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index 8ba587e4..12d047ee 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -74,18 +74,18 @@ GL3_TextureMode(char *string) /* clamp selected anisotropy */ if (gl3config.anisotropic) { - if (r_anisotropic->value > gl3config.max_anisotropy) + if (gl_anisotropic->value > gl3config.max_anisotropy) { - ri.Cvar_SetValue("r_anisotropic", gl3config.max_anisotropy); + ri.Cvar_SetValue("gl_anisotropic", gl3config.max_anisotropy); } - else if (r_anisotropic->value < 1.0) + else if (gl_anisotropic->value < 1.0) { - ri.Cvar_SetValue("r_anisotropic", 1.0); + ri.Cvar_SetValue("gl_anisotropic", 1.0); } } else { - ri.Cvar_SetValue("r_anisotropic", 0.0); + ri.Cvar_SetValue("gl_anisotropic", 0.0); } gl3image_t *glt; @@ -101,9 +101,9 @@ GL3_TextureMode(char *string) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); /* Set anisotropic filter if supported and enabled */ - if (gl3config.anisotropic && r_anisotropic->value) + if (gl3config.anisotropic && gl_anisotropic->value) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_anisotropic->value); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value); } } } @@ -200,9 +200,9 @@ GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } - if (mipmap && gl3config.anisotropic && r_anisotropic->value) + if (mipmap && gl3config.anisotropic && gl_anisotropic->value) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_anisotropic->value); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value); } return res; diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 78ab8029..1990f071 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -87,7 +87,7 @@ cvar_t *r_mode; cvar_t *r_customwidth; cvar_t *r_customheight; cvar_t *vid_gamma; -cvar_t *r_anisotropic; +cvar_t *gl_anisotropic; cvar_t *gl_texturemode; cvar_t *gl_drawbuffer; cvar_t *r_clear; @@ -216,7 +216,7 @@ GL3_Register(void) gl_nobind = ri.Cvar_Get("gl_nobind", "0", 0); gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE); - r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); + gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE); vid_fullscreen = ri.Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE); vid_gamma = ri.Cvar_Get("vid_gamma", "1.2", CVAR_ARCHIVE); @@ -276,7 +276,7 @@ GL3_Register(void) //gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE); gl1_texturealphamode = ri.Cvar_Get("gl1_texturealphamode", "default", CVAR_ARCHIVE); gl1_texturesolidmode = ri.Cvar_Get("gl1_texturesolidmode", "default", CVAR_ARCHIVE); - //r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); + //gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE); //r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", 0); //gl1_palettedtexture = ri.Cvar_Get("gl1_palettedtexture", "0", CVAR_ARCHIVE); NOPE. @@ -1657,11 +1657,11 @@ GL3_BeginFrame(float camera_separation) } /* texturemode stuff */ - if (gl_texturemode->modified || (gl3config.anisotropic && r_anisotropic->modified)) + if (gl_texturemode->modified || (gl3config.anisotropic && gl_anisotropic->modified)) { GL3_TextureMode(gl_texturemode->string); gl_texturemode->modified = false; - r_anisotropic->modified = false; + gl_anisotropic->modified = false; } if (r_vsync->modified) diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index c632a5c2..a94e8a3d 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -498,7 +498,7 @@ extern cvar_t *r_drawworld; extern cvar_t *vid_gamma; extern cvar_t *gl3_intensity; extern cvar_t *gl3_intensity_2D; -extern cvar_t *r_anisotropic; +extern cvar_t *gl_anisotropic; extern cvar_t *r_lightlevel; extern cvar_t *gl3_overbrightbits; diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index b0df3bae..c18b2218 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -375,7 +375,6 @@ extern int d_pix_min, d_pix_max, d_pix_mul; extern pixel_t *d_viewbuffer; extern zvalue_t *d_pzbuffer; -extern unsigned int d_zwidth; extern int d_minmip; extern float d_scalemip[NUM_MIPS-1]; @@ -384,7 +383,6 @@ extern float d_scalemip[NUM_MIPS-1]; extern int cachewidth; extern pixel_t *cacheblock; -extern int r_screenwidth; extern int r_drawnpolycount; @@ -508,7 +506,7 @@ typedef struct { int sfrac, tfrac, light; zvalue_t zi; } spanpackage_t; -extern spanpackage_t *triangle_spans; +extern spanpackage_t *triangle_spans, *triangles_max; extern byte **warp_rowptr; extern int *warp_column; @@ -523,6 +521,7 @@ extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; extern int r_outofsurfaces; extern int r_outofedges; extern int r_outofverts; +extern int r_outoftriangles; extern mvertex_t *r_pcurrentvertbase; diff --git a/src/client/refresh/soft/sw_edge.c b/src/client/refresh/soft/sw_edge.c index f3a1c495..1c59e960 100644 --- a/src/client/refresh/soft/sw_edge.c +++ b/src/client/refresh/soft/sw_edge.c @@ -786,7 +786,7 @@ D_FlatFillSurface (surf_t *surf, pixel_t color) { pixel_t *pdest; - pdest = d_viewbuffer + r_screenwidth*span->v + span->u; + pdest = d_viewbuffer + vid.width*span->v + span->u; memset(pdest, color&0xFF, span->count * sizeof(pixel_t)); } } diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index fb91eb63..e98b783f 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -59,10 +59,6 @@ typedef struct swstate_s unsigned char gammatable[256]; unsigned char currentpalette[1024]; - - // SDL colors - Uint32 palette_colors[256]; - } swstate_t; static swstate_t sw_state; @@ -71,10 +67,12 @@ void *colormap; float r_time1; int r_numallocatededges; int r_numallocatedverts; +int r_numallocatedtriangles; float r_aliasuvscale = 1.0; int r_outofsurfaces; int r_outofedges; int r_outofverts; +int r_outoftriangles; qboolean r_dowarp; @@ -101,8 +99,6 @@ float xscaleinv, yscaleinv; float xscaleshrink, yscaleshrink; float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; -int r_screenwidth; - mplane_t screenedge[4]; // @@ -137,7 +133,7 @@ cvar_t *sw_surfcacheoverride; cvar_t *sw_waterwarp; static cvar_t *sw_overbrightbits; cvar_t *sw_custom_particles; -cvar_t *r_anisotropic; +cvar_t *sw_texture_filtering; cvar_t *r_drawworld; static cvar_t *r_drawentities; @@ -197,12 +193,9 @@ pixel_t *cacheblock; int cachewidth; pixel_t *d_viewbuffer; zvalue_t *d_pzbuffer; -unsigned int d_zwidth; qboolean insubmodel; -static qboolean sdl_palette_outdated; - static struct texture_buffer { image_t image; byte buffer[1024]; @@ -290,7 +283,7 @@ R_Register (void) sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0); sw_overbrightbits = ri.Cvar_Get("sw_overbrightbits", "1.0", CVAR_ARCHIVE); sw_custom_particles = ri.Cvar_Get("sw_custom_particles", "0", CVAR_ARCHIVE); - r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE); + sw_texture_filtering = ri.Cvar_Get("sw_texture_filtering", "0", CVAR_ARCHIVE); r_mode = ri.Cvar_Get( "r_mode", "0", CVAR_ARCHIVE ); r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE ); @@ -332,7 +325,9 @@ R_UnRegister (void) ri.Cmd_RemoveCommand( "imagelist" ); } -static void SWimp_DestroyRender(void); +static void RE_ShutdownContext(void); +static void SWimp_CreateRender(void); +static int RE_InitContext(void *win); /* =============== @@ -402,7 +397,7 @@ RE_Shutdown (void) Mod_FreeAll (); R_ShutdownImages (); - SWimp_DestroyRender(); + RE_ShutdownContext(); } /* @@ -528,6 +523,35 @@ R_ReallocateMapBuffers (void) R_Printf(PRINT_ALL, "Allocated %d verts\n", r_numallocatedverts); } + + if (!r_numallocatedtriangles || r_outoftriangles) + { + if (triangle_spans) + { + free(triangle_spans); + } + + if (r_outoftriangles) + { + //R_Printf(PRINT_ALL, "%s: not enough %d(+%d) triangles\n", + // __func__, r_numallocatedtriangles, r_outoftriangles); + r_numallocatedtriangles *= 2; + } + + if (r_numallocatedtriangles < vid.height) + r_numallocatedtriangles = vid.height; + + triangle_spans = malloc(r_numallocatedtriangles * sizeof(spanpackage_t)); + if (!triangle_spans) + { + R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n", + __func__, (int)(r_numallocatedtriangles * sizeof(spanpackage_t))); + return; + } + triangles_max = &triangle_spans[r_numallocatedtriangles]; + + R_Printf(PRINT_ALL, "Allocated %d triangles\n", r_numallocatedtriangles); + } } @@ -1269,12 +1293,11 @@ R_GammaCorrectAndSetPalette( const unsigned char *palette ) for ( i = 0; i < 256; i++ ) { - sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]]; - sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]]; - sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]]; + sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+2]]; // blue + sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]]; // green + sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+0]]; // red + sw_state.currentpalette[i*4+3] = 0xFF; // alpha } - - sdl_palette_outdated = true; } /* @@ -1508,6 +1531,12 @@ RE_IsVsyncActive(void) } } +static int RE_PrepareForWindow(void) +{ + int flags = SDL_SWSURFACE; + return flags; +} + /* =============== GetRefAPI @@ -1546,6 +1575,9 @@ GetRefAPI(refimport_t imp) re.Init = RE_Init; re.IsVSyncActive = RE_IsVsyncActive; re.Shutdown = RE_Shutdown; + re.InitContext = RE_InitContext; + re.ShutdownContext = RE_ShutdownContext; + re.PrepareForWindow = RE_PrepareForWindow; re.SetPalette = RE_SetPalette; re.BeginFrame = RE_BeginFrame; @@ -1571,106 +1603,26 @@ GetRefAPI(refimport_t imp) */ static SDL_Window *window = NULL; -static SDL_Surface *surface = NULL; static SDL_Texture *texture = NULL; static SDL_Renderer *renderer = NULL; -/* - * Sets the window icon - */ -static void -SetSDLIcon() -{ - /* The 64x64 32bit window icon */ - #include "../../vid/icon/q2icon64.h" - - /* these masks are needed to tell SDL_CreateRGBSurface(From) - to assume the data it gets is byte-wise RGB(A) data */ - Uint32 rmask, gmask, bmask, amask; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - int shift = (q2icon64.bytes_per_pixel == 3) ? 8 : 0; - rmask = 0xff000000 >> shift; - gmask = 0x00ff0000 >> shift; - bmask = 0x0000ff00 >> shift; - amask = 0x000000ff >> shift; -#else /* little endian, like x86 */ - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = (q2icon64.bytes_per_pixel == 3) ? 0 : 0xff000000; -#endif - - SDL_Surface* icon = SDL_CreateRGBSurfaceFrom((void*)q2icon64.pixel_data, q2icon64.width, - q2icon64.height, q2icon64.bytes_per_pixel*8, q2icon64.bytes_per_pixel*q2icon64.width, - rmask, gmask, bmask, amask); - - SDL_SetWindowIcon(window, icon); - - SDL_FreeSurface(icon); -} - static int -IsFullscreen() -{ - if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) { - return 1; - } else if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) { - return 2; - } else { - return 0; - } -} - -static qboolean -GetWindowSize(int* w, int* h) -{ - if(window == NULL || w == NULL || h == NULL) - return false; - - SDL_DisplayMode m; - if(SDL_GetWindowDisplayMode(window, &m) != 0) - { - Com_Printf("Can't get Displaymode: %s\n", SDL_GetError()); - return false; - } - *w = m.w; - *h = m.h; - - return true; -} - -static int -R_InitContext(SDL_Window *win) +RE_InitContext(void *win) { char title[40] = {0}; if(win == NULL) { - ri.Sys_Error(ERR_FATAL, "R_InitContext() must not be called with NULL argument!"); + ri.Sys_Error(ERR_FATAL, "RE_InitContext() must not be called with NULL argument!"); return false; } - window = win; + window = (SDL_Window *)win; /* Window title - set here so we can display renderer name in it */ snprintf(title, sizeof(title), "Yamagi Quake II %s - Soft Render", YQ2VERSION); SDL_SetWindowTitle(window, title); - return true; -} - -static qboolean -CreateSDLWindow(int flags, int w, int h) -{ - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - int windowPos = SDL_WINDOWPOS_UNDEFINED; - if (!SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) - return 0; - - // TODO: support fullscreen on different displays with SDL_WINDOWPOS_UNDEFINED_DISPLAY(displaynum) - window = SDL_CreateWindow("Yamagi Quake II", windowPos, windowPos, w, h, flags); - if (r_vsync->value) { renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); @@ -1680,17 +1632,30 @@ CreateSDLWindow(int flags, int w, int h) renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); } - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + /* Select the color for drawing. It is set to black here. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + + /* Clear the entire screen to our selected color. */ + SDL_RenderClear(renderer); + + /* Up until now everything was drawn behind the scenes. + This will show the new, black contents of the window. */ + SDL_RenderPresent(renderer); texture = SDL_CreateTexture(renderer, +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_BGRA8888, +#else SDL_PIXELFORMAT_ARGB8888, +#endif SDL_TEXTUREACCESS_STREAMING, - w, h); - return window != NULL; + vid.width, vid.height); + + return true; } static void -SWimp_DestroyRender(void) +RE_ShutdownContext(void) { if (vid_buffer) { @@ -1788,24 +1753,11 @@ SWimp_DestroyRender(void) } texture = NULL; - if (surface) - { - SDL_FreeSurface(surface); - } - surface = NULL; - if (renderer) { SDL_DestroyRenderer(renderer); } renderer = NULL; - - /* Is the surface used? */ - if (window) - { - SDL_DestroyWindow(window); - } - window = NULL; } /* @@ -1814,165 +1766,10 @@ point math used in R_ScanEdges() overflows at width 2048 !! */ char shift_size; -/* -** SWimp_InitGraphics -** -** This initializes the software refresh's implementation specific -** graphics subsystem. In the case of Windows it creates DIB or -** DDRAW surfaces. -** -** The necessary width and height parameters are grabbed from -** vid.width and vid.height. -*/ -static qboolean -SWimp_InitGraphics(int fullscreen, int *pwidth, int *pheight) -{ - int flags; - int curWidth, curHeight; - int width = *pwidth; - int height = *pheight; - unsigned int fs_flag = 0; - - if (fullscreen == 1) { - fs_flag = SDL_WINDOW_FULLSCREEN_DESKTOP; - } else if (fullscreen == 2) { - fs_flag = SDL_WINDOW_FULLSCREEN; - } - - if (GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height)) - { - /* If we want fullscreen, but aren't */ - if (fullscreen != IsFullscreen()) - { - SDL_SetWindowFullscreen(window, fs_flag); - - ri.Cvar_SetValue("vid_fullscreen", fullscreen); - } - - /* Are we now? */ - if (fullscreen == IsFullscreen()) - { - return true; - } - } - - SWimp_DestroyRender(); - - // let the sound and input subsystems know about the new window - ri.Vid_NewWindow (vid.width, vid.height); - - flags = SDL_SWSURFACE; - if (fs_flag) - { - flags |= fs_flag; - } - - while (1) - { - if (!CreateSDLWindow(flags, width, height)) - { - Sys_Error("(SOFTSDL) SDL SetVideoMode failed: %s\n", SDL_GetError()); - return false; - } - else - { - break; - } - } - - if(!R_InitContext(window)) - { - // InitContext() should have logged an error - return false; - } - - /* Note: window title is now set in re.InitContext() to include renderer name */ - /* Set the window icon - For SDL2, this must be done after creating the window */ - SetSDLIcon(); - - /* No cursor */ - SDL_ShowCursor(0); - - vid_buffer = malloc(vid.height * vid.width * sizeof(pixel_t)); - - sintable = malloc((vid.width+CYCLE) * sizeof(int)); - intsintable = malloc((vid.width+CYCLE) * sizeof(int)); - blanktable = malloc((vid.width+CYCLE) * sizeof(int)); - - newedges = malloc(vid.width * sizeof(edge_t *)); - removeedges = malloc(vid.width * sizeof(edge_t *)); - - // 1 extra for spanpackage that marks end - triangle_spans = malloc((vid.width + 1) * sizeof(spanpackage_t)); - - warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*)); - warp_column = malloc((vid.width+AMP2*2) * sizeof(int)); - - edge_basespans = malloc((vid.width*2) * sizeof(espan_t)); - - // count of "out of items" - r_outofsurfaces = r_outofedges = r_outofverts = 0; - // pointers to allocated buffers - finalverts = NULL; - r_edges = NULL; - lsurfs = NULL; - // curently allocated items - r_cnumsurfs = r_numallocatededges = r_numallocatedverts = 0; - - R_ReallocateMapBuffers(); - - r_warpbuffer = malloc(vid.height * vid.width * sizeof(pixel_t)); - - if ((vid.width >= 2048) && (sizeof(shift20_t) == 4)) // 2k+ resolution and 32 == shift20_t - { - shift_size = 18; - } - else - { - shift_size = 20; - } - - R_InitTurb (); - - vid_polygon_spans = malloc(sizeof(espan_t) * (vid.height + 1)); - - memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette)); - memset(sw_state.palette_colors, 0, sizeof(sw_state.palette_colors)); - - sdl_palette_outdated = true; - - return true; -} - - -static void -RE_SDLPaletteConvert (void) -{ - int i; - const unsigned char *palette = sw_state.currentpalette; - Uint32 *sdl_palette = sw_state.palette_colors; - - if (!sdl_palette_outdated) - return; - - sdl_palette_outdated = false; - for ( i = 0; i < 256; i++ ) - { - if (surface) - { - sdl_palette[i] = SDL_MapRGB(surface->format, - palette[i * 4 + 0], // red - palette[i * 4 + 1], // green - palette[i * 4 + 2] //blue - ); - } - } -} - static void RE_CopyFrame (Uint32 * pixels, int pitch) { - RE_SDLPaletteConvert(); + Uint32 *sdl_palette = (Uint32 *)sw_state.currentpalette; // no gaps between images rows if (pitch == vid.width) @@ -1986,7 +1783,7 @@ RE_CopyFrame (Uint32 * pixels, int pitch) for (pixels_pos = pixels; pixels_pos < max_pixels; pixels_pos++) { - *pixels_pos = sw_state.palette_colors[*buffer_pos]; + *pixels_pos = sdl_palette[*buffer_pos]; buffer_pos++; } } @@ -1999,7 +1796,7 @@ RE_CopyFrame (Uint32 * pixels, int pitch) { for (x=0; x < vid.width; x ++) { - pixels[x] = sw_state.palette_colors[vid_buffer[buffer_pos + x]]; + pixels[x] = sdl_palette[vid_buffer[buffer_pos + x]]; } pixels += pitch; buffer_pos += vid.width; @@ -2019,14 +1816,16 @@ static void RE_EndFrame (void) { int pitch; + Uint32 * pixels; - Uint32 * pixels = (Uint32 *)surface->pixels; - pitch = surface->pitch / sizeof(Uint32); + if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch)) + { + Com_Printf("Can't lock texture: %s\n", SDL_GetError()); + return; + } + RE_CopyFrame (pixels, pitch / sizeof(Uint32)); + SDL_UnlockTexture(texture); - RE_CopyFrame (pixels, pitch); - - SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); - SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } @@ -2049,16 +1848,66 @@ SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen ) R_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight); - if ( !SWimp_InitGraphics(fullscreen, pwidth, pheight) ) { + if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight)) + { // failed to set a valid mode in windowed mode return rserr_invalid_mode; } - R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); + SWimp_CreateRender(); return retval; } +static void +SWimp_CreateRender(void) +{ + vid_buffer = malloc(vid.height * vid.width * sizeof(pixel_t)); + + sintable = malloc((vid.width+CYCLE) * sizeof(int)); + intsintable = malloc((vid.width+CYCLE) * sizeof(int)); + blanktable = malloc((vid.width+CYCLE) * sizeof(int)); + + newedges = malloc(vid.width * sizeof(edge_t *)); + removeedges = malloc(vid.width * sizeof(edge_t *)); + + warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*)); + warp_column = malloc((vid.width+AMP2*2) * sizeof(int)); + + edge_basespans = malloc((vid.width*2) * sizeof(espan_t)); + + // count of "out of items" + r_outofsurfaces = r_outofedges = r_outofverts = r_outoftriangles = 0; + // pointers to allocated buffers + finalverts = NULL; + r_edges = NULL; + lsurfs = NULL; + triangle_spans = NULL; + // curently allocated items + r_cnumsurfs = r_numallocatededges = r_numallocatedverts = r_numallocatedtriangles = 0; + + R_ReallocateMapBuffers(); + + r_warpbuffer = malloc(vid.height * vid.width * sizeof(pixel_t)); + + if ((vid.width >= 2048) && (sizeof(shift20_t) == 4)) // 2k+ resolution and 32 == shift20_t + { + shift_size = 18; + } + else + { + shift_size = 20; + } + + R_InitTurb (); + + vid_polygon_spans = malloc(sizeof(espan_t) * (vid.height + 1)); + + memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette)); + + R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); +} + // this is only here so the functions in q_shared.c and q_shwin.c can link void Sys_Error (char *error, ...) @@ -2116,9 +1965,9 @@ R_ScreenShot_f(void) { for (y=0; y < vid.height; y ++) { int buffer_pos = y * vid.width + x; - buffer[buffer_pos * 3 + 0] = palette[vid_buffer[buffer_pos] * 4 + 0]; // red + buffer[buffer_pos * 3 + 0] = palette[vid_buffer[buffer_pos] * 4 + 2]; // red buffer[buffer_pos * 3 + 1] = palette[vid_buffer[buffer_pos] * 4 + 1]; // green - buffer[buffer_pos * 3 + 2] = palette[vid_buffer[buffer_pos] * 4 + 2]; // blue + buffer[buffer_pos * 3 + 2] = palette[vid_buffer[buffer_pos] * 4 + 0]; // blue } } diff --git a/src/client/refresh/soft/sw_misc.c b/src/client/refresh/soft/sw_misc.c index 54597c0f..224825fd 100644 --- a/src/client/refresh/soft/sw_misc.c +++ b/src/client/refresh/soft/sw_misc.c @@ -47,8 +47,6 @@ D_ViewChanged (void) if (yscale > xscale) scale_for_mip = yscale; - d_zwidth = vid.width; - d_pix_min = r_refdef.vrect.height / 240; if (d_pix_min < 1) d_pix_min = 1; @@ -360,7 +358,6 @@ R_SetupFrame (void) vrect.height = r_newrefdef.height; d_viewbuffer = r_warpbuffer; - r_screenwidth = vid.width; } else { @@ -370,7 +367,6 @@ R_SetupFrame (void) vrect.height = r_newrefdef.height; d_viewbuffer = vid_buffer; - r_screenwidth = vid.width; } R_ViewChanged (&vrect); @@ -392,6 +388,7 @@ R_SetupFrame (void) r_outofsurfaces = 0; r_outofverts = 0; r_outofedges = 0; + r_outoftriangles = 0; // d_setup d_minmip = sw_mipcap->value; diff --git a/src/client/refresh/soft/sw_part.c b/src/client/refresh/soft/sw_part.c index 9f844454..a64d9da3 100644 --- a/src/client/refresh/soft/sw_part.c +++ b/src/client/refresh/soft/sw_part.c @@ -83,8 +83,8 @@ R_DrawParticle(particle_t *pparticle, int level) ** compute addresses of zbuffer, framebuffer, and ** compute the Z-buffer reference value. */ - pz = d_pzbuffer + (d_zwidth * v) + u; - pdest = d_viewbuffer + r_screenwidth * v + u; + pz = d_pzbuffer + (vid.width * v) + u; + pdest = d_viewbuffer + vid.width * v + u; izi = (int)(zi * 0x8000); /* @@ -106,7 +106,7 @@ R_DrawParticle(particle_t *pparticle, int level) { switch (level) { case PARTICLE_33 : - for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth) + for ( ; count ; count--, pz += vid.width, pdest += vid.width) { //FIXME--do it in blocks of 8? for (i=0 ; iv) + pspan->u; - s_spanletvars.pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + s_spanletvars.pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u; + s_spanletvars.pz = d_pzbuffer + (vid.width * pspan->v) + pspan->u; s_spanletvars.u = pspan->u; s_spanletvars.v = pspan->v; count = pspan->count; diff --git a/src/client/refresh/soft/sw_polyse.c b/src/client/refresh/soft/sw_polyse.c index 35c58baf..1ed1ae44 100644 --- a/src/client/refresh/soft/sw_polyse.c +++ b/src/client/refresh/soft/sw_polyse.c @@ -65,10 +65,9 @@ static int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; static zvalue_t r_zistepx, r_zistepy; static int d_aspancount, d_countextrastep; -static spanpackage_t *a_spans; static spanpackage_t *d_pedgespanpackage; -spanpackage_t *triangle_spans; +spanpackage_t *triangle_spans, *triangles_max; static int ystart; static pixel_t *d_pdest, *d_ptex; @@ -208,8 +207,6 @@ R_DrawTriangle(const finalvert_t *a, const finalvert_t *b, const finalvert_t *c) if ( d_xdenom < 0 ) { - a_spans = triangle_spans; - r_p0[0] = a->u; // u r_p0[1] = a->v; // v r_p0[2] = a->s; // s @@ -236,6 +233,30 @@ R_DrawTriangle(const finalvert_t *a, const finalvert_t *b, const finalvert_t *c) } } +static void +R_PushEdgesSpan() +{ + if (d_pedgespanpackage >= triangles_max) + { + // no space any more + r_outoftriangles++; + return; + } + + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; +} /* =================== @@ -247,19 +268,7 @@ R_PolysetScanLeftEdge_C(int height) { do { - d_pedgespanpackage->pdest = d_pdest; - d_pedgespanpackage->pz = d_pz; - d_pedgespanpackage->count = d_aspancount; - d_pedgespanpackage->ptex = d_ptex; - - d_pedgespanpackage->sfrac = d_sfrac; - d_pedgespanpackage->tfrac = d_tfrac; - - // FIXME: need to clamp l, s, t, at both ends? - d_pedgespanpackage->light = d_light; - d_pedgespanpackage->zi = d_zi; - - d_pedgespanpackage++; + R_PushEdgesSpan(); errorterm += erroradjustup; if (errorterm >= 0) @@ -359,8 +368,6 @@ R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, int tm, tn; adivtab_t *ptemp; - // TODO: implement x86 version - errorterm = -1; tm = endvertu - startvertu; @@ -782,7 +789,7 @@ R_RasterizeAliasPolySmooth (void) // // scan out the top (and possibly only) part of the left edge // - d_pedgespanpackage = a_spans; + d_pedgespanpackage = triangle_spans; ystart = plefttop[1]; d_aspancount = plefttop[0] - prighttop[0]; @@ -796,35 +803,23 @@ R_RasterizeAliasPolySmooth (void) d_light = plefttop[4]; d_zi = plefttop[5]; - d_pdest = d_viewbuffer + ystart * r_screenwidth + plefttop[0]; - d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + d_pdest = d_viewbuffer + ystart * vid.width + plefttop[0]; + d_pz = d_pzbuffer + ystart * vid.width + plefttop[0]; if (initialleftheight == 1) { - d_pedgespanpackage->pdest = d_pdest; - d_pedgespanpackage->pz = d_pz; - d_pedgespanpackage->count = d_aspancount; - d_pedgespanpackage->ptex = d_ptex; - - d_pedgespanpackage->sfrac = d_sfrac; - d_pedgespanpackage->tfrac = d_tfrac; - - // FIXME: need to clamp l, s, t, at both ends? - d_pedgespanpackage->light = d_light; - d_pedgespanpackage->zi = d_zi; - - d_pedgespanpackage++; + R_PushEdgesSpan(); } else { R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], pleftbottom[0], pleftbottom[1]); { - d_pzbasestep = d_zwidth + ubasestep; + d_pzbasestep = vid.width + ubasestep; d_pzextrastep = d_pzbasestep + 1; } - d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestbasestep = vid.width + ubasestep; d_pdestextrastep = d_pdestbasestep + 1; // TODO: can reuse partial expressions here @@ -886,35 +881,23 @@ R_RasterizeAliasPolySmooth (void) d_light = plefttop[4]; d_zi = plefttop[5]; - d_pdest = d_viewbuffer + ystart * r_screenwidth + plefttop[0]; - d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + d_pdest = d_viewbuffer + ystart * vid.width + plefttop[0]; + d_pz = d_pzbuffer + ystart * vid.width + plefttop[0]; if (height == 1) { - d_pedgespanpackage->pdest = d_pdest; - d_pedgespanpackage->pz = d_pz; - d_pedgespanpackage->count = d_aspancount; - d_pedgespanpackage->ptex = d_ptex; - - d_pedgespanpackage->sfrac = d_sfrac; - d_pedgespanpackage->tfrac = d_tfrac; - - // FIXME: need to clamp l, s, t, at both ends? - d_pedgespanpackage->light = d_light; - d_pedgespanpackage->zi = d_zi; - - d_pedgespanpackage++; + R_PushEdgesSpan(); } else { R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], pleftbottom[0], pleftbottom[1]); - d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestbasestep = vid.width + ubasestep; d_pdestextrastep = d_pdestbasestep + 1; { - d_pzbasestep = d_zwidth + ubasestep; + d_pzbasestep = vid.width + ubasestep; d_pzextrastep = d_pzbasestep + 1; } @@ -952,15 +935,21 @@ R_RasterizeAliasPolySmooth (void) // scan out the top (and possibly only) part of the right edge, updating the // count field - d_pedgespanpackage = a_spans; + d_pedgespanpackage = triangle_spans; R_PolysetSetUpForLineScan(prighttop[0], prighttop[1], prightbottom[0], prightbottom[1]); d_aspancount = 0; d_countextrastep = ubasestep + 1; - originalcount = a_spans[initialrightheight].count; - a_spans[initialrightheight].count = -999999; // mark end of the spanpackages - (*d_pdrawspans) (a_spans); + if ((triangle_spans + initialrightheight) >= triangles_max) + { + // we dont have enough triangles for save full height + r_outoftriangles++; + return; + } + originalcount = triangle_spans[initialrightheight].count; + triangle_spans[initialrightheight].count = -999999; // mark end of the spanpackages + (*d_pdrawspans) (triangle_spans); // scan out the bottom part of the right edge, if it exists if (pedgetable->numrightedges == 2) @@ -968,7 +957,7 @@ R_RasterizeAliasPolySmooth (void) int height; spanpackage_t *pstart; - pstart = a_spans + initialrightheight; + pstart = triangle_spans + initialrightheight; pstart->count = originalcount; d_aspancount = prightbottom[0] - prighttop[0]; @@ -982,7 +971,14 @@ R_RasterizeAliasPolySmooth (void) prightbottom[0], prightbottom[1]); d_countextrastep = ubasestep + 1; - a_spans[initialrightheight + height].count = -999999; // mark end of the spanpackages + + if ((triangle_spans + initialrightheight + height) >= triangles_max) + { + // we dont have enough triangles for save full height + r_outoftriangles++; + return; + } + triangle_spans[initialrightheight + height].count = -999999; // mark end of the spanpackages (*d_pdrawspans) (pstart); } } diff --git a/src/client/refresh/soft/sw_scan.c b/src/client/refresh/soft/sw_scan.c index 2a3ef3ac..017ccc94 100644 --- a/src/client/refresh/soft/sw_scan.c +++ b/src/client/refresh/soft/sw_scan.c @@ -25,7 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SPANSTEP_SHIFT 4 -#define SPANSTEP (1 << SPANSTEP_SHIFT) byte **warp_rowptr; int *warp_column; @@ -100,7 +99,7 @@ Return safe span step for u/z and v/z ============= */ static int -D_DrawSpanGetStep(float d_zistepu, float d_zistepv, int cachewidth) +D_DrawSpanGetStep(float d_zistepu, float d_zistepv) { int spanzshift = SPANSTEP_SHIFT; int spanzshift_value = (1 << spanzshift); @@ -115,24 +114,46 @@ D_DrawSpanGetStep(float d_zistepu, float d_zistepv, int cachewidth) (int)(d_zistepv_shifted * spanzshift_value) == 0) { // search next safe value - while (spanzshift_value < vid.width && - (int)(d_zistepu_shifted * spanzshift_value) == 0 && - (int)(d_zistepv_shifted * spanzshift_value) == 0) + do { spanzshift ++; spanzshift_value <<= 1; - } - // step back to last safe value - if ((int)(d_zistepu_shifted * spanzshift_value) != 0 || - (int)(d_zistepv_shifted * spanzshift_value) != 0) - { - spanzshift --; + if ((int)(d_zistepu_shifted * spanzshift_value) != 0 || + (int)(d_zistepv_shifted * spanzshift_value) != 0) + { + // step back to last safe value + return spanzshift - 1; + } + } + while (spanzshift_value < vid.width); } return spanzshift; } +/* +============= +D_DrawZSpanGetStepValue + +Return safe span step for izistep +============= +*/ +static int +D_DrawZSpanGetStepValue(zvalue_t izistep) +{ + // check that we can draw parallel surfaces to screen surface + // (both ends have same z value) + int count = 1; + + while ((izistep * count) >> SHIFT16XYZ == 0 && count < vid.width) + { + count <<= 1; + } + + return count; +} + /* ============= D_DrawTurbulentSpan @@ -169,14 +190,18 @@ TurbulentPow2 (espan_t *pspan) float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu; pixel_t *r_turb_pbase; int *r_turb_turb; + int spanstep_shift, spanstep_value; + + spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv); + spanstep_value = (1 << spanstep_shift); r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1)); r_turb_pbase = (unsigned char *)cacheblock; - sdivzpow2stepu = d_sdivzstepu * SPANSTEP; - tdivzpow2stepu = d_tdivzstepu * SPANSTEP; - zipow2stepu = d_zistepu * SPANSTEP; + sdivzpow2stepu = d_sdivzstepu * spanstep_value; + tdivzpow2stepu = d_tdivzstepu * spanstep_value; + zipow2stepu = d_zistepu * spanstep_value; do { @@ -184,7 +209,7 @@ TurbulentPow2 (espan_t *pspan) float sdivz, tdivz, zi, z, du, dv; pixel_t *r_turb_pdest; - r_turb_pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u; + r_turb_pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u; count = pspan->count; @@ -219,8 +244,8 @@ TurbulentPow2 (espan_t *pspan) r_turb_tstep = 0; // ditto // calculate s and t at the far end of the span - if (count >= SPANSTEP) - r_turb_spancount = SPANSTEP; + if (count >= spanstep_value) + r_turb_spancount = spanstep_value; else r_turb_spancount = count; @@ -238,21 +263,21 @@ TurbulentPow2 (espan_t *pspan) snext = (int)(sdivz * z) + sadjust; if (snext > bbextents) snext = bbextents; - else if (snext < SPANSTEP) + else if (snext < spanstep_value) // prevent round-off error on <0 steps from // from causing overstepping & running off the // edge of the texture - snext = SPANSTEP; + snext = spanstep_value; tnext = (int)(tdivz * z) + tadjust; if (tnext > bbextentt) tnext = bbextentt; - else if (tnext < SPANSTEP) + else if (tnext < spanstep_value) // guard against round-off error on <0 steps - tnext = SPANSTEP; + tnext = spanstep_value; - r_turb_sstep = (snext - r_turb_s) >> SPANSTEP_SHIFT; - r_turb_tstep = (tnext - r_turb_t) >> SPANSTEP_SHIFT; + r_turb_sstep = (snext - r_turb_s) >> spanstep_shift; + r_turb_tstep = (tnext - r_turb_t) >> spanstep_shift; } else { @@ -268,18 +293,18 @@ TurbulentPow2 (espan_t *pspan) snext = (int)(sdivz * z) + sadjust; if (snext > bbextents) snext = bbextents; - else if (snext < SPANSTEP) + else if (snext < spanstep_value) // prevent round-off error on <0 steps from // from causing overstepping & running off the // edge of the texture - snext = SPANSTEP; + snext = spanstep_value; tnext = (int)(tdivz * z) + tadjust; if (tnext > bbextentt) tnext = bbextentt; - else if (tnext < SPANSTEP) + else if (tnext < spanstep_value) // guard against round-off error on <0 steps - tnext = SPANSTEP; + tnext = spanstep_value; if (r_turb_spancount > 1) { @@ -320,14 +345,18 @@ NonTurbulentPow2 (espan_t *pspan) float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu; pixel_t *r_turb_pbase; int *r_turb_turb; + int spanstep_shift, spanstep_value; + + spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv); + spanstep_value = (1 << spanstep_shift); r_turb_turb = blanktable; r_turb_pbase = (unsigned char *)cacheblock; - sdivzpow2stepu = d_sdivzstepu * SPANSTEP; - tdivzpow2stepu = d_tdivzstepu * SPANSTEP; - zipow2stepu = d_zistepu * SPANSTEP; + sdivzpow2stepu = d_sdivzstepu * spanstep_value; + tdivzpow2stepu = d_tdivzstepu * spanstep_value; + zipow2stepu = d_zistepu * spanstep_value; do { @@ -335,7 +364,7 @@ NonTurbulentPow2 (espan_t *pspan) float sdivz, tdivz, zi, z, dv, du; pixel_t *r_turb_pdest; - r_turb_pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u; + r_turb_pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u; count = pspan->count; @@ -370,8 +399,8 @@ NonTurbulentPow2 (espan_t *pspan) r_turb_tstep = 0; // ditto // calculate s and t at the far end of the span - if (count >= SPANSTEP) - r_turb_spancount = SPANSTEP; + if (count >= spanstep_value) + r_turb_spancount = spanstep_value; else r_turb_spancount = count; @@ -389,21 +418,21 @@ NonTurbulentPow2 (espan_t *pspan) snext = (int)(sdivz * z) + sadjust; if (snext > bbextents) snext = bbextents; - else if (snext < SPANSTEP) + else if (snext < spanstep_value) // prevent round-off error on <0 steps from // from causing overstepping & running off the // edge of the texture - snext = SPANSTEP; + snext = spanstep_value; tnext = (int)(tdivz * z) + tadjust; if (tnext > bbextentt) tnext = bbextentt; - else if (tnext < SPANSTEP) + else if (tnext < spanstep_value) // guard against round-off error on <0 steps - tnext = SPANSTEP; + tnext = spanstep_value; - r_turb_sstep = (snext - r_turb_s) >> SPANSTEP_SHIFT; - r_turb_tstep = (tnext - r_turb_t) >> SPANSTEP_SHIFT; + r_turb_sstep = (snext - r_turb_s) >> spanstep_shift; + r_turb_tstep = (tnext - r_turb_t) >> spanstep_shift; } else { @@ -419,18 +448,18 @@ NonTurbulentPow2 (espan_t *pspan) snext = (int)(sdivz * z) + sadjust; if (snext > bbextents) snext = bbextents; - else if (snext < SPANSTEP) + else if (snext < spanstep_value) // prevent round-off error on <0 steps from // from causing overstepping & running off the // edge of the texture - snext = SPANSTEP; + snext = spanstep_value; tnext = (int)(tdivz * z) + tadjust; if (tnext > bbextentt) tnext = bbextentt; - else if (tnext < SPANSTEP) + else if (tnext < spanstep_value) // guard against round-off error on <0 steps - tnext = SPANSTEP; + tnext = spanstep_value; if (r_turb_spancount > 1) { @@ -459,7 +488,7 @@ NonTurbulentPow2 (espan_t *pspan) //==================== // Enable custom filtering -extern cvar_t *r_anisotropic; +extern cvar_t *sw_texture_filtering; static const int filtering_kernel[2][2][2] = { { {0x1 << (SHIFT16XYZ-2), 0x0}, @@ -572,12 +601,12 @@ D_DrawSpansPow2 (espan_t *pspan) int texture_filtering; int spanstep_shift, spanstep_value; - spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv, cachewidth); + spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv); spanstep_value = (1 << spanstep_shift); pbase = (unsigned char *)cacheblock; - texture_filtering = (int)r_anisotropic->value; + texture_filtering = (int)sw_texture_filtering->value; sdivzpow2stepu = d_sdivzstepu * spanstep_value; tdivzpow2stepu = d_tdivzstepu * spanstep_value; zipow2stepu = d_zistepu * spanstep_value; @@ -588,7 +617,7 @@ D_DrawSpansPow2 (espan_t *pspan) int count, s, t; float sdivz, tdivz, zi, z, du, dv; - pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u; + pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u; count = pspan->count; @@ -717,10 +746,12 @@ void D_DrawZSpans (espan_t *pspan) { zvalue_t izistep; + int safe_step; // FIXME: check for clamping/range problems // we count on FP exceptions being turned off to avoid range problems izistep = (int)(d_zistepu * 0x8000 * (float)SHIFT16XYZ_MULT); + safe_step = D_DrawZSpanGetStepValue(izistep); do { @@ -730,7 +761,7 @@ D_DrawZSpans (espan_t *pspan) float zi; float du, dv; - pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + pdest = d_pzbuffer + (vid.width * pspan->v) + pspan->u; count = pspan->count; @@ -742,11 +773,29 @@ D_DrawZSpans (espan_t *pspan) // we count on FP exceptions being turned off to avoid range problems izi = (int)(zi * 0x8000 * (float)SHIFT16XYZ_MULT); - while (count > 0) + if (safe_step > 1) { - *pdest++ = izi >> SHIFT16XYZ; - izi += izistep; - count--; + const zvalue_t *tdest_max = pdest + count; + do + { + int step; + zvalue_t izi_shifted = izi >> SHIFT16XYZ; + + for(step = 0; (step < safe_step) && (pdest < tdest_max); step++) + { + *pdest++ = izi_shifted; + } + izi += (izistep * safe_step); + } while (pdest < tdest_max); + } + else + { + while (count > 0) + { + *pdest++ = izi >> SHIFT16XYZ; + izi += izistep; + count--; + } } } while ((pspan = pspan->pnext) != NULL); } diff --git a/src/client/refresh/soft/sw_surf.c b/src/client/refresh/soft/sw_surf.c index ca7519e7..f7e57660 100644 --- a/src/client/refresh/soft/sw_surf.c +++ b/src/client/refresh/soft/sw_surf.c @@ -80,7 +80,6 @@ R_DrawSurface (drawsurf_t *drawsurf) int smax, tmax, twidth; int u; int soffset, basetoffset, texwidth; - int horzblockstep; unsigned char *pcolumndest; image_t *mt; @@ -104,7 +103,7 @@ R_DrawSurface (drawsurf_t *drawsurf) //============================== // TODO: only needs to be set when there is a display settings change - horzblockstep = blocksize; + blocksize = blocksize; smax = mt->width >> drawsurf->surfmip; twidth = texwidth; @@ -138,7 +137,7 @@ R_DrawSurface (drawsurf_t *drawsurf) if (soffset >= smax) soffset = 0; - pcolumndest += horzblockstep; + pcolumndest += blocksize; } } diff --git a/src/client/vid/glimp_sdl.c b/src/client/vid/glimp_sdl.c index f9839e08..774a26f8 100644 --- a/src/client/vid/glimp_sdl.c +++ b/src/client/vid/glimp_sdl.c @@ -36,6 +36,7 @@ cvar_t *vid_displayrefreshrate; int glimp_refreshRate = -1; +static int last_flags = 0; static SDL_Window* window = NULL; static qboolean initSuccessful = false; @@ -219,10 +220,10 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight) } /* Only do this if we already have a working window and a fully - initialized rendering backend GLimp_InitGraphics() is also - called when recovering if creating GL context fails or the - one we got is unusable. */ - if (initSuccessful && GetWindowSize(&curWidth, &curHeight) + initialized rendering backend GLimp_InitGraphics() is also + called when recovering if creating GL context fails or the + one we got is unusable. */ + if (initSuccessful && GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height)) { /* If we want fullscreen, but aren't */ @@ -252,8 +253,11 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight) viddef.width = width; viddef.height = height; - /* Reset SDL. */ - SDL_GL_ResetAttributes(); + if(last_flags != -1 && (last_flags & SDL_WINDOW_OPENGL)) + { + /* Reset SDL. */ + SDL_GL_ResetAttributes(); + } /* Let renderer prepare things (set OpenGL attributes). FIXME: This is no longer necessary, the renderer @@ -317,6 +321,8 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight) } } + last_flags = flags; + if (!re.InitContext(window)) { /* InitContext() should have logged an error. */ diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index e6833caa..be5cac82 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -226,7 +226,6 @@ typedef struct qboolean (IMPORT *Vid_GetModeInfo)(int *width, int *height, int mode); void (IMPORT *Vid_MenuInit)( void ); - void (IMPORT *Vid_NewWindow)( int width, int height ); // called with image data of width*height pixel which comp bytes per pixel (must be 3 or 4 for RGB or RGBA) // expects the pixels data to be row-wise, starting at top left void (IMPORT *Vid_WriteScreenshot)( int width, int height, int comp, const void* data ); diff --git a/src/client/vid/vid.c b/src/client/vid/vid.c index 1625dd82..fc353bba 100644 --- a/src/client/vid/vid.c +++ b/src/client/vid/vid.c @@ -42,7 +42,7 @@ compress_for_stbiw(unsigned char *data, int data_len, int *out_len, int quality) { uLongf bufSize = compressBound(data_len); unsigned char* buf = malloc(bufSize); - + if (buf == NULL) { return NULL; @@ -192,7 +192,7 @@ void VID_WriteScreenshot(int width, int height, int comp, const void* data) { Com_Printf("SCR_ScreenShot_f: Couldn't write %s\n", picname); } -} +} // -------- @@ -309,18 +309,6 @@ VID_Restart_f(void) vid_fullscreen->modified = true; } -/* - * FIXME: This is only used by the softrenderer. The software - * renderer should be ported to the API provided by refresh.c - * and this call removed. - */ -void -VID_NewWindow(int width, int height) -{ - viddef.width = width; - viddef.height = height; -} - /* * Shuts the renderer down and unloads it. */ @@ -402,7 +390,6 @@ VID_LoadRenderer(void) ri.Sys_Error = Com_Error; ri.Vid_GetModeInfo = VID_GetModeInfo; ri.Vid_MenuInit = VID_MenuInit; - ri.Vid_NewWindow = VID_NewWindow; ri.Vid_WriteScreenshot = VID_WriteScreenshot; // Exchange our export struct with the renderers import struct. @@ -440,7 +427,7 @@ VID_LoadRenderer(void) return true; } - + /* * Checks if a renderer changes was requested and executes it. * Inclusive fallback through all renderers. :) @@ -469,7 +456,7 @@ VID_CheckChanges(void) // Mkay, let's try our luck. while (!VID_LoadRenderer()) { - // We try: gl3 -> gl1 -> soft. + // We try: gl3 -> gl1 -> soft. if (strcmp(vid_renderer->string, "gl3") == 0) { Com_Printf("Retrying with gl1...\n"); @@ -480,7 +467,7 @@ VID_CheckChanges(void) Com_Printf("Retrying with soft...\n"); Cvar_Set("vid_renderer", "soft"); } - else if (strcmp("vid_renderer", "soft") == 0) + else if (strcmp(vid_renderer->string, "soft") == 0) { // Sorry, no usable renderer found. Com_Error(ERR_FATAL, "No usable renderer found!\n"); diff --git a/src/common/cvar.c b/src/common/cvar.c index 719ec6ed..3237d091 100644 --- a/src/common/cvar.c +++ b/src/common/cvar.c @@ -39,7 +39,6 @@ typedef struct replacement_t replacements[] = { {"cd_shuffle", "ogg_shuffle"}, {"cl_drawfps", "cl_showfps"}, - {"gl_anisotropic", "r_anisotropic"}, {"gl_drawentities", "r_drawentities"}, {"gl_drawworld", "r_drawworld"}, {"gl_fullbright", "r_fullbright"}, diff --git a/stuff/cvarlist.md b/stuff/cvarlist.md index 86d612fc..b24cf66f 100644 --- a/stuff/cvarlist.md +++ b/stuff/cvarlist.md @@ -163,15 +163,15 @@ Graphics (all renderers): * **r_vsync**: Enables the vsync: frames are synchronized with display refresh rate, should (but doesn't always) prevent tearing. -* **r_anisotropic**: Anisotropic filtering. Possible values are - dependent on the GPU driver, most of them support `1`, `2`, `4`, `8` - and `16`. Anisotropic filtering gives a huge improvement to texture - quality by a negligible performance impact. - Graphics (GL renderers only): ----------------------------- +* **gl_anisotropic**: Anisotropic filtering. Possible values are + dependent on the GPU driver, most of them support `1`, `2`, `4`, `8` + and `16`. Anisotropic filtering gives a huge improvement to texture + quality by a negligible performance impact. + * **gl_msaa_samples**: Full scene anti aliasing samples. The number of samples depends on the GPU driver, most drivers support at least `2`, `4` and `8` samples. If an invalid value is set, the value is