573 lines · 11.7 KB · C
RawDownload
#include "quakedef.h" static float scr_conlines; // lines of console to displaystatic float oldfov;static cvar_t scr_conspeed = {"scr_conspeed", "900", true};static cvar_t scr_centertime = {"scr_centertime", "2"};static cvar_t scr_showram = {"showram", "1"};static cvar_t scr_showturtle = {"showturtle", "0"};static cvar_t scr_showpause = {"showpause", "1"};static cvar_t scr_printspeed = {"scr_printspeed", "8"};static cvar_t scr_showfps = {"showfps", "0", true};static cvar_t v_maxfps = {"v_maxfps", "0", true}; cvar_t scr_viewsize = {"viewsize", "100", true};cvar_t scr_fov = {"fov", "90", true}; // 10 - 170 static bool scr_initialized; // ready to drawstatic qpic_t *scr_net, *scr_turtle;static int clearconsole;static bool scr_drawloading;static double scr_disabled_time;static u64int scr_framecount;double scr_frametime, scr_oldtime; int scr_fullupdate;int clearnotify;viddef_t vid; // global video statevrect_t scr_vrect;bool scr_disabled_for_loading;float scr_con_current; float scr_centertime_off;static char scr_centerstring[1024];static float scr_centertime_start; // for slow victory printingstatic int scr_center_lines;static int scr_erase_lines;static int scr_erase_center;static const char *scr_notifystring; /* * Called for important messages that should stay in the center of the screen * for a few moments */voidSCR_CenterPrint(const char *str){	strncpy(scr_centerstring, str, sizeof(scr_centerstring) - 1);	scr_centertime_off = scr_centertime.value;	scr_centertime_start = cl.time; 	// count the number of lines for centering	scr_center_lines = 1;	while(*str) {		if(*str == '\n')			scr_center_lines++;		str++;	}} static voidSCR_EraseCenterString(void){	int y; 	if(scr_erase_center++ > vid.numpages) {		scr_erase_lines = 0;		return;	} 	if(scr_center_lines <= 4)		y = vid.height * 0.35;	else		y = 48; 	Draw_TileClear(0, y, vid.width, 8 * scr_erase_lines);} static voidSCR_DrawCenterString(void){	const char *start;	int l, j, x, y, remaining; 	// the finale prints the characters one at a time	if(cl.intermission)		remaining = scr_printspeed.value * (cl.time - scr_centertime_start);	else		remaining = Q_MAXINT; 	scr_erase_center = 0;	start = scr_centerstring; 	if(scr_center_lines <= 4)		y = vid.height * 0.35;	else		y = 48; 	do {		// scan the width of the line		for(l = 0; l < 40; l++) {			if(start[l] == '\n' || !start[l])				break;		}		x = (vid.width - l * 8) / 2;		for(j = 0; j < l; j++, x += 8) {			Draw_Character(x, y, start[j]);			if(!remaining--)				return;		} 		y += 8; 		while(*start && *start != '\n')			start++; 		if(!*start)			break;		start++; // skip the \n	} while(1);} static voidSCR_CheckDrawCenterString(void){	if(scr_center_lines > scr_erase_lines)		scr_erase_lines = scr_center_lines; 	scr_centertime_off -= scr_frametime; 	if(scr_centertime_off <= 0 && !cl.intermission)		return;	if(key_dest != key_game)		return; 	SCR_DrawCenterString();} static floatCalcFov(float fov, float a, float b){	float v; 	fov = clamp(fov, 1, 179);	v = a / tanf(fov / 360 * M_PI); 	return atanf(b / v) * 360.0 / M_PI;} /* Must be called whenever vid changes */static voidSCR_CalcRefdef(void){	vrect_t vrect;	float size; 	scr_fullupdate = 0; // force a background redraw	vid.recalc_refdef = false; 	// bound viewsize	if(scr_viewsize.value < 100)		setcvar("viewsize", "100");	else if(scr_viewsize.value > 120)		setcvar("viewsize", "120"); 	// bound field of view	if(scr_fov.value < 10)		setcvar("fov", "10");	else if(scr_fov.value > 170)		setcvar("fov", "170"); 	scr_vrect = r_refdef.vrect; 	// intermission is always full screen	size = cl.intermission ? 120 : scr_viewsize.value; 	if(size >= 120)		sb_lines = 0; // no status bar at all	else if(size >= 110)		sb_lines = 24; // no inventory	else		sb_lines = 24 + 16 + 8; 	// adapt 4:3 fov to current aspect (taken from yquake2)	r_refdef.fov_x = atanf(						 tanf(scr_fov.value / 360.0 * M_PI) *						 ((float)r_refdef.vrect.width / (float)r_refdef.vrect.height * 0.75)					 ) /					 M_PI * 360.0;	r_refdef.fov_y = CalcFov(r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); 	// these calculations mirror those in R_Init() for r_refdef, but take no	// account of water warping	vrect.x = 0;	vrect.y = 0;	vrect.width = vid.width;	vrect.height = vid.height; 	// guard against going from one mode to another that's less than half the	// vertical resolution	if(scr_con_current > vid.height)		scr_con_current = vid.height; 	// notify the refresh of the change	R_ViewChanged(&vrect, vid.aspect);} static voidSCR_SizeUp_f(cmd_t *c){	USED(c);	setcvarv("viewsize", scr_viewsize.value + 10);	vid.recalc_refdef = true;} static voidSCR_SizeDown_f(cmd_t *c){	USED(c);	setcvarv("viewsize", scr_viewsize.value - 10);	vid.recalc_refdef = true;} voidSCR_Init(void){	Cvar_RegisterVariable(&scr_fov);	Cvar_RegisterVariable(&scr_viewsize);	Cvar_RegisterVariable(&scr_conspeed);	Cvar_RegisterVariable(&scr_showram);	Cvar_RegisterVariable(&scr_showturtle);	Cvar_RegisterVariable(&scr_showpause);	Cvar_RegisterVariable(&scr_centertime);	Cvar_RegisterVariable(&scr_printspeed);	Cvar_RegisterVariable(&scr_showfps);	Cvar_RegisterVariable(&v_maxfps);	Cmd_AddCommand("sizeup", SCR_SizeUp_f);	Cmd_AddCommand("sizedown", SCR_SizeDown_f); 	scr_net = Draw_PicFromWad("net");	scr_turtle = Draw_PicFromWad("turtle"); 	scr_initialized = true;} static voidSCR_DrawTurtle(void){	static int count; 	if(!scr_showturtle.value)		return; 	if(scr_frametime < 0.1) {		count = 0;		return;	} 	count++;	if(count < 3)		return; 	Draw_Pic(scr_vrect.x, scr_vrect.y, scr_turtle);} static voidSCR_DrawFPS(void){	static u64int lastframetime;	static int lastcnt, fps;	u64int t;	int n;	char s[16]; 	if(!scr_showfps.value)		return;	t = nanosec();	if((t - lastframetime) >= 1000000000ULL) {		fps = scr_framecount - lastcnt;		lastcnt = scr_framecount;		lastframetime = t;	}	n = snprint(s, sizeof(s), "%d", fps);	Draw_String(vid.width - n * 8, 0, s);} static voidSCR_DrawNet(void){	if(realtime - cl.last_received_message < 0.3)		return;	if(cls.demoplayback)		return; 	Draw_Pic(scr_vrect.x + 64, scr_vrect.y, scr_net);} static voidSCR_DrawPause(void){	qpic_t *pic; 	if(!scr_showpause.value) // turn off for screenshots		return; 	if(!cl.paused)		return; 	pic = Draw_CachePic("gfx/pause.lmp");	Draw_Pic((vid.width - pic->width) / 2, (vid.height - 48 - pic->height) / 2, pic);} static voidSCR_DrawLoading(void){	qpic_t *pic; 	if(!scr_drawloading)		return; 	pic = Draw_CachePic("gfx/loading.lmp");	Draw_Pic((vid.width - pic->width) / 2, (vid.height - 48 - pic->height) / 2, pic);} static voidSCR_SetUpToDrawConsole(void){	float dt; 	Con_CheckResize(); 	if(scr_drawloading)		return; // never a console with loading plaque 	// decide on the height of the console	con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; 	if(con_forcedup) {		scr_conlines = vid.height; // full screen		scr_con_current = scr_conlines;	} else if(key_dest == key_console)		scr_conlines = vid.height / 2; // half screen	else		scr_conlines = 0; // none visible 	dt = scr_conspeed.value * scr_frametime * vid.height / MINHEIGHT;	if(scr_conlines < scr_con_current) {		scr_con_current -= dt;		if(scr_conlines > scr_con_current)			scr_con_current = scr_conlines;	} else if(scr_conlines > scr_con_current) {		scr_con_current += dt;		if(scr_conlines < scr_con_current)			scr_con_current = scr_conlines;	} 	if(clearconsole++ < vid.numpages)		Draw_TileClear(0, (int)scr_con_current, vid.width, vid.height - (int)scr_con_current);	else if(clearnotify++ < vid.numpages)		Draw_TileClear(0, 0, vid.width, con_notifylines);	else		con_notifylines = 0;} static voidSCR_DrawConsole(void){	if(scr_con_current)		Con_DrawConsole(scr_con_current, true);	else if(key_dest == key_game || key_dest == key_message)		Con_DrawNotify(); // only draw notify in game	clearconsole = 0;} voidSCR_BeginLoadingPlaque(void){	stopallsfx(nil); 	if(cls.state != ca_connected)		return;	if(cls.signon != SIGNONS)		return; 	// redraw with no console and the loading plaque	Con_ClearNotify();	scr_centertime_off = 0;	scr_con_current = 0; 	scr_drawloading = true;	scr_fullupdate = 0;	SCR_UpdateScreen(false);	scr_drawloading = false; 	scr_disabled_for_loading = true;	scr_disabled_time = realtime;	scr_fullupdate = 0;} voidSCR_EndLoadingPlaque(void){	scr_disabled_for_loading = false;	scr_fullupdate = 0;	Con_ClearNotify();} static voidSCR_DrawNotifyString(void){	const char *start;	int l, j, x, y; 	start = scr_notifystring; 	y = vid.height * 0.35; 	do {		// scan the width of the line		for(l = 0; l < 40; l++) {			if(start[l] == '\n' || !start[l])				break;		}		x = (vid.width - l * 8) / 2;		for(j = 0; j < l; j++, x += 8)			Draw_Character(x, y, start[j]); 		y += 8; 		while(*start && *start != '\n')			start++; 		if(!*start)			break;		start++; // skip the \n	} while(1);} /* * Displays a text string in the center of the screen and waits for a Y or N keypress. */boolSCR_ModalMessage(const char *text){	if(cls.state == ca_dedicated)		return true; 	scr_notifystring = text; 	// draw a fresh screen	scr_fullupdate = 0;	SCR_UpdateScreen(true);	do {		key_count = -1; // wait for a key down and up		Sys_SendKeyEvents();	} while(key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE); 	scr_fullupdate = 0;	SCR_UpdateScreen(false); 	return key_lastpress == 'y';} /* Brings the console down and fades the palettes back to normal */voidSCR_BringDownConsole(void){	int i; 	scr_centertime_off = 0; 	for(i = 0; i < 20 && scr_conlines != scr_con_current; i++)		SCR_UpdateScreen(false); 	cl.cshifts[0].percent = 0; // no area contents palette on next frame} static boolboundfps(void){	static double oldtime;	double time, fpsmax = v_maxfps.value;	if(fpsmax < 1 || fpsmax > 999)		return false;	time = dtime();	if(time - oldtime < 1.0 / fpsmax)		return true;	oldtime = time;	return false;} /* * This is called every frame, and can also be called explicitly to flush * text to the screen. */voidSCR_UpdateScreen(bool drawdialog){	double t; 	if(scr_disabled_for_loading) {

Lines 1–500 of 573.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t