Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 1 | /* |
2 | Copyright (C) 1996-1997 Id Software, Inc. |
||
3 | |||
4 | This program is free software; you can redistribute it and/or |
||
5 | modify it under the terms of the GNU General Public License |
||
6 | as published by the Free Software Foundation; either version 2 |
||
7 | of the License, or (at your option) any later version. |
||
8 | |||
9 | This program is distributed in the hope that it will be useful, |
||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
12 | |||
13 | See the GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program; if not, write to the Free Software |
||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||
18 | |||
19 | */ |
||
20 | // screen.c -- master for refresh, status bar, console, chat, notify, etc |
||
21 | |||
22 | #include "quakedef.h" |
||
23 | #include "r_local.h" |
||
24 | |||
25 | // only the refresh window will be updated unless these variables are flagged |
||
26 | int scr_copytop; |
||
27 | int scr_copyeverything; |
||
28 | |||
29 | float scr_con_current; |
||
30 | float scr_conlines; // lines of console to display |
||
31 | |||
32 | float oldscreensize, oldfov; |
||
33 | cvar_t scr_viewsize = {"viewsize","100", true}; |
||
34 | cvar_t scr_fov = {"fov","90"}; // 10 - 170 |
||
35 | cvar_t scr_conspeed = {"scr_conspeed","300"}; |
||
36 | cvar_t scr_centertime = {"scr_centertime","2"}; |
||
37 | cvar_t scr_showram = {"showram","1"}; |
||
38 | cvar_t scr_showturtle = {"showturtle","0"}; |
||
39 | cvar_t scr_showpause = {"showpause","1"}; |
||
40 | cvar_t scr_printspeed = {"scr_printspeed","8"}; |
||
41 | |||
42 | qboolean scr_initialized; // ready to draw |
||
43 | |||
44 | qpic_t *scr_ram; |
||
45 | qpic_t *scr_net; |
||
46 | qpic_t *scr_turtle; |
||
47 | |||
48 | int scr_fullupdate; |
||
49 | |||
50 | int clearconsole; |
||
51 | int clearnotify; |
||
52 | |||
53 | viddef_t vid; // global video state |
||
54 | |||
55 | vrect_t *pconupdate; |
||
56 | vrect_t scr_vrect; |
||
57 | |||
58 | qboolean scr_disabled_for_loading; |
||
59 | qboolean scr_drawloading; |
||
60 | float scr_disabled_time; |
||
61 | qboolean scr_skipupdate; |
||
62 | |||
63 | qboolean block_drawing; |
||
64 | |||
65 | void SCR_ScreenShot_f (void); |
||
66 | |||
67 | /* |
||
68 | =============================================================================== |
||
69 | |||
70 | CENTER PRINTING |
||
71 | |||
72 | =============================================================================== |
||
73 | */ |
||
74 | |||
75 | char scr_centerstring[1024]; |
||
76 | float scr_centertime_start; // for slow victory printing |
||
77 | float scr_centertime_off; |
||
78 | int scr_center_lines; |
||
79 | int scr_erase_lines; |
||
80 | int scr_erase_center; |
||
81 | |||
82 | /* |
||
83 | ============== |
||
84 | SCR_CenterPrint |
||
85 | |||
86 | Called for important messages that should stay in the center of the screen |
||
87 | for a few moments |
||
88 | ============== |
||
89 | */ |
||
90 | void SCR_CenterPrint (char *str) |
||
91 | { |
||
92 | strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); |
||
93 | scr_centertime_off = scr_centertime.value; |
||
94 | scr_centertime_start = cl.time; |
||
95 | |||
96 | // count the number of lines for centering |
||
97 | scr_center_lines = 1; |
||
98 | while (*str) |
||
99 | { |
||
100 | if (*str == '\n') |
||
101 | scr_center_lines++; |
||
102 | str++; |
||
103 | } |
||
104 | } |
||
105 | |||
106 | void SCR_EraseCenterString (void) |
||
107 | { |
||
108 | int y; |
||
109 | |||
110 | if (scr_erase_center++ > vid.numpages) |
||
111 | { |
||
112 | scr_erase_lines = 0; |
||
113 | return; |
||
114 | } |
||
115 | |||
116 | if (scr_center_lines <= 4) |
||
117 | y = vid.height*0.35; |
||
118 | else |
||
119 | y = 48; |
||
120 | |||
121 | scr_copytop = 1; |
||
122 | Draw_TileClear (0, y,vid.width, 8*scr_erase_lines); |
||
123 | } |
||
124 | |||
125 | void SCR_DrawCenterString (void) |
||
126 | { |
||
127 | char *start; |
||
128 | int l; |
||
129 | int j; |
||
130 | int x, y; |
||
131 | int remaining; |
||
132 | |||
133 | // the finale prints the characters one at a time |
||
134 | if (cl.intermission) |
||
135 | remaining = scr_printspeed.value * (cl.time - scr_centertime_start); |
||
136 | else |
||
137 | remaining = 9999; |
||
138 | |||
139 | scr_erase_center = 0; |
||
140 | start = scr_centerstring; |
||
141 | |||
142 | if (scr_center_lines <= 4) |
||
143 | y = vid.height*0.35; |
||
144 | else |
||
145 | y = 48; |
||
146 | |||
147 | do |
||
148 | { |
||
149 | // scan the width of the line |
||
150 | for (l=0 ; l<40 ; l++) |
||
151 | if (start[l] == '\n' || !start[l]) |
||
152 | break; |
||
153 | x = (vid.width - l*8)/2; |
||
154 | for (j=0 ; j |
||
155 | { |
||
156 | Draw_Character (x, y, start[j]); |
||
157 | if (!remaining--) |
||
158 | return; |
||
159 | } |
||
160 | |||
161 | y += 8; |
||
162 | |||
163 | while (*start && *start != '\n') |
||
164 | start++; |
||
165 | |||
166 | if (!*start) |
||
167 | break; |
||
168 | start++; // skip the \n |
||
169 | } while (1); |
||
170 | } |
||
171 | |||
172 | void SCR_CheckDrawCenterString (void) |
||
173 | { |
||
174 | scr_copytop = 1; |
||
175 | if (scr_center_lines > scr_erase_lines) |
||
176 | scr_erase_lines = scr_center_lines; |
||
177 | |||
178 | scr_centertime_off -= host_frametime; |
||
179 | |||
180 | if (scr_centertime_off <= 0 && !cl.intermission) |
||
181 | return; |
||
182 | if (key_dest != key_game) |
||
183 | return; |
||
184 | |||
185 | SCR_DrawCenterString (); |
||
186 | } |
||
187 | |||
188 | //============================================================================= |
||
189 | |||
190 | /* |
||
191 | ==================== |
||
192 | CalcFov |
||
193 | ==================== |
||
194 | */ |
||
195 | float CalcFov (float fov_x, float width, float height) |
||
196 | { |
||
197 | float a; |
||
198 | float x; |
||
199 | |||
200 | if (fov_x < 1 || fov_x > 179) |
||
201 | Sys_Error ("Bad fov: %f", fov_x); |
||
202 | |||
203 | x = width/tan(fov_x/360*M_PI); |
||
204 | |||
205 | a = atan (height/x); |
||
206 | |||
207 | a = a*360/M_PI; |
||
208 | |||
209 | return a; |
||
210 | } |
||
211 | |||
212 | /* |
||
213 | ================= |
||
214 | SCR_CalcRefdef |
||
215 | |||
216 | Must be called whenever vid changes |
||
217 | Internal use only |
||
218 | ================= |
||
219 | */ |
||
220 | static void SCR_CalcRefdef (void) |
||
221 | { |
||
222 | vrect_t vrect; |
||
223 | float size; |
||
224 | |||
225 | scr_fullupdate = 0; // force a background redraw |
||
226 | vid.recalc_refdef = 0; |
||
227 | |||
228 | // force the status bar to redraw |
||
229 | Sbar_Changed (); |
||
230 | |||
231 | //======================================== |
||
232 | |||
233 | // bound viewsize |
||
234 | if (scr_viewsize.value < 30) |
||
235 | Cvar_Set ("viewsize","30"); |
||
236 | if (scr_viewsize.value > 120) |
||
237 | Cvar_Set ("viewsize","120"); |
||
238 | |||
239 | // bound field of view |
||
240 | if (scr_fov.value < 10) |
||
241 | Cvar_Set ("fov","10"); |
||
242 | if (scr_fov.value > 170) |
||
243 | Cvar_Set ("fov","170"); |
||
244 | |||
245 | r_refdef.fov_x = scr_fov.value; |
||
246 | r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); |
||
247 | |||
248 | // intermission is always full screen |
||
249 | if (cl.intermission) |
||
250 | size = 120; |
||
251 | else |
||
252 | size = scr_viewsize.value; |
||
253 | |||
254 | if (size >= 120) |
||
255 | sb_lines = 0; // no status bar at all |
||
256 | else if (size >= 110) |
||
257 | sb_lines = 24; // no inventory |
||
258 | else |
||
259 | sb_lines = 24+16+8; |
||
260 | |||
261 | // these calculations mirror those in R_Init() for r_refdef, but take no |
||
262 | // account of water warping |
||
263 | vrect.x = 0; |
||
264 | vrect.y = 0; |
||
265 | vrect.width = vid.width; |
||
266 | vrect.height = vid.height; |
||
267 | |||
268 | R_SetVrect (&vrect, &scr_vrect, sb_lines); |
||
269 | |||
270 | // guard against going from one mode to another that's less than half the |
||
271 | // vertical resolution |
||
272 | if (scr_con_current > vid.height) |
||
273 | scr_con_current = vid.height; |
||
274 | |||
275 | // notify the refresh of the change |
||
276 | R_ViewChanged (&vrect, sb_lines, vid.aspect); |
||
277 | } |
||
278 | |||
279 | |||
280 | /* |
||
281 | ================= |
||
282 | SCR_SizeUp_f |
||
283 | |||
284 | Keybinding command |
||
285 | ================= |
||
286 | */ |
||
287 | void SCR_SizeUp_f (void) |
||
288 | { |
||
289 | Cvar_SetValue ("viewsize",scr_viewsize.value+10); |
||
290 | vid.recalc_refdef = 1; |
||
291 | } |
||
292 | |||
293 | |||
294 | /* |
||
295 | ================= |
||
296 | SCR_SizeDown_f |
||
297 | |||
298 | Keybinding command |
||
299 | ================= |
||
300 | */ |
||
301 | void SCR_SizeDown_f (void) |
||
302 | { |
||
303 | Cvar_SetValue ("viewsize",scr_viewsize.value-10); |
||
304 | vid.recalc_refdef = 1; |
||
305 | } |
||
306 | |||
307 | //============================================================================ |
||
308 | |||
309 | /* |
||
310 | ================== |
||
311 | SCR_Init |
||
312 | ================== |
||
313 | */ |
||
314 | void SCR_Init (void) |
||
315 | { |
||
316 | Cvar_RegisterVariable (&scr_fov); |
||
317 | Cvar_RegisterVariable (&scr_viewsize); |
||
318 | Cvar_RegisterVariable (&scr_conspeed); |
||
319 | Cvar_RegisterVariable (&scr_showram); |
||
320 | Cvar_RegisterVariable (&scr_showturtle); |
||
321 | Cvar_RegisterVariable (&scr_showpause); |
||
322 | Cvar_RegisterVariable (&scr_centertime); |
||
323 | Cvar_RegisterVariable (&scr_printspeed); |
||
324 | |||
325 | // |
||
326 | // register our commands |
||
327 | // |
||
328 | Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); |
||
329 | Cmd_AddCommand ("sizeup",SCR_SizeUp_f); |
||
330 | Cmd_AddCommand ("sizedown",SCR_SizeDown_f); |
||
331 | |||
332 | scr_ram = Draw_PicFromWad ("ram"); |
||
333 | scr_net = Draw_PicFromWad ("net"); |
||
334 | scr_turtle = Draw_PicFromWad ("turtle"); |
||
335 | |||
336 | scr_initialized = true; |
||
337 | } |
||
338 | |||
339 | |||
340 | |||
341 | /* |
||
342 | ============== |
||
343 | SCR_DrawRam |
||
344 | ============== |
||
345 | */ |
||
346 | void SCR_DrawRam (void) |
||
347 | { |
||
348 | if (!scr_showram.value) |
||
349 | return; |
||
350 | |||
351 | if (!r_cache_thrash) |
||
352 | return; |
||
353 | |||
354 | Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); |
||
355 | } |
||
356 | |||
357 | /* |
||
358 | ============== |
||
359 | SCR_DrawTurtle |
||
360 | ============== |
||
361 | */ |
||
362 | void SCR_DrawTurtle (void) |
||
363 | { |
||
364 | static int count; |
||
365 | |||
366 | if (!scr_showturtle.value) |
||
367 | return; |
||
368 | |||
369 | if (host_frametime < 0.1) |
||
370 | { |
||
371 | count = 0; |
||
372 | return; |
||
373 | } |
||
374 | |||
375 | count++; |
||
376 | if (count < 3) |
||
377 | return; |
||
378 | |||
379 | Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); |
||
380 | } |
||
381 | |||
382 | /* |
||
383 | ============== |
||
384 | SCR_DrawNet |
||
385 | ============== |
||
386 | */ |
||
387 | void SCR_DrawNet (void) |
||
388 | { |
||
389 | if (realtime - cl.last_received_message < 0.3) |
||
390 | return; |
||
391 | if (cls.demoplayback) |
||
392 | return; |
||
393 | |||
394 | Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); |
||
395 | } |
||
396 | |||
397 | /* |
||
398 | ============== |
||
399 | DrawPause |
||
400 | ============== |
||
401 | */ |
||
402 | void SCR_DrawPause (void) |
||
403 | { |
||
404 | qpic_t *pic; |
||
405 | |||
406 | if (!scr_showpause.value) // turn off for screenshots |
||
407 | return; |
||
408 | |||
409 | if (!cl.paused) |
||
410 | return; |
||
411 | |||
412 | pic = Draw_CachePic ("gfx/pause.lmp"); |
||
413 | Draw_Pic ( (vid.width - pic->width)/2, |
||
414 | (vid.height - 48 - pic->height)/2, pic); |
||
415 | } |
||
416 | |||
417 | |||
418 | |||
419 | /* |
||
420 | ============== |
||
421 | SCR_DrawLoading |
||
422 | ============== |
||
423 | */ |
||
424 | void SCR_DrawLoading (void) |
||
425 | { |
||
426 | qpic_t *pic; |
||
427 | |||
428 | if (!scr_drawloading) |
||
429 | return; |
||
430 | |||
431 | pic = Draw_CachePic ("gfx/loading.lmp"); |
||
432 | Draw_Pic ( (vid.width - pic->width)/2, |
||
433 | (vid.height - 48 - pic->height)/2, pic); |
||
434 | } |
||
435 | |||
436 | |||
437 | |||
438 | //============================================================================= |
||
439 | |||
440 | |||
441 | /* |
||
442 | ================== |
||
443 | SCR_SetUpToDrawConsole |
||
444 | ================== |
||
445 | */ |
||
446 | void SCR_SetUpToDrawConsole (void) |
||
447 | { |
||
448 | Con_CheckResize (); |
||
449 | |||
450 | if (scr_drawloading) |
||
451 | return; // never a console with loading plaque |
||
452 | |||
453 | // decide on the height of the console |
||
454 | con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; |
||
455 | |||
456 | if (con_forcedup) |
||
457 | { |
||
458 | scr_conlines = vid.height; // full screen |
||
459 | scr_con_current = scr_conlines; |
||
460 | } |
||
461 | else if (key_dest == key_console) |
||
462 | scr_conlines = vid.height/2; // half screen |
||
463 | else |
||
464 | scr_conlines = 0; // none visible |
||
465 | |||
466 | if (scr_conlines < scr_con_current) |
||
467 | { |
||
468 | scr_con_current -= scr_conspeed.value*host_frametime; |
||
469 | if (scr_conlines > scr_con_current) |
||
470 | scr_con_current = scr_conlines; |
||
471 | |||
472 | } |
||
473 | else if (scr_conlines > scr_con_current) |
||
474 | { |
||
475 | scr_con_current += scr_conspeed.value*host_frametime; |
||
476 | if (scr_conlines < scr_con_current) |
||
477 | scr_con_current = scr_conlines; |
||
478 | } |
||
479 | |||
480 | if (clearconsole++ < vid.numpages) |
||
481 | { |
||
482 | scr_copytop = 1; |
||
483 | Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current); |
||
484 | Sbar_Changed (); |
||
485 | } |
||
486 | else if (clearnotify++ < vid.numpages) |
||
487 | { |
||
488 | scr_copytop = 1; |
||
489 | Draw_TileClear (0,0,vid.width, con_notifylines); |
||
490 | } |
||
491 | else |
||
492 | con_notifylines = 0; |
||
493 | } |
||
494 | |||
495 | /* |
||
496 | ================== |
||
497 | SCR_DrawConsole |
||
498 | ================== |
||
499 | */ |
||
500 | void SCR_DrawConsole (void) |
||
501 | { |
||
502 | if (scr_con_current) |
||
503 | { |
||
504 | scr_copyeverything = 1; |
||
505 | Con_DrawConsole (scr_con_current, true); |
||
506 | clearconsole = 0; |
||
507 | } |
||
508 | else |
||
509 | { |
||
510 | if (key_dest == key_game || key_dest == key_message) |
||
511 | Con_DrawNotify (); // only draw notify in game |
||
512 | } |
||
513 | } |
||
514 | |||
515 | |||
516 | /* |
||
517 | ============================================================================== |
||
518 | |||
519 | SCREEN SHOTS |
||
520 | |||
521 | ============================================================================== |
||
522 | */ |
||
523 | |||
524 | |||
525 | typedef struct |
||
526 | { |
||
527 | char manufacturer; |
||
528 | char version; |
||
529 | char encoding; |
||
530 | char bits_per_pixel; |
||
531 | unsigned short xmin,ymin,xmax,ymax; |
||
532 | unsigned short hres,vres; |
||
533 | unsigned char palette[48]; |
||
534 | char reserved; |
||
535 | char color_planes; |
||
536 | unsigned short bytes_per_line; |
||
537 | unsigned short palette_type; |
||
538 | char filler[58]; |
||
539 | unsigned char data; // unbounded |
||
540 | } pcx_t; |
||
541 | |||
542 | /* |
||
543 | ============== |
||
544 | WritePCXfile |
||
545 | ============== |
||
546 | */ |
||
547 | void WritePCXfile (char *filename, byte *data, int width, int height, |
||
548 | int rowbytes, byte *palette) |
||
549 | { |
||
550 | int i, j, length; |
||
551 | pcx_t *pcx; |
||
552 | byte *pack; |
||
553 | |||
554 | pcx = Hunk_TempAlloc (width*height*2+1000); |
||
555 | if (pcx == NULL) |
||
556 | { |
||
557 | Con_Printf("SCR_ScreenShot_f: not enough memory\n"); |
||
558 | return; |
||
559 | } |
||
560 | |||
561 | pcx->manufacturer = 0x0a; // PCX id |
||
562 | pcx->version = 5; // 256 color |
||
563 | pcx->encoding = 1; // uncompressed |
||
564 | pcx->bits_per_pixel = 8; // 256 color |
||
565 | pcx->xmin = 0; |
||
566 | pcx->ymin = 0; |
||
567 | pcx->xmax = LittleShort((short)(width-1)); |
||
568 | pcx->ymax = LittleShort((short)(height-1)); |
||
569 | pcx->hres = LittleShort((short)width); |
||
570 | pcx->vres = LittleShort((short)height); |
||
571 | Q_memset (pcx->palette,0,sizeof(pcx->palette)); |
||
572 | pcx->color_planes = 1; // chunky image |
||
573 | pcx->bytes_per_line = LittleShort((short)width); |
||
574 | pcx->palette_type = LittleShort(2); // not a grey scale |
||
575 | Q_memset (pcx->filler,0,sizeof(pcx->filler)); |
||
576 | |||
577 | // pack the image |
||
578 | pack = &pcx->data; |
||
579 | |||
580 | for (i=0 ; i |
||
581 | { |
||
582 | for (j=0 ; j |
||
583 | { |
||
584 | if ( (*data & 0xc0) != 0xc0) |
||
585 | *pack++ = *data++; |
||
586 | else |
||
587 | { |
||
588 | *pack++ = 0xc1; |
||
589 | *pack++ = *data++; |
||
590 | } |
||
591 | } |
||
592 | |||
593 | data += rowbytes - width; |
||
594 | } |
||
595 | |||
596 | // write the palette |
||
597 | *pack++ = 0x0c; // palette ID byte |
||
598 | for (i=0 ; i<768 ; i++) |
||
599 | *pack++ = *palette++; |
||
600 | |||
601 | // write output file |
||
602 | length = pack - (byte *)pcx; |
||
603 | COM_WriteFile (filename, pcx, length); |
||
604 | } |
||
605 | |||
606 | |||
607 | |||
608 | /* |
||
609 | ================== |
||
610 | SCR_ScreenShot_f |
||
611 | ================== |
||
612 | */ |
||
613 | void SCR_ScreenShot_f (void) |
||
614 | { |
||
615 | int i; |
||
616 | char pcxname[80]; |
||
617 | char checkname[MAX_OSPATH]; |
||
618 | |||
619 | // |
||
620 | // find a file name to save it to |
||
621 | // |
||
622 | strcpy(pcxname,"quake00.pcx"); |
||
623 | |||
624 | for (i=0 ; i<=99 ; i++) |
||
625 | { |
||
626 | pcxname[5] = i/10 + '0'; |
||
627 | pcxname[6] = i%10 + '0'; |
||
628 | sprintf (checkname, "%s/%s", com_gamedir, pcxname); |
||
629 | if (Sys_FileTime(checkname) == -1) |
||
630 | break; // file doesn't exist |
||
631 | } |
||
632 | if (i==100) |
||
633 | { |
||
634 | Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); |
||
635 | return; |
||
636 | } |
||
637 | |||
638 | // |
||
639 | // save the pcx file |
||
640 | // |
||
641 | D_EnableBackBufferAccess (); // enable direct drawing of console to back |
||
642 | // buffer |
||
643 | |||
644 | WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes, |
||
645 | host_basepal); |
||
646 | |||
647 | D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
||
648 | // for linear writes all the time |
||
649 | |||
650 | Con_Printf ("Wrote %s\n", pcxname); |
||
651 | } |
||
652 | |||
653 | |||
654 | //============================================================================= |
||
655 | |||
656 | |||
657 | /* |
||
658 | =============== |
||
659 | SCR_BeginLoadingPlaque |
||
660 | |||
661 | ================ |
||
662 | */ |
||
663 | void SCR_BeginLoadingPlaque (void) |
||
664 | { |
||
665 | S_StopAllSounds (true); |
||
666 | |||
667 | if (cls.state != ca_connected) |
||
668 | return; |
||
669 | if (cls.signon != SIGNONS) |
||
670 | return; |
||
671 | |||
672 | // redraw with no console and the loading plaque |
||
673 | Con_ClearNotify (); |
||
674 | scr_centertime_off = 0; |
||
675 | scr_con_current = 0; |
||
676 | |||
677 | scr_drawloading = true; |
||
678 | scr_fullupdate = 0; |
||
679 | Sbar_Changed (); |
||
680 | SCR_UpdateScreen (); |
||
681 | scr_drawloading = false; |
||
682 | |||
683 | scr_disabled_for_loading = true; |
||
684 | scr_disabled_time = realtime; |
||
685 | scr_fullupdate = 0; |
||
686 | } |
||
687 | |||
688 | /* |
||
689 | =============== |
||
690 | SCR_EndLoadingPlaque |
||
691 | |||
692 | ================ |
||
693 | */ |
||
694 | void SCR_EndLoadingPlaque (void) |
||
695 | { |
||
696 | scr_disabled_for_loading = false; |
||
697 | scr_fullupdate = 0; |
||
698 | Con_ClearNotify (); |
||
699 | } |
||
700 | |||
701 | //============================================================================= |
||
702 | |||
703 | char *scr_notifystring; |
||
704 | qboolean scr_drawdialog; |
||
705 | |||
706 | void SCR_DrawNotifyString (void) |
||
707 | { |
||
708 | char *start; |
||
709 | int l; |
||
710 | int j; |
||
711 | int x, y; |
||
712 | |||
713 | start = scr_notifystring; |
||
714 | |||
715 | y = vid.height*0.35; |
||
716 | |||
717 | do |
||
718 | { |
||
719 | // scan the width of the line |
||
720 | for (l=0 ; l<40 ; l++) |
||
721 | if (start[l] == '\n' || !start[l]) |
||
722 | break; |
||
723 | x = (vid.width - l*8)/2; |
||
724 | for (j=0 ; j |
||
725 | Draw_Character (x, y, start[j]); |
||
726 | |||
727 | y += 8; |
||
728 | |||
729 | while (*start && *start != '\n') |
||
730 | start++; |
||
731 | |||
732 | if (!*start) |
||
733 | break; |
||
734 | start++; // skip the \n |
||
735 | } while (1); |
||
736 | } |
||
737 | |||
738 | /* |
||
739 | ================== |
||
740 | SCR_ModalMessage |
||
741 | |||
742 | Displays a text string in the center of the screen and waits for a Y or N |
||
743 | keypress. |
||
744 | ================== |
||
745 | */ |
||
746 | int SCR_ModalMessage (char *text) |
||
747 | { |
||
748 | if (cls.state == ca_dedicated) |
||
749 | return true; |
||
750 | |||
751 | scr_notifystring = text; |
||
752 | |||
753 | // draw a fresh screen |
||
754 | scr_fullupdate = 0; |
||
755 | scr_drawdialog = true; |
||
756 | SCR_UpdateScreen (); |
||
757 | scr_drawdialog = false; |
||
758 | |||
759 | S_ClearBuffer (); // so dma doesn't loop current sound |
||
760 | |||
761 | do |
||
762 | { |
||
763 | key_count = -1; // wait for a key down and up |
||
764 | Sys_SendKeyEvents (); |
||
765 | } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE); |
||
766 | |||
767 | scr_fullupdate = 0; |
||
768 | SCR_UpdateScreen (); |
||
769 | |||
770 | return key_lastpress == 'y'; |
||
771 | } |
||
772 | |||
773 | |||
774 | //============================================================================= |
||
775 | |||
776 | /* |
||
777 | =============== |
||
778 | SCR_BringDownConsole |
||
779 | |||
780 | Brings the console down and fades the palettes back to normal |
||
781 | ================ |
||
782 | */ |
||
783 | void SCR_BringDownConsole (void) |
||
784 | { |
||
785 | int i; |
||
786 | |||
787 | scr_centertime_off = 0; |
||
788 | |||
789 | for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++) |
||
790 | SCR_UpdateScreen (); |
||
791 | |||
792 | cl.cshifts[0].percent = 0; // no area contents palette on next frame |
||
793 | VID_SetPalette (host_basepal); |
||
794 | } |
||
795 | |||
796 | |||
797 | /* |
||
798 | ================== |
||
799 | SCR_UpdateScreen |
||
800 | |||
801 | This is called every frame, and can also be called explicitly to flush |
||
802 | text to the screen. |
||
803 | |||
804 | WARNING: be very careful calling this from elsewhere, because the refresh |
||
805 | needs almost the entire 256k of stack space! |
||
806 | ================== |
||
807 | */ |
||
808 | void SCR_UpdateScreen (void) |
||
809 | { |
||
810 | static float oldscr_viewsize; |
||
811 | static float oldlcd_x; |
||
812 | vrect_t vrect; |
||
813 | |||
814 | if (scr_skipupdate || block_drawing) |
||
815 | return; |
||
816 | |||
817 | scr_copytop = 0; |
||
818 | scr_copyeverything = 0; |
||
819 | |||
820 | if (scr_disabled_for_loading) |
||
821 | { |
||
822 | if (realtime - scr_disabled_time > 60) |
||
823 | { |
||
824 | scr_disabled_for_loading = false; |
||
825 | Con_Printf ("load failed.\n"); |
||
826 | } |
||
827 | else |
||
828 | return; |
||
829 | } |
||
830 | |||
831 | if (cls.state == ca_dedicated) |
||
832 | return; // stdout only |
||
833 | |||
834 | if (!scr_initialized || !con_initialized) |
||
835 | return; // not initialized yet |
||
836 | |||
837 | if (scr_viewsize.value != oldscr_viewsize) |
||
838 | { |
||
839 | oldscr_viewsize = scr_viewsize.value; |
||
840 | vid.recalc_refdef = 1; |
||
841 | } |
||
842 | |||
843 | // |
||
844 | // check for vid changes |
||
845 | // |
||
846 | if (oldfov != scr_fov.value) |
||
847 | { |
||
848 | oldfov = scr_fov.value; |
||
849 | vid.recalc_refdef = true; |
||
850 | } |
||
851 | |||
852 | if (oldlcd_x != lcd_x.value) |
||
853 | { |
||
854 | oldlcd_x = lcd_x.value; |
||
855 | vid.recalc_refdef = true; |
||
856 | } |
||
857 | |||
858 | if (oldscreensize != scr_viewsize.value) |
||
859 | { |
||
860 | oldscreensize = scr_viewsize.value; |
||
861 | vid.recalc_refdef = true; |
||
862 | } |
||
863 | |||
864 | if (vid.recalc_refdef) |
||
865 | { |
||
866 | // something changed, so reorder the screen |
||
867 | SCR_CalcRefdef (); |
||
868 | } |
||
869 | |||
870 | // |
||
871 | // do 3D refresh drawing, and then update the screen |
||
872 | // |
||
873 | D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly |
||
874 | |||
875 | if (scr_fullupdate++ < vid.numpages) |
||
876 | { // clear the entire screen |
||
877 | scr_copyeverything = 1; |
||
878 | Draw_TileClear (0,0,vid.width,vid.height); |
||
879 | Sbar_Changed (); |
||
880 | } |
||
881 | |||
882 | pconupdate = NULL; |
||
883 | |||
884 | |||
885 | SCR_SetUpToDrawConsole (); |
||
886 | SCR_EraseCenterString (); |
||
887 | |||
888 | D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
||
889 | // for linear writes all the time |
||
890 | |||
891 | VID_LockBuffer (); |
||
892 | |||
893 | V_RenderView (); |
||
894 | |||
895 | VID_UnlockBuffer (); |
||
896 | |||
897 | D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly |
||
898 | |||
899 | if (scr_drawdialog) |
||
900 | { |
||
901 | Sbar_Draw (); |
||
902 | Draw_FadeScreen (); |
||
903 | SCR_DrawNotifyString (); |
||
904 | scr_copyeverything = true; |
||
905 | } |
||
906 | else if (scr_drawloading) |
||
907 | { |
||
908 | SCR_DrawLoading (); |
||
909 | Sbar_Draw (); |
||
910 | } |
||
911 | else if (cl.intermission == 1 && key_dest == key_game) |
||
912 | { |
||
913 | Sbar_IntermissionOverlay (); |
||
914 | } |
||
915 | else if (cl.intermission == 2 && key_dest == key_game) |
||
916 | { |
||
917 | Sbar_FinaleOverlay (); |
||
918 | SCR_CheckDrawCenterString (); |
||
919 | } |
||
920 | else if (cl.intermission == 3 && key_dest == key_game) |
||
921 | { |
||
922 | SCR_CheckDrawCenterString (); |
||
923 | } |
||
924 | else |
||
925 | { |
||
926 | SCR_DrawRam (); |
||
927 | SCR_DrawNet (); |
||
928 | SCR_DrawTurtle (); |
||
929 | SCR_DrawPause (); |
||
930 | SCR_CheckDrawCenterString (); |
||
931 | Sbar_Draw (); |
||
932 | SCR_DrawConsole (); |
||
933 | M_Draw (); |
||
934 | } |
||
935 | |||
936 | D_DisableBackBufferAccess (); // for adapters that can't stay mapped in |
||
937 | // for linear writes all the time |
||
938 | if (pconupdate) |
||
939 | { |
||
940 | D_UpdateRects (pconupdate); |
||
941 | } |
||
942 | |||
943 | V_UpdatePalette (); |
||
944 | |||
945 | // |
||
946 | // update one of three areas |
||
947 | // |
||
948 | |||
949 | if (scr_copyeverything) |
||
950 | { |
||
951 | vrect.x = 0; |
||
952 | vrect.y = 0; |
||
953 | vrect.width = vid.width; |
||
954 | vrect.height = vid.height; |
||
955 | vrect.pnext = 0; |
||
956 | |||
957 | VID_Update (&vrect); |
||
958 | } |
||
959 | else if (scr_copytop) |
||
960 | { |
||
961 | vrect.x = 0; |
||
962 | vrect.y = 0; |
||
963 | vrect.width = vid.width; |
||
964 | vrect.height = vid.height - sb_lines; |
||
965 | vrect.pnext = 0; |
||
966 | |||
967 | VID_Update (&vrect); |
||
968 | } |
||
969 | else |
||
970 | { |
||
971 | vrect.x = scr_vrect.x; |
||
972 | vrect.y = scr_vrect.y; |
||
973 | vrect.width = scr_vrect.width; |
||
974 | vrect.height = scr_vrect.height; |
||
975 | vrect.pnext = 0; |
||
976 | |||
977 | VID_Update (&vrect); |
||
978 | } |
||
979 | } |
||
980 | |||
981 | |||
982 | /* |
||
983 | ================== |
||
984 | SCR_UpdateWholeScreen |
||
985 | ================== |
||
986 | */ |
||
987 | void SCR_UpdateWholeScreen (void) |
||
988 | { |
||
989 | scr_fullupdate = 0; |
||
990 | SCR_UpdateScreen (); |
||
991 | }>20>40>=99>768>>>>>>>>>>>=>40>=>=> |