CnC_Remastered_Collection

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

GSCREEN.CPP (28580B)


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