/* =============== R_SetVrect =============== */ public static void R_SetVrect(vid.vrect_t pvrectin, vid.vrect_t pvrect, int lineadj) { int h; double size; size = screen.scr_viewsize.value > 100 ? 100 : screen.scr_viewsize.value; if (client.cl.intermission != 0) { size = 100; lineadj = 0; } size /= 100; h = pvrectin.height - lineadj; pvrect.width = (int)(pvrectin.width * size); if (pvrect.width < 96) { size = 96.0 / pvrectin.width; pvrect.width = 96; // min for icons } pvrect.width &= ~7; pvrect.height = (int)(pvrectin.height * size); if (pvrect.height > pvrectin.height - lineadj) pvrect.height = pvrectin.height - lineadj; pvrect.height &= ~1; pvrect.x = (pvrectin.width - pvrect.width)/2; pvrect.y = (h - pvrect.height)/2; { if (view.lcd_x.value != 0) { pvrect.y >>= 1; pvrect.height >>= 1; } } }
/* =============== R_ViewChanged Called every time the vid structure or r_refdef changes. Guaranteed to be called before the first refresh =============== */ public static void R_ViewChanged(vid.vrect_t pvrect, int lineadj, double aspect) { int i; double res_scale; r_viewchanged = true; R_SetVrect(pvrect, r_refdef.vrect, lineadj); r_refdef.horizontalFieldOfView = 2.0 * Math.Tan(r_refdef.fov_x / 360 * mathlib.M_PI); r_refdef.fvrectx = (double)r_refdef.vrect.x; r_refdef.fvrectx_adj = (double)r_refdef.vrect.x - 0.5; r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x << 20) + (1 << 19) - 1; r_refdef.fvrecty = (double)r_refdef.vrect.y; r_refdef.fvrecty_adj = (double)r_refdef.vrect.y - 0.5; r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width; r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright << 20) + (1 << 19) - 1; r_refdef.fvrectright = (double)r_refdef.vrectright; r_refdef.fvrectright_adj = (double)r_refdef.vrectright - 0.5; r_refdef.vrectrightedge = (double)r_refdef.vrectright - 0.99; r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height; r_refdef.fvrectbottom = (double)r_refdef.vrectbottom; r_refdef.fvrectbottom_adj = (double)r_refdef.vrectbottom - 0.5; r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale); r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale); r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale); r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale); r_refdef.aliasvrectright = r_refdef.aliasvrect.x + r_refdef.aliasvrect.width; r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y + r_refdef.aliasvrect.height; pixelAspect = aspect; xOrigin = r_refdef.xOrigin; yOrigin = r_refdef.yOrigin; screenAspect = r_refdef.vrect.width * pixelAspect / r_refdef.vrect.height; // 320*200 1.0 pixelAspect = 1.6 screenAspect // 320*240 1.0 pixelAspect = 1.3333 screenAspect // proper 320*200 pixelAspect = 0.8333333 verticalFieldOfView = r_refdef.horizontalFieldOfView / screenAspect; // values for perspective projection // if math were exact, the values would range from 0.5 to to range+0.5 // hopefully they wll be in the 0.000001 to range+.999999 and truncate // the polygon rasterization will never render in the first row or column // but will definately render in the [range] row and column, so adjust the // buffer origin to get an exact edge to edge fill xcenter = ((double)r_refdef.vrect.width * XCENTERING) + r_refdef.vrect.x - 0.5; aliasxcenter = xcenter * r_aliasuvscale; ycenter = ((double)r_refdef.vrect.height * YCENTERING) + r_refdef.vrect.y - 0.5; aliasycenter = ycenter * r_aliasuvscale; xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView; aliasxscale = xscale * r_aliasuvscale; xscaleinv = 1.0 / xscale; yscale = xscale * pixelAspect; aliasyscale = yscale * r_aliasuvscale; yscaleinv = 1.0 / yscale; xscaleshrink = (r_refdef.vrect.width - 6) / r_refdef.horizontalFieldOfView; yscaleshrink = xscaleshrink * pixelAspect; // left side clip screenedge[0].normal[0] = -1.0 / (xOrigin * r_refdef.horizontalFieldOfView); screenedge[0].normal[1] = 0; screenedge[0].normal[2] = 1; screenedge[0].type = bspfile.PLANE_ANYZ; // right side clip screenedge[1].normal[0] = 1.0 / ((1.0 - xOrigin) * r_refdef.horizontalFieldOfView); screenedge[1].normal[1] = 0; screenedge[1].normal[2] = 1; screenedge[1].type = bspfile.PLANE_ANYZ; // top side clip screenedge[2].normal[0] = 0; screenedge[2].normal[1] = -1.0 / (yOrigin * verticalFieldOfView); screenedge[2].normal[2] = 1; screenedge[2].type = bspfile.PLANE_ANYZ; // bottom side clip screenedge[3].normal[0] = 0; screenedge[3].normal[1] = 1.0 / ((1.0 - yOrigin) * verticalFieldOfView); screenedge[3].normal[2] = 1; screenedge[3].type = bspfile.PLANE_ANYZ; for (i = 0; i < 4; i++) mathlib.VectorNormalize(screenedge[i].normal); res_scale = Math.Sqrt((double)(r_refdef.vrect.width * r_refdef.vrect.height) / (320.0 * 152.0)) * (2.0 / r_refdef.horizontalFieldOfView); r_aliastransition = r_aliastransbase.value * res_scale; r_resfudge = r_aliastransadj.value * res_scale; if (screen.scr_fov.value <= 90.0) r_fov_greater_than_90 = false; else r_fov_greater_than_90 = true; draw.D_ViewChanged(); }
/* ============== R_DrawRect8 ============== */ static void R_DrawRect8(vid.vrect_t prect, int rowbytes, int psrc, int transparent) { byte t; int i, j, srcdelta, destdelta; int pdest; pdest = (int)(/*vid.buffer + */(prect.y * screen.vid.rowbytes) + prect.x); srcdelta = rowbytes - prect.width; destdelta = (int)(screen.vid.rowbytes - prect.width); if (transparent != 0) { for (i=0 ; i<prect.height ; i++) { for (j=0 ; j<prect.width ; j++) { t = r_rectdesc.ptexbytes[psrc]; if (t != TRANSPARENT_COLOR) { screen.vid.buffer[pdest] = t; } psrc++; pdest++; } psrc += srcdelta; pdest += destdelta; } } else { for (i=0 ; i<prect.height ; i++) { Buffer.BlockCopy(r_rectdesc.ptexbytes, psrc, screen.vid.buffer, pdest, prect.width); psrc += rowbytes; pdest += (int)screen.vid.rowbytes; } } }