CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

GSCREEN.CPP (29987B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header:   F:\projects\c&c\vcs\code\gscreen.cpv   2.17   16 Oct 1995 16:51:34   JOE_BOSTIC  $ */
     17 /***********************************************************************************************
     18  ***             C O N F I D E N T I A L  ---  W E S T W O O D   S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : GSCREEN.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 12/15/94                                                     *
     28  *                                                                                             *
     29  *                  Last Update : January 19, 1995 [JLB]                                       *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   GScreenClass::GScreenClass -- Default constructor for GScreenClass.                       *
     34  *   GScreenClass::One_Time -- Handles one time class setups.                                  *
     35  *   GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines.   *
     36  *   GScreenClass::Init_Clear -- Sets the map to a known state.                                *
     37  *   GScreenClass::Init_Theater -- Performs theater-specific initializations.                  *
     38  *   GScreenClass::Init_IO -- Initializes the Button list ('Buttons').                         *
     39  *   GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn.                          *
     40  *   GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage.        *
     41  *   GScreenClass::Render -- General drawing dispatcher an display update function.            *
     42  *   GScreenClass::Input -- Fetches input and processes gadgets.                               *
     43  *   GScreenClass::Add_A_Button -- Add a gadget to the game input system.                      *
     44  *   GScreenClass::Remove_A_Button -- Removes a gadget from the game input system.             *
     45  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     46 
     47 #include "function.h"
     48 
     49 #include <filepcx.h>
     50 
     51 GadgetClass * GScreenClass::Buttons = 0;
     52 
     53 GraphicBufferClass * GScreenClass::ShadowPage = 0;
     54 
     55 
     56 /***********************************************************************************************
     57  * GScreenClass::GScreenClass -- Default constructor for GScreenClass.                         *
     58  *                                                                                             *
     59  *    This constructor merely sets the display system, so that it will redraw the first time   *
     60  *    the render function is called.                                                           *
     61  *                                                                                             *
     62  * INPUT:   none                                                                               *
     63  *                                                                                             *
     64  * OUTPUT:  none                                                                               *
     65  *                                                                                             *
     66  * WARNINGS:   none                                                                            *
     67  *                                                                                             *
     68  * HISTORY:                                                                                    *
     69  *   12/15/1994 JLB : Created.                                                                 *
     70  *=============================================================================================*/
     71 GScreenClass::GScreenClass(void)
     72 {
     73 	IsToUpdate = true;
     74 	IsToRedraw = true;
     75 }
     76 
     77 
     78 /***********************************************************************************************
     79  * GScreenClass::One_Time -- Handles one time class setups.                                    *
     80  *                                                                                             *
     81  * This routine (and all those that overload it) must perform truly one-time initialization.   *
     82  * Such init's would normally be done in the constructor, but other aspects of the game may    *
     83  * not have been initialized at the time the constructors are called (such as the file system, *
     84  * the display, or other WWLIB subsystems), so many initializations should be deferred to the  *
     85  * One_Time init's.                                                                            *
     86  *                                                                                             *
     87  * Any variables set in this routine should be declared as static, so they won't be modified   *
     88  * by the load/save process.  Non-static variables will be over-written by a loaded game.      *
     89  *                                                                                             *
     90  * This function allocates the shadow buffer that is used for quick screen updates. If         *
     91  * there were any data files to load, they would be loaded at this time as well.               *
     92  *                                                                                             *
     93  * INPUT:   none                                                                               *
     94  *                                                                                             *
     95  * OUTPUT:  none                                                                               *
     96  *                                                                                             *
     97  * WARNINGS:   Call this routine only ONCE at the beginning of the game.                       *
     98  *                                                                                             *
     99  * HISTORY:                                                                                    *
    100  *   12/15/1994 JLB : Created.                                                                 *
    101  *=============================================================================================*/
    102 void GScreenClass::One_Time(void)
    103 {
    104 	/*
    105 	**	Allocate the screen shadow page. This page is used to reduce access to the
    106 	**	actual screen memory. It contains a duplicate of what the SEENPAGE is.
    107 	*/
    108 	Buttons = 0;
    109 	ShadowPage = new GraphicBufferClass(320,200);
    110 	if (ShadowPage) {
    111 		ShadowPage->Clear();
    112 		HiddenPage.Clear();
    113 	}
    114 }
    115 
    116 
    117 /***********************************************************************************************
    118  * GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines.     *
    119  *                                                                                             *
    120  * This routine shouldn't be overloaded.  It's the main map initialization routine, and will   *
    121  * perform a complete map initialization, from mixfiles to clearing the buffers.  Calling this *
    122  * routine results in calling every initialization routine in the entire map hierarchy.        *
    123  *                                                                                             *
    124  * INPUT:                                                                                      *
    125  *      theater      theater to initialize to                                                  *
    126  *                                                                                             *
    127  * OUTPUT:                                                                                     *
    128  *      none.                                                                                  *
    129  *                                                                                             *
    130  * WARNINGS:                                                                                   *
    131  *      none.                                                                                  *
    132  *                                                                                             *
    133  * HISTORY:                                                                                    *
    134  *   12/28/1994 BR : Created.                                                                  *
    135  *=============================================================================================*/
    136 void GScreenClass::Init(TheaterType theater)
    137 {
    138 	Init_Clear();
    139 	Init_IO();
    140 	Init_Theater(theater);
    141 }
    142 
    143 
    144 /***********************************************************************************************
    145  * GScreenClass::Init_Clear -- Sets the map to a known state.                                  *
    146  *                                                                                             *
    147  * This routine (and those that overload it) clears any buffers and variables to a known       *
    148  * state.  It assumes that all buffers are allocated & valid.  The map should be displayable   *
    149  * after calling this function, and should draw basically an empty display.                    *
    150  *                                                                                             *
    151  * INPUT:                                                                                      *
    152  *      none.                                                                                  *
    153  *                                                                                             *
    154  * OUTPUT:                                                                                     *
    155  *      none.                                                                                  *
    156  *                                                                                             *
    157  * WARNINGS:                                                                                   *
    158  *      none.                                                                                  *
    159  *                                                                                             *
    160  * HISTORY:                                                                                    *
    161  *   12/28/1994 BR : Created.                                                                  *
    162  *=============================================================================================*/
    163 void GScreenClass::Init_Clear(void)
    164 {
    165 	/*
    166 	** Clear the ShadowPage & HidPage to force a complete shadow blit.
    167 	*/
    168 	if (ShadowPage) {
    169 		ShadowPage->Clear();
    170 		HiddenPage.Clear();
    171 	}
    172 
    173 	IsToRedraw = true;
    174 }
    175 
    176 
    177 /***********************************************************************************************
    178  * GScreenClass::Init_Theater -- Performs theater-specific initializations.                    *
    179  *                                                                                             *
    180  * This routine (and those that overload it) performs any theater-specific initializations     *
    181  * needed.  This will include setting the palette, setting up remap tables, etc.  This routine *
    182  * only needs to be called when the theater has changed.                                       *
    183  *                                                                                             *
    184  * INPUT:                                                                                      *
    185  *      none.                                                                                  *
    186  *                                                                                             *
    187  * OUTPUT:                                                                                     *
    188  *      none.                                                                                  *
    189  *                                                                                             *
    190  * WARNINGS:                                                                                   *
    191  *      none.                                                                                  *
    192  *                                                                                             *
    193  * HISTORY:                                                                                    *
    194  *   12/28/1994 BR : Created.                                                                  *
    195  *=============================================================================================*/
    196 void GScreenClass::Init_Theater(TheaterType )
    197 {
    198 }
    199 
    200 
    201 /***********************************************************************************************
    202  * GScreenClass::Init_IO -- Initializes the Button list ('Buttons').                           *
    203  *                                                                                             *
    204  * INPUT:                                                                                      *
    205  *      none.                                                                                  *
    206  *                                                                                             *
    207  * OUTPUT:                                                                                     *
    208  *      none.                                                                                  *
    209  *                                                                                             *
    210  * WARNINGS:                                                                                   *
    211  *      none.                                                                                  *
    212  *                                                                                             *
    213  * HISTORY:                                                                                    *
    214  *   12/28/1994 BR : Created.                                                                  *
    215  *=============================================================================================*/
    216 void GScreenClass::Init_IO(void)
    217 {
    218 	/*
    219 	** Reset the button list.  This means that any other elements of the map that need
    220 	** buttons must attach them after this routine is called!
    221 	*/
    222 	Buttons = 0;
    223 
    224 }
    225 
    226 
    227 /***********************************************************************************************
    228  * GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn.                            *
    229  *                                                                                             *
    230  *    This function is used to flag the display system whether any rendering is needed. The    *
    231  *    parameter tells the system either to redraw EVERYTHING, or just that something somewhere *
    232  *    has changed and the individual Draw_It functions must be called. When a sub system       *
    233  *    determines that it needs to render something local to itself, it would call this routine *
    234  *    with a false parameter. If the entire screen gets trashed or needs to be rebuilt, then   *
    235  *    this routine will be called with a true parameter.                                       *
    236  *                                                                                             *
    237  * INPUT:   complete -- bool; Should the ENTIRE screen be redrawn?                             *
    238  *                                                                                             *
    239  * OUTPUT:  none                                                                               *
    240  *                                                                                             *
    241  * WARNINGS:   This doesn't actually draw the screen, it merely sets flags so that when the    *
    242  *             Render() function is called, the appropriate drawing steps will be performed.   *
    243  *                                                                                             *
    244  * HISTORY:                                                                                    *
    245  *   12/15/1994 JLB : Created.                                                                 *
    246  *=============================================================================================*/
    247 void GScreenClass::Flag_To_Redraw(bool complete)
    248 {
    249 	IsToUpdate = true;
    250 	if (complete) {
    251 		IsToRedraw = true;
    252 	}
    253 }
    254 
    255 
    256 /***********************************************************************************************
    257  * GScreenClass::Input -- Fetches input and processes gadgets.                                 *
    258  *                                                                                             *
    259  *    This routine will fetch the keyboard/mouse input and dispatch this through the gadget    *
    260  *    system.                                                                                  *
    261  *                                                                                             *
    262  * INPUT:   key      -- Reference to the key code (for future examination).                    *
    263  *                                                                                             *
    264  *          x,y      -- Reference to mouse coordinates (for future examination).               *
    265  *                                                                                             *
    266  * OUTPUT:  none                                                                               *
    267  *                                                                                             *
    268  * WARNINGS:   none                                                                            *
    269  *                                                                                             *
    270  * HISTORY:                                                                                    *
    271  *   01/19/1995 JLB : Created.                                                                 *
    272  *=============================================================================================*/
    273 void GScreenClass::Input(KeyNumType & key, int & x, int & y)
    274 {
    275 	key = Keyboard::Check();
    276 
    277 	x = Keyboard::Mouse_X();
    278 	y = Keyboard::Mouse_Y();
    279 
    280 	if (Buttons) {
    281 
    282 		/*
    283 		** If any buttons need redrawing, they will do so in the Input routine, and
    284 		** they should draw themselves to the HidPage.  So, flag ourselves for a Blit
    285 		** to show the newly drawn buttons.
    286 		*/
    287 		if (Buttons->Is_List_To_Redraw()) {
    288 			Flag_To_Redraw(false);
    289 		}
    290 
    291 		GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage);
    292 
    293 		key = Buttons->Input();
    294 
    295 		Set_Logic_Page(oldpage);
    296 
    297 	} else {
    298 		if (key) {
    299 			key = Keyboard::Get();
    300 		}
    301 	}
    302 	AI(key, x, y);
    303 
    304 }
    305 
    306 
    307 /***********************************************************************************************
    308  * GScreenClass::Add_A_Button -- Add a gadget to the game input system.                        *
    309  *                                                                                             *
    310  *    This will add a gadget to the game input system. The gadget will be processed in         *
    311  *    subsiquent calls to the GScreenClass::Input() function.                                  *
    312  *                                                                                             *
    313  * INPUT:   gadget   -- Reference to the gadget that will be added to the input system.        *
    314  *                                                                                             *
    315  * OUTPUT:  none                                                                               *
    316  *                                                                                             *
    317  * WARNINGS:   none                                                                            *
    318  *                                                                                             *
    319  * HISTORY:                                                                                    *
    320  *   01/19/1995 JLB : Created.                                                                 *
    321  *=============================================================================================*/
    322 void GScreenClass::Add_A_Button(GadgetClass & gadget)
    323 {
    324 	/*------------------------------------------------------------------------
    325 	If this gadget is already in the list, remove it before adding it in:
    326 	- If 1st gadget in list, use Remove_A_Button to remove it, to reset the
    327 	  value of 'Buttons' appropriately
    328 	- Otherwise, just call the Remove function for that gadget to remove it
    329 	  from any list it may be in
    330 	------------------------------------------------------------------------*/
    331 	if (Buttons == &gadget) {
    332 		Remove_A_Button(gadget);
    333 	} else {
    334 		gadget.Remove();
    335 	}
    336 
    337 	/*------------------------------------------------------------------------
    338 	Now add the gadget to our list:
    339 	- If there are not buttons, start the list with this one
    340 	- Otherwise, add it to the tail of the existing list
    341 	------------------------------------------------------------------------*/
    342 	if (Buttons) {
    343 		gadget.Add_Tail(*Buttons);
    344 	} else {
    345 		Buttons = &gadget;
    346 	}
    347 }
    348 
    349 
    350 /***********************************************************************************************
    351  * GScreenClass::Remove_A_Button -- Removes a gadget from the game input system.               *
    352  *                                                                                             *
    353  * INPUT:   gadget   -- Reference to the gadget that will be removed from the input system.    *
    354  *                                                                                             *
    355  * OUTPUT:  none                                                                               *
    356  *                                                                                             *
    357  * WARNINGS:   'gadget' MUST be already a part of 'Buttons', or the new value of 'Buttons'     *
    358  *               will be invalid!                                                              *
    359  *                                                                                             *
    360  * HISTORY:                                                                                    *
    361  *   01/19/1995 JLB : Created.                                                                 *
    362  *=============================================================================================*/
    363 void GScreenClass::Remove_A_Button(GadgetClass & gadget)
    364 {
    365 	Buttons = gadget.Remove();
    366 }
    367 
    368 
    369 /***********************************************************************************************
    370  * GScreenClass::Render -- General drawing dispatcher an display update function.              *
    371  *                                                                                             *
    372  *    This routine should be called in the main game loop (once every game frame). It will     *
    373  *    call the Draw_It() function if necessary. All rendering is performed to the LogicPage    *
    374  *    which is set to the HIDPAGE. After rendering has been performed, the HIDPAGE is          *
    375  *    copied to the visible page.                                                              *
    376  *                                                                                             *
    377  * INPUT:   none                                                                               *
    378  *                                                                                             *
    379  * OUTPUT:  none                                                                               *
    380  *                                                                                             *
    381  * WARNINGS:   This actually updates the graphic display. As a result it can take quite a      *
    382  *             while to perform.                                                               *
    383  *                                                                                             *
    384  * HISTORY:                                                                                    *
    385  *   12/15/1994 JLB : Created.                                                                 *
    386  *=============================================================================================*/
    387 void GScreenClass::Render(void)
    388 {
    389 	//if (Buttons && Buttons->Is_List_To_Redraw()) {
    390 	//	IsToRedraw = true;
    391 	//}
    392 
    393 
    394 	if (IsToUpdate || IsToRedraw) {
    395 
    396 		//WWMouse->Erase_Mouse(&HidPage, TRUE);
    397 		GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage);
    398 
    399 		//if (IsToRedraw) {
    400 		//	Hide_Mouse();
    401 		//	SeenBuff.To_Buffer(0, 0, 320, 200, ShadowPage);
    402 		//	Show_Mouse();
    403 		//}
    404 		Draw_It(IsToRedraw);
    405 
    406 		if (Buttons) Buttons->Draw_All(false);
    407 
    408 #ifdef SCENARIO_EDITOR
    409 		/*
    410 		** Draw the Editor's buttons
    411 		*/
    412 		if (Debug_Map) {
    413 			if (Buttons) {
    414 				Buttons->Draw_All();
    415 			}
    416 		}
    417 #endif
    418 		/*
    419 		** Draw the multiplayer message system to the Hidpage at this point.
    420 		** This way, they'll Blit along with the rest of the map.
    421 		*/
    422 		if (Messages.Num_Messages() > 0) {
    423 			Messages.Set_Width(Lepton_To_Cell(Map.TacLeptonWidth) * ICON_PIXEL_W);
    424 		}
    425 		Messages.Draw();
    426 
    427 		//Blit_Display(); // 5/19/20 SKY - Skip copying to scene page, we can get the data directly from hidden page
    428 		IsToUpdate = false;
    429 		IsToRedraw = false;
    430 
    431 		Set_Logic_Page(oldpage);
    432 	}
    433 }
    434 
    435 
    436 
    437 #ifdef CHEAT_KEYS
    438 
    439 #define MAX_SCREENS_SAVED 30*15	      // Enough for 30 seconds @ 15 fps
    440 
    441 GraphicBufferClass *ScreenList[MAX_SCREENS_SAVED];
    442 int CurrentScreen = 0;
    443 bool ScreenRecording = false;
    444 
    445 void Add_Current_Screen(void)
    446 {
    447 #if (0)		                            // ST - 1/2/2019 5:51PM
    448 	if (ScreenRecording){
    449 		ScreenList[CurrentScreen] = new GraphicBufferClass;
    450 		ScreenList[CurrentScreen]->Init ( SeenBuff.Get_Width(), SeenBuff.Get_Height(), NULL, 0, (GBC_Enum) 0);
    451 		SeenBuff.Blit (*ScreenList[CurrentScreen]);
    452 
    453 		CurrentScreen++;
    454 
    455 		if (CurrentScreen == MAX_SCREENS_SAVED){
    456 
    457 			char filename[20];
    458 			for (int i = 0 ; i < MAX_SCREENS_SAVED ; i++){
    459 				sprintf (filename, "SCRN%04d.PCX", i);
    460 				Write_PCX_File (filename,*ScreenList[i], (unsigned char *)CurrentPalette);
    461 				delete ScreenList[i];
    462 			}
    463 
    464 			CurrentScreen = 0;
    465 			ScreenRecording = 0;
    466 
    467 		}
    468 	}
    469 #endif
    470 }
    471 
    472 #endif	//CHEAT_KEYS
    473 
    474 
    475 extern bool CanVblankSync;
    476 
    477 /***********************************************************************************************
    478  * GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage.          *
    479  *                                                                                             *
    480  *    This routine is used to copy the correct display from the HIDPAGE                        *
    481  *    to the SEENPAGE.                                                                         *
    482  *                                                                                             *
    483  * INPUT:   none                                                                               *
    484  *                                                                                             *
    485  * OUTPUT:  none                                                                               *
    486  *                                                                                             *
    487  * WARNINGS:   none                                                                            *
    488  *                                                                                             *
    489  * HISTORY:                                                                                    *
    490  *   02/14/1994 JLB : Created.                                                                 *
    491  *   05/01/1994 JLB : Converted to member function.                                            *
    492  *=============================================================================================*/
    493 void GScreenClass::Blit_Display(void)
    494 {
    495 	if (SeenBuff.Get_Width()!=320){
    496 #if (0)
    497 		if (HidPage.Get_IsDirectDraw() && (Options.GameSpeed >1 || Options.ScrollRate==6 && CanVblankSync) ){
    498 			WWMouse->Draw_Mouse(&HidPage);
    499 			SeenBuff.Get_Graphic_Buffer()->Get_DD_Surface()->Flip(NULL , DDFLIP_WAIT);
    500 			SeenBuff.Blit (HidPage , 0 , 0 , 0 , 0 , SeenBuff.Get_Width() , SeenBuff.Get_Height() , (BOOL) FALSE );
    501 #ifdef CHEAT_KEYS
    502 			Add_Current_Screen();
    503 #endif
    504 			//HidPage.Blit ( SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE );
    505 			WWMouse->Erase_Mouse(&HidPage, FALSE);
    506 		}else{
    507 #else	//(0)
    508 			WWMouse->Draw_Mouse(&HidPage);
    509 			HidPage.Blit ( SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE );
    510 #ifdef CHEAT_KEYS
    511 			Add_Current_Screen();
    512 #endif
    513 			WWMouse->Erase_Mouse(&HidPage, FALSE);
    514 #endif	//(0)
    515 #if (0)
    516 		}
    517 #endif	//(0)
    518 
    519 	} else {
    520 		// ST - 1/2/2019 5:26PM
    521 		//ModeX_Blit (&HiddenPage);
    522 	}
    523 
    524 }
    525 
    526 
    527 
    528