CnC_Remastered_Collection

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

SIDEBAR.CPP (113668B)


      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/SIDEBAR.CPP 2     3/17/97 1:05a Steve_tall $ */
     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 : SIDEBAR.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : October 20, 1994                                             *
     28  *                                                                                             *
     29  *                  Last Update : October 9, 1996 [JLB]                                        *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   SidebarClass::AI -- Handles player clicking on sidebar area.                              *
     34  *   SidebarClass::Abandon_Production -- Stops production of the object specified.             *
     35  *   SidebarClass::Activate -- Controls the sidebar activation.                                *
     36  *   SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar.           *
     37  *   SidebarClass::Activate_Repair -- Controls the repair button on the sidebar.               *
     38  *   SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar.             *
     39  *   SidebarClass::Add -- Adds a game object to the sidebar list.                              *
     40  *   SidebarClass::Draw_It -- Renders the sidebar display.                                     *
     41  *   SidebarClass::Factory_Link -- Links a factory to a sidebar strip.                         *
     42  *   SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state               *
     43  *   SidebarClass::Init_IO -- Adds buttons to the button list                                  *
     44  *   SidebarClass::Init_Theater -- Performs theater-specific initialization                    *
     45  *   SidebarClass::One_Time -- Handles the one time game initializations.                      *
     46  *   SidebarClass::One_Time -- Handles the one time game initializations.                      *
     47  *   SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary.            *
     48  *   SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls.      *
     49  *   SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the s*
     50  *   SidebarClass::Scroll -- Handles scrolling the sidebar object strip.                       *
     51  *   SidebarClass::Set_Current -- Sets a specified object that controls the sidebar display.   *
     52  *   SidebarClass::SidebarClass -- Default constructor for the sidebar.                        *
     53  *   SidebarClass::SidebarClass -- This is the no initialization constructor for the sidebar.  *
     54  *   SidebarClass::StripClass::AI -- Input and AI processing for the side strip.               *
     55  *   SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar.   *
     56  *   SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system.         *
     57  *   SidebarClass::StripClass::Add -- Add an object to the side strip.                         *
     58  *   SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syst*
     59  *   SidebarClass::StripClass::Draw_It -- Render the sidebar display.                          *
     60  *   SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button.            *
     61  *   SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn.         *
     62  *   SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape.     *
     63  *   SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state   *
     64  *   SidebarClass::StripClass::Init_IO -- Adds buttons to the button list                      *
     65  *   SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization        *
     66  *   SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side str*
     67  *   SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects.      *
     68  *   SidebarClass::StripClass::Scroll -- Causes the side strip to scroll.                      *
     69  *   SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selecte*
     70  *   SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select bu*
     71  *   SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor.                *
     72  *   SidebarClass::StripClass::StripClass -- Default constructor for the side strip class.     *
     73  *   SidebarClass::Which_Column -- Determines which column a given type should appear.         *
     74  *   SidebarClass::Zoom_Mode_Control -- Handles the zoom mode toggle operation.                *
     75  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     76 
     77 #include	"function.h"
     78 
     79 
     80 void * SidebarClass::SidebarShape = NULL;
     81 void * SidebarClass::SidebarMiddleShape = NULL;
     82 void * SidebarClass::SidebarBottomShape = NULL;
     83 
     84 
     85 /***************************************************************************
     86 **	This holds the translucent table for use with the construction clock
     87 **	animation.
     88 */
     89 char SidebarClass::StripClass::ClockTranslucentTable[(1+1)*256];
     90 
     91 
     92 /***************************************************************************
     93 **	This points to the main sidebar shapes. These include the upgrade and
     94 **	repair buttons.
     95 */
     96 //TheaterType SidebarClass::StripClass::LastTheater = THEATER_NONE;
     97 
     98 typedef enum ButtonNumberType {
     99 	BUTTON_RADAR = 100,
    100 	BUTTON_REPAIR,
    101 	BUTTON_DEMOLISH,
    102 	BUTTON_UPGRADE,
    103 	BUTTON_SELECT,
    104 	BUTTON_ZOOM
    105 } ButtonNumberType;
    106 
    107 /*
    108 ** Sidebar buttons
    109 */
    110 SidebarClass::SBGadgetClass SidebarClass::Background;
    111 ShapeButtonClass SidebarClass::Repair;
    112 ShapeButtonClass SidebarClass::Upgrade;
    113 ShapeButtonClass SidebarClass::Zoom;
    114 ShapeButtonClass SidebarClass::StripClass::UpButton[COLUMNS];
    115 ShapeButtonClass SidebarClass::StripClass::DownButton[COLUMNS];
    116 SidebarClass::StripClass::SelectClass
    117 SidebarClass::StripClass::SelectButton[COLUMNS][MAX_VISIBLE];
    118 
    119 /*
    120 ** Shape data pointers
    121 */
    122 void * SidebarClass::StripClass::LogoShapes = NULL;
    123 void const * SidebarClass::StripClass::ClockShapes;
    124 void const * SidebarClass::StripClass::SpecialShapes[SPC_COUNT];
    125 
    126 
    127 /***********************************************************************************************
    128  * SidebarClass::SidebarClass -- Default constructor for the sidebar.                          *
    129  *                                                                                             *
    130  *    Constructor for the sidebar handler. It basically sets up the sidebar to the empty       *
    131  *    condition.                                                                               *
    132  *                                                                                             *
    133  * INPUT:   none                                                                               *
    134  *                                                                                             *
    135  * OUTPUT:  none                                                                               *
    136  *                                                                                             *
    137  * WARNINGS:   none                                                                            *
    138  *                                                                                             *
    139  * HISTORY:                                                                                    *
    140  *   11/17/1994 JLB : Created.                                                                 *
    141  *=============================================================================================*/
    142 SidebarClass::SidebarClass(void) :
    143 	IsSidebarActive(false),
    144 	IsToRedraw(true),
    145 	IsRepairActive(false),
    146 	IsUpgradeActive(false),
    147 	IsDemolishActive(false)
    148 {
    149 	/*
    150 	**	This sets up the clipping window. This window is used by the shape drawing
    151 	**	code so that as the sidebar buildable buttons scroll, they get properly
    152 	**	clipped at the top and bottom edges.
    153 	*/
    154 	WindowList[WINDOW_SIDEBAR][WINDOWX] = (SIDE_X+8);
    155 	WindowList[WINDOW_SIDEBAR][WINDOWY] = SIDE_Y + 1 + TOP_HEIGHT;
    156 	WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = SIDE_WIDTH;
    157 	WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT;
    158 //	WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT-1;
    159 
    160 	/*
    161 	**	Set up the coordinates for the sidebar strips. These coordinates are for
    162 	**	the upper left corner.
    163 	*/
    164 	new (&Column[0]) StripClass(InitClass());
    165 	new (&Column[1]) StripClass(InitClass());
    166 
    167 	Column[0].X = COLUMN_ONE_X * RESFACTOR;
    168 	Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
    169 	Column[1].X = COLUMN_TWO_X * RESFACTOR;
    170 	Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
    171 }
    172 
    173 
    174 /***********************************************************************************************
    175  * SidebarClass::SidebarClass -- This is the no initialization constructor for the sidebar.    *
    176  *                                                                                             *
    177  *    Unlike the normal constructor, this one doesn't do any initialization. There is one      *
    178  *    exception to this. The stip classes can't call an explicit NoInitClass constructor       *
    179  *    since they are an array. Since the default constructor is called for these strips, we    *
    180  *    must reset the X and Y location to what we know they should be.                          *
    181  *                                                                                             *
    182  * INPUT:   flag to indicate that this is a no initialization constructor.                     *
    183  *                                                                                             *
    184  * OUTPUT:  none                                                                               *
    185  *                                                                                             *
    186  * WARNINGS:   none                                                                            *
    187  *                                                                                             *
    188  * HISTORY:                                                                                    *
    189  *   08/06/1996 JLB : Created.                                                                 *
    190  *=============================================================================================*/
    191 SidebarClass::SidebarClass(NoInitClass const & x) : PowerClass(x)
    192 {
    193 	/*
    194 	**	Set up the coordinates for the sidebar strips. These coordinates are for
    195 	**	the upper left corner.
    196 	*/
    197 //	Column[0].X = COLUMN_ONE_X * RESFACTOR;
    198 //	Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
    199 //	Column[1].X = COLUMN_TWO_X * RESFACTOR;
    200 //	Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
    201 }
    202 
    203 
    204 /***********************************************************************************************
    205  * SidebarClass::One_Time -- Handles the one time game initializations.                        *
    206  *                                                                                             *
    207  *    This routine is used to load the graphic data that is needed by the sidebar display. It  *
    208  *    should only be called ONCE.                                                              *
    209  *                                                                                             *
    210  * INPUT:   none                                                                               *
    211  *                                                                                             *
    212  * OUTPUT:  none                                                                               *
    213  *                                                                                             *
    214  * WARNINGS:   Only call this routine once when the game first starts.                         *
    215  *                                                                                             *
    216  * HISTORY:                                                                                    *
    217  *   10/28/94   JLB : Created.                                                                 *
    218  *=============================================================================================*/
    219 void SidebarClass::One_Time(void)
    220 {
    221 	PowerClass::One_Time();
    222 
    223 	/*
    224 	**	This sets up the clipping window. This window is used by the shape drawing
    225 	**	code so that as the sidebar buildable buttons scroll, they get properly
    226 	**	clipped at the top and bottom edges.
    227 	*/
    228 	WindowList[WINDOW_SIDEBAR][WINDOWX] = ((SIDE_X+8))  * RESFACTOR;
    229 	WindowList[WINDOW_SIDEBAR][WINDOWY] = (SIDE_Y + 1 + TOP_HEIGHT) * RESFACTOR;
    230 	WindowList[WINDOW_SIDEBAR][WINDOWWIDTH] = (SIDE_WIDTH) * RESFACTOR;
    231 	WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT) * RESFACTOR;
    232 //	WindowList[WINDOW_SIDEBAR][WINDOWHEIGHT] = (StripClass::MAX_VISIBLE * StripClass::OBJECT_HEIGHT-1) * RESFACTOR;
    233 
    234 	/*
    235 	** Top of the window seems to be wrong for the new sidebar. ST - 5/2/96 2:49AM
    236 	*/
    237 	WindowList[WINDOW_SIDEBAR][WINDOWY] -= 1*RESFACTOR;
    238 
    239 	/*
    240 	**	Set up the coordinates for the sidebar strips. These coordinates are for
    241 	**	the upper left corner.
    242 	*/
    243 //	Column[0].X = COLUMN_ONE_X * RESFACTOR;
    244 //	Column[0].Y = COLUMN_ONE_Y * RESFACTOR;
    245 //	Column[1].X = COLUMN_TWO_X * RESFACTOR;
    246 //	Column[1].Y = COLUMN_TWO_Y * RESFACTOR;
    247 	Column[0].One_Time(0);
    248 	Column[1].One_Time(1);
    249 
    250 	/*
    251 	**	Load the sidebar shape in at this time. (Hi-Res sidebar is theater dependant)
    252 	*/
    253 	if (SidebarShape == NULL) {
    254 		SidebarShape = (void*)MFCD::Retrieve("SIDEBAR.SHP");
    255 	}
    256 }
    257 
    258 
    259 /***********************************************************************************************
    260  * SidebarClass::Init_Clear -- Sets sidebar to a known (and deactivated) state                 *
    261  *                                                                                             *
    262  * INPUT:   none                                                                               *
    263  *                                                                                             *
    264  * OUTPUT:  none                                                                               *
    265  *                                                                                             *
    266  * WARNINGS:   none                                                                            *
    267  *                                                                                             *
    268  * HISTORY:                                                                                    *
    269  *   12/24/1994 JLB : Created.                                                                 *
    270  *=============================================================================================*/
    271 void SidebarClass::Init_Clear(void)
    272 {
    273 
    274 	PowerClass::Init_Clear();
    275 
    276 	IsToRedraw = true;
    277 	IsRepairActive = false;
    278 	IsUpgradeActive = false;
    279 	IsDemolishActive = false;
    280 
    281 	Column[0].Init_Clear();
    282 	Column[1].Init_Clear();
    283 
    284 	Activate(false);
    285 }
    286 
    287 
    288 /***********************************************************************************************
    289  * SidebarClass::Init_IO -- Adds buttons to the button list                                    *
    290  *                                                                                             *
    291  * INPUT:   none                                                                               *
    292  *                                                                                             *
    293  * OUTPUT:  none                                                                               *
    294  *                                                                                             *
    295  * WARNINGS:   none                                                                            *
    296  *                                                                                             *
    297  * HISTORY:                                                                                    *
    298  *   12/24/1994 JLB : Created.                                                                 *
    299  *=============================================================================================*/
    300 void SidebarClass::Init_IO(void)
    301 {
    302 	PowerClass::Init_IO();
    303 
    304 	/*
    305 	** Add the sidebar's buttons only if we're not in editor mode.
    306 	*/
    307 	if (!Debug_Map) {
    308 
    309 		Repair.IsSticky = true;
    310 		Repair.ID = BUTTON_REPAIR;
    311 		Repair.X = (0x1f2/2)*RESFACTOR;
    312 		Repair.Y = (0x96/2)*RESFACTOR;
    313 		Repair.IsPressed = false;
    314 		Repair.IsToggleType = true;
    315 		Repair.ReflectButtonState = true;
    316 		Repair.Set_Shape(MFCD::Retrieve("REPAIR.SHP"));
    317 
    318 		Upgrade.IsSticky = true;
    319 		Upgrade.ID = BUTTON_UPGRADE;
    320 #ifdef WIN32
    321 		Upgrade.X = 0x21f;
    322 #else
    323 		Upgrade.X = ((0x21f/2)+1)*RESFACTOR;
    324 #endif
    325 		Upgrade.Y = (0x96/2)*RESFACTOR;
    326 		Upgrade.IsPressed = false;
    327 		Upgrade.IsToggleType = true;
    328 		Upgrade.ReflectButtonState = true;
    329 		Upgrade.Set_Shape(MFCD::Retrieve("SELL.SHP"));
    330 
    331 		Zoom.IsSticky = true;
    332 		Zoom.ID = BUTTON_ZOOM;
    333 		Zoom.X = (0x24c/2)*RESFACTOR;
    334 		Zoom.Y = (0x96/2)*RESFACTOR;
    335 		Zoom.IsPressed = false;
    336 		Zoom.Set_Shape(MFCD::Retrieve("MAP.SHP"));
    337 
    338 		if ((IsRadarActive && Is_Zoomable()) || Session.Type != GAME_NORMAL) {
    339 			Zoom.Enable();
    340 		} else {
    341 			Zoom.Disable();
    342 		}
    343 		Column[0].Init_IO(0);
    344 		Column[1].Init_IO(1);
    345 
    346 		/*
    347 		** If a game was loaded & the sidebar was enabled, pop it up now
    348 		*/
    349 		if (IsSidebarActive) {
    350 			IsSidebarActive = false;
    351 			Activate(1);
    352 //			Background.Zap();
    353 //			Add_A_Button(Background);
    354 		}
    355 	}
    356 }
    357 
    358 
    359 /***********************************************************************************************
    360  * SidebarClass::Init_Theater -- Performs theater-specific initialization                      *
    361  *                                                                                             *
    362  * INPUT:   theater  -- The theater that is being initialized. Sometimes this has an effect on *
    363  *                      the data that is loaded.                                               *
    364  *                                                                                             *
    365  * OUTPUT:  none                                                                               *
    366  *                                                                                             *
    367  * WARNINGS:   none                                                                            *
    368  *                                                                                             *
    369  * HISTORY:                                                                                    *
    370  *   12/24/1994 JLB : Created.                                                                 *
    371  *=============================================================================================*/
    372 void SidebarClass::Init_Theater(TheaterType theater)
    373 {
    374 	Reload_Sidebar();
    375 
    376 	PowerClass::Init_Theater(theater);
    377 
    378 	Column[0].Init_Theater(theater);
    379 	Column[1].Init_Theater(theater);
    380 }
    381 
    382 /***********************************************************************************************
    383  * SidebarClass::Reload_Sidebar -- Loads appropriate sidebar shapes depending on house			  *
    384  *                                                                                             *
    385  * INPUT:  none 																										  *
    386  *                                                                                             *
    387  * OUTPUT:  none                                                                               *
    388  *                                                                                             *
    389  * WARNINGS:   none                                                                            *
    390  *                                                                                             *
    391  * HISTORY:                                                                                    *
    392  *   9/18/1996 BWG : Created.                                                                 *
    393  *=============================================================================================*/
    394 void SidebarClass::Reload_Sidebar(void)
    395 {
    396 	static char * sidebarnames[]={
    397 		"SIDE?NA.SHP",		//NATO
    398 		"SIDE?NA.SHP",
    399 		"SIDE?US.SHP",		//USSR
    400 		"SIDE?NA.SHP",
    401 		"SIDE?US.SHP",		//UKRAINE
    402 		"SIDE?NA.SHP",
    403 		"SIDE?NA.SHP",
    404 		"SIDE?NA.SHP",
    405 		"SIDE?NA.SHP",		//HOUSE_GOOD
    406 		"SIDE?US.SHP"		//HOUSE_BAD
    407 	};
    408 	int houseloaded = 0;
    409 
    410 	if(PlayerPtr) {
    411 		houseloaded = PlayerPtr->ActLike;
    412 	}
    413 
    414 	/*  Don't have write access to the static char array. ST - 5/20/2019 */
    415 #if (0)
    416 	char * sidename = sidebarnames[houseloaded];
    417 	*(sidename+4) = '1';
    418 	SidebarShape = (void*)MFCD::Retrieve(sidename);
    419 	*(sidename+4) = '2';
    420 	SidebarMiddleShape = (void*)MFCD::Retrieve(sidename);
    421 	*(sidename+4) = '3';
    422 	SidebarBottomShape = (void*)MFCD::Retrieve(sidename);
    423 #else
    424 	char sb_name[16];
    425 	strcpy(sb_name, sidebarnames[houseloaded]);
    426 	sb_name[4] = '1';
    427 	SidebarShape = (void*)MFCD::Retrieve(sb_name);
    428 	sb_name[4] = '2';
    429 	SidebarMiddleShape = (void*)MFCD::Retrieve(sb_name);
    430 	sb_name[4] = '3';
    431 	SidebarBottomShape = (void*)MFCD::Retrieve(sb_name);
    432 
    433 #endif
    434 
    435 
    436 
    437 
    438 	Column[0].Reload_LogoShapes();
    439 	Column[1].Reload_LogoShapes();
    440 }
    441 
    442 /***********************************************************************************************
    443  * SidebarClass::Which_Column -- Determines which column a given type should appear.           *
    444  *                                                                                             *
    445  *    Use this function to resolve what column the specified object type should be placed      *
    446  *    into.                                                                                    *
    447  *                                                                                             *
    448  * INPUT:   otype -- Pointer to the object type class of the object in question.               *
    449  *                                                                                             *
    450  * OUTPUT:  Returns with the column number that the object should be placed in.                *
    451  *                                                                                             *
    452  * WARNINGS:   none                                                                            *
    453  *                                                                                             *
    454  * HISTORY:                                                                                    *
    455  *   01/01/1995 JLB : Created.                                                                 *
    456  *=============================================================================================*/
    457 int SidebarClass::Which_Column(RTTIType type)
    458 {
    459 	if (type == RTTI_BUILDINGTYPE || type == RTTI_BUILDING) {
    460 		return(0);
    461 	}
    462 	return(1);
    463 }
    464 
    465 
    466 /***********************************************************************************************
    467  * SidebarClass::Factory_Link -- Links a factory to a sidebar strip.                           *
    468  *                                                                                             *
    469  *    This routine will link the specified factory to the sidebar strip. A factory must be     *
    470  *    linked to the sidebar so that as the factory production progresses, the sidebar will     *
    471  *    show the production progress.                                                            *
    472  *                                                                                             *
    473  * INPUT:   factory  -- The factory number to attach.                                          *
    474  *                                                                                             *
    475  *          type     -- The object type number.                                                *
    476  *                                                                                             *
    477  *          id       -- The object sub-type number.                                            *
    478  *                                                                                             *
    479  * OUTPUT:  Was the factory successfully attached to the sidebar strip?                        *
    480  *                                                                                             *
    481  * WARNINGS:   none                                                                            *
    482  *                                                                                             *
    483  * HISTORY:                                                                                    *
    484  *   05/19/1995 JLB : Created.                                                                 *
    485  *=============================================================================================*/
    486 bool SidebarClass::Factory_Link(int factory, RTTIType type, int id)
    487 {
    488 	assert((unsigned)type < RTTI_COUNT);
    489 	assert(id >= 0);
    490 
    491 	return(Column[Which_Column(type)].Factory_Link(factory, type, id));
    492 }
    493 
    494 
    495 /***********************************************************************************************
    496  * SidebarClass::Refresh_Cells -- Intercepts the refresh, looking for sidebar controls.        *
    497  *                                                                                             *
    498  *    This routine intercepts the Refresh_Cells call in order to see if the sidebar needs      *
    499  *    to be refreshed as well. If the special code to refresh the sidebar was found, it        *
    500  *    flags the sidebar to be redrawn and then removes the code from the list.                 *
    501  *                                                                                             *
    502  * INPUT:   cell  -- The cell to base the refresh list on.                                     *
    503  *                                                                                             *
    504  *          list  -- Pointer to the cell offset list that elaborates all the cells that        *
    505  *                   need to be flagged for redraw.                                            *
    506  *                                                                                             *
    507  * OUTPUT:  none                                                                               *
    508  *                                                                                             *
    509  * WARNINGS:   none                                                                            *
    510  *                                                                                             *
    511  * HISTORY:                                                                                    *
    512  *   01/19/1995 JLB : Created.                                                                 *
    513  *=============================================================================================*/
    514 void SidebarClass::Refresh_Cells(CELL cell, short const * list)
    515 {
    516 	if (*list == REFRESH_SIDEBAR) {
    517 		IsToRedraw = true;
    518 		Column[0].IsToRedraw = true;
    519 		Column[1].IsToRedraw = true;
    520 		Flag_To_Redraw(false);
    521 	}
    522 	PowerClass::Refresh_Cells(cell, list);
    523 }
    524 
    525 
    526 /***********************************************************************************************
    527  * SidebarClass::Activate_Repair -- Controls the repair button on the sidebar.                 *
    528  *                                                                                             *
    529  *    Use this routine to turn the repair sidebar button on and off. Typically, the button     *
    530  *    is enabled when the currently selected structure is friendly and damaged.                *
    531  *                                                                                             *
    532  * INPUT:   control  -- The controls how the button is to be activated or deactivated;         *
    533  *                      0  -- Turn button off.                                                 *
    534  *                      1  -- Turn button on.                                                  *
    535  *                      -1 -- Toggle button state.                                             *
    536  *                                                                                             *
    537  * OUTPUT:  bool; Was the button previously activated?                                         *
    538  *                                                                                             *
    539  * WARNINGS:   none                                                                            *
    540  *                                                                                             *
    541  * HISTORY:                                                                                    *
    542  *   12/24/1994 JLB : Created.                                                                 *
    543  *=============================================================================================*/
    544 bool SidebarClass::Activate_Repair(int control)
    545 {
    546 	bool old = IsRepairActive;
    547 
    548 	if (control == -1) {
    549 		control = IsRepairActive ? 0 : 1;
    550 	}
    551 	switch (control) {
    552 		case 1:
    553 			IsRepairActive = true;
    554 			break;
    555 
    556 		default:
    557 		case 0:
    558 			IsRepairActive = false;
    559 			break;
    560 	}
    561 	if (old != IsRepairActive) {
    562 		Flag_To_Redraw(false);
    563 		IsToRedraw = true;
    564 
    565 		if (!IsRepairActive) {
    566 			Help_Text(TXT_NONE);
    567 			Set_Default_Mouse(MOUSE_NORMAL, false);
    568 		}
    569 	}
    570 	return(old);
    571 }
    572 
    573 
    574 /***********************************************************************************************
    575  * SidebarClass::Activate_Upgrade -- Controls the upgrade button on the sidebar.               *
    576  *                                                                                             *
    577  *    Use this routine to turn the upgrade sidebar button on and off. Typically, the button    *
    578  *    is enabled when the currently selected structure can be upgraded and disabled otherwise. *
    579  *                                                                                             *
    580  * INPUT:   control  -- The controls how the button is to be activated or deactivated;         *
    581  *                      0  -- Turn button off.                                                 *
    582  *                      1  -- Turn button on.                                                  *
    583  *                      -1 -- Toggle button state.                                             *
    584  *                                                                                             *
    585  * OUTPUT:  bool; Was the button previously activated?                                         *
    586  *                                                                                             *
    587  * WARNINGS:   none                                                                            *
    588  *                                                                                             *
    589  * HISTORY:                                                                                    *
    590  *   12/24/1994 JLB : Created.                                                                 *
    591  *=============================================================================================*/
    592 bool SidebarClass::Activate_Upgrade(int control)
    593 {
    594 	bool old = IsUpgradeActive;
    595 	if (control == -1) {
    596 		control = IsUpgradeActive ? 0 : 1;
    597 	}
    598 	switch (control) {
    599 		case 1:
    600 			IsUpgradeActive = true;
    601 			break;
    602 
    603 		default:
    604 		case 0:
    605 			IsUpgradeActive = false;
    606 			break;
    607 	}
    608 	if (old != IsUpgradeActive) {
    609 		Flag_To_Redraw(false);
    610 		IsToRedraw = true;
    611 		if (!IsUpgradeActive) {
    612 			Set_Default_Mouse(MOUSE_NORMAL, false);
    613 		}
    614 	}
    615 	return(old);
    616 }
    617 
    618 
    619 /***********************************************************************************************
    620  * SidebarClass::Activate_Demolish -- Controls the demolish button on the sidebar.             *
    621  *                                                                                             *
    622  *    Use this routine to turn the demolish/dismantle sidebar button on and off. Typically,    *
    623  *    the button is enabled when a friendly building is selected and disabled otherwise.       *
    624  *                                                                                             *
    625  * INPUT:   control  -- The controls how the button is to be activated or deactivated;         *
    626  *                      0  -- Turn button off.                                                 *
    627  *                      1  -- Turn button on.                                                  *
    628  *                      -1 -- Toggle button state.                                             *
    629  *                                                                                             *
    630  * OUTPUT:  bool; Was the button previously activated?                                         *
    631  *                                                                                             *
    632  * WARNINGS:   none                                                                            *
    633  *                                                                                             *
    634  * HISTORY:                                                                                    *
    635  *   12/24/1994 JLB : Created.                                                                 *
    636  *=============================================================================================*/
    637 bool SidebarClass::Activate_Demolish(int control)
    638 {
    639 	bool old = IsDemolishActive;
    640 
    641 	if (control == -1) {
    642 		control = IsDemolishActive ? 0 : 1;
    643 	}
    644 	switch (control) {
    645 		case 1:
    646 			IsDemolishActive = true;
    647 			break;
    648 
    649 		default:
    650 		case 0:
    651 			IsDemolishActive = false;
    652 			break;
    653 	}
    654 	if (old != IsDemolishActive) {
    655 		Flag_To_Redraw(false);
    656 		IsToRedraw = true;
    657 		if (!IsDemolishActive) {
    658 			Set_Default_Mouse(MOUSE_NORMAL, false);
    659 		}
    660 	}
    661 	return(old);
    662 }
    663 
    664 
    665 /***********************************************************************************************
    666  * SidebarClass::Add -- Adds a game object to the sidebar list.                                *
    667  *                                                                                             *
    668  *    This routine is used to add a game object to the sidebar. Call this routine when a       *
    669  *    factory type building is created. It handles the case of adding an item that has already *
    670  *    been added -- it just ignores it.                                                        *
    671  *                                                                                             *
    672  * INPUT:   object   -- Pointer to the object that is being added.                             *
    673  *                                                                                             *
    674  * OUTPUT:  bool; Was the object added to the sidebar?                                         *
    675  *                                                                                             *
    676  * WARNINGS:   none                                                                            *
    677  *                                                                                             *
    678  * HISTORY:                                                                                    *
    679  *   11/17/1994 JLB : Created.                                                                 *
    680  *   9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality              *
    681  *=============================================================================================*/
    682 bool SidebarClass::Add(RTTIType type, int id, bool via_capture)
    683 {
    684 	assert((unsigned)type < RTTI_COUNT);
    685 
    686 	/*
    687 	** Add the sidebar only if we're not in editor mode.
    688 	*/
    689 	if (!Debug_Map) {
    690 		int column = Which_Column(type);
    691 
    692 		if (Column[column].Add(type, id, via_capture)) {
    693 			Activate(1);
    694 			IsToRedraw = true;
    695 			Flag_To_Redraw(false);
    696 			return(true);
    697 		}
    698 		return(false);
    699 	}
    700 
    701 	return(false);
    702 }
    703 
    704 
    705 /***********************************************************************************************
    706  * SidebarClass::Scroll -- Handles scrolling the sidebar object strip.                         *
    707  *                                                                                             *
    708  *    This routine is used to scroll the sidebar strip of objects. The strip appears whenever  *
    709  *    a building is selected that can produce units. If the number of units to produce is      *
    710  *    greater than what the sidebar can hold, this routine is used to scroll the other object  *
    711  *    into view so they can be selected.                                                       *
    712  *                                                                                             *
    713  * INPUT:   up -- Should the scroll be upwards? Upward scrolling reveals object that are       *
    714  *                later in the list of objects.                                                *
    715  *                                                                                             *
    716  * OUTPUT:  bool; Did scrolling occur?                                                         *
    717  *                                                                                             *
    718  * WARNINGS:   none                                                                            *
    719  *                                                                                             *
    720  * HISTORY:                                                                                    *
    721  *   10/28/94   JLB : Created.                                                                 *
    722  *=============================================================================================*/
    723 bool SidebarClass::Scroll(bool up, int column)
    724 {
    725 	if (column == -1) {
    726 		bool scr = false;
    727 		scr |= Column[0].Scroll(up);
    728 		scr |= Column[1].Scroll(up);
    729 		if (!scr) {
    730 			Sound_Effect(VOC_SCOLD);
    731 		}
    732 		if (scr) {
    733 			IsToRedraw = true;
    734 			Flag_To_Redraw(false);
    735 			return(true);
    736 		}
    737 		return(false);
    738 	}
    739 
    740 	if (Column[column].Scroll(up)) {
    741 		// No need to redraw the whole sidebar juts because we scrolled a strip is there? ST - 10/15/96 7:29PM
    742 		//IsToRedraw = true;
    743 		Flag_To_Redraw(false);
    744 		return(true);
    745 	}
    746 	return(false);
    747 }
    748 
    749 
    750 /***********************************************************************************************
    751  * SidebarClass::Draw_It -- Renders the sidebar display.                                       *
    752  *                                                                                             *
    753  *    This routine performs the actual drawing of the sidebar display.                         *
    754  *                                                                                             *
    755  * INPUT:   none                                                                               *
    756  *                                                                                             *
    757  * OUTPUT:  bool; Was the sidebar imagery changed at all?                                      *
    758  *                                                                                             *
    759  * WARNINGS:   none                                                                            *
    760  *                                                                                             *
    761  * HISTORY:                                                                                    *
    762  *   10/28/94   JLB : Created.                                                                 *
    763  *   12/31/1994 JLB : Split rendering off into the sidebar strip class.                        *
    764  *=============================================================================================*/
    765 void SidebarClass::Draw_It(bool complete)
    766 {
    767 	PowerClass::Draw_It(complete);
    768 
    769 	BStart(BENCH_SIDEBAR);
    770 
    771 	if (IsSidebarActive && (IsToRedraw || complete) && !Debug_Map) {
    772 		IsToRedraw = false;
    773 
    774 		if (LogicPage->Lock()) {
    775 			/*
    776 			**	Draw the outline box around the sidebar buttons.
    777 			*/
    778 			int shape = complete ? 0 : 1;
    779 
    780 			/*
    781 			** The sidebar shape is too big in 640x400 so it needs to be drawn in three chunks.
    782 			*/
    783 			CC_Draw_Shape(SidebarShape, 0, SIDE_X * RESFACTOR, 8*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
    784 			CC_Draw_Shape(SidebarMiddleShape, shape, SIDE_X * RESFACTOR, (8+80)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
    785 			CC_Draw_Shape(SidebarBottomShape, shape, SIDE_X * RESFACTOR, (8+80+50)*RESFACTOR, WINDOW_MAIN, SHAPE_WIN_REL);
    786 
    787 			Repair.Draw_Me(true);
    788 			Upgrade.Draw_Me(true);
    789 			Zoom.Draw_Me(true);
    790 			LogicPage->Unlock();
    791 		}
    792 	}
    793 
    794 	/*
    795 	**	Draw the side strip elements by calling their respective draw functions.
    796 	*/
    797 	if (IsSidebarActive) {
    798 		Column[0].Draw_It(complete);
    799 		Column[1].Draw_It(complete);
    800 
    801 		if (complete || IsToRedraw) {
    802 			Repair.Draw_Me(true);
    803 			Upgrade.Draw_Me(true);
    804 			Zoom.Draw_Me(true);
    805 		}
    806 	}
    807 	IsToRedraw = false;
    808 
    809 	BEnd(BENCH_SIDEBAR);
    810 }
    811 
    812 
    813 /***********************************************************************************************
    814  * SidebarClass::AI -- Handles player clicking on sidebar area.                                *
    815  *                                                                                             *
    816  *    This routine handles the processing necessary when the player clicks on the sidebar.     *
    817  *    Typically, this is selection of the item to build.                                       *
    818  *                                                                                             *
    819  * INPUT:   input -- Reference to the keyboard input value.                                    *
    820  *                                                                                             *
    821  *          x,y   -- Mouse coordinates at time of input.                                       *
    822  *                                                                                             *
    823  * OUTPUT:  bool; Was the click handled?                                                       *
    824  *                                                                                             *
    825  * WARNINGS:   none                                                                            *
    826  *                                                                                             *
    827  * HISTORY:                                                                                    *
    828  *   10/28/94   JLB : Created.                                                                 *
    829  *   11/11/1994 JLB : Processes input directly.                                                *
    830  *   12/26/1994 JLB : Uses factory manager class for construction handling.                    *
    831  *   12/31/1994 JLB : Simplified to use the sidebar strip class handlers.                      *
    832  *   12/31/1994 JLB : Uses mouse coordinate parameters.                                        *
    833  *   06/27/1995 JLB : <TAB> key toggles sidebar.                                               *
    834  *=============================================================================================*/
    835 void SidebarClass::AI(KeyNumType & input, int x, int y)
    836 {
    837 	bool redraw = false;
    838 
    839 	//
    840 	// We need to process the sidebar differently in multiplayer. ST - 8/7/2019 10:48AM
    841 	//
    842 	if (Session.Type == GAME_GLYPHX_MULTIPLAYER) {
    843 		PowerClass::AI(input, x, y);
    844 		return;
    845 	}
    846 
    847 	/*
    848 	**	Toggle the sidebar in and out with the <TAB> key.
    849 	*/
    850 #ifndef WIN32
    851 	if (input == KN_TAB) {
    852 		Activate(-1);
    853 	}
    854 #else
    855 	if (!Debug_Map) {
    856 		Activate(1);	// Force the sidebar always on in Win95 mode
    857 	}
    858 #endif	//WIN32
    859 	if (!Debug_Map) {
    860 		Column[0].AI(input, x, y);
    861 		Column[1].AI(input, x, y);
    862 	}
    863 
    864 #ifdef NEVER
    865 	if (IsSidebarActive && !Debug_Map) {
    866 
    867 		if (input == KN_DOWN) {
    868 			int scr = 0;
    869 			scr |= Column[0].Scroll(false);
    870 			scr |= Column[1].Scroll(false);
    871 			if (!scr) {
    872 				Sound_Effect(VOC_SCOLD);
    873 			}
    874 			redraw |= scr;
    875 			input = KN_NONE;
    876 		}
    877 		if (input == KN_UP) {
    878 			int scr = 0;
    879 			scr |= Column[0].Scroll(true);
    880 			scr |= Column[1].Scroll(true);
    881 			if (!scr) {
    882 				Sound_Effect(VOC_SCOLD);
    883 			}
    884 			redraw |= scr;
    885 			input = KN_NONE;
    886 		}
    887 	}
    888 #endif
    889 
    890 
    891 	if (IsSidebarActive) {
    892 
    893 		/*
    894 		**	If there are any buildings in the payer's inventory, then allow the repair
    895 		**	option.
    896 		*/
    897 		if (PlayerPtr->BScan) {
    898 			Activate_Repair(true);
    899 		} else {
    900 			Activate_Repair(false);
    901 		}
    902 
    903 		if (input == (BUTTON_REPAIR|KN_BUTTON)) {
    904 			Repair_Mode_Control(-1);
    905 		}
    906 
    907 		if (input == (BUTTON_ZOOM|KN_BUTTON)) {
    908 			Zoom_Mode_Control();
    909 		}
    910 
    911 		if (input == (BUTTON_UPGRADE|KN_BUTTON)) {
    912 			Sell_Mode_Control(-1);
    913 		}
    914 
    915 		if (redraw) {
    916 			//IsToRedraw = true;
    917 			Column[0].Flag_To_Redraw();
    918 			Column[1].Flag_To_Redraw();
    919 
    920 			Flag_To_Redraw(false);
    921 		}
    922 	}
    923 
    924 	if ((!IsRepairMode) && Repair.IsOn) {
    925 		Repair.Turn_Off();
    926 	}
    927 
    928 	if ((!IsSellMode) && Upgrade.IsOn) {
    929 		Upgrade.Turn_Off();
    930 	}
    931 
    932 	PowerClass::AI(input, x, y);
    933 }
    934 
    935 
    936 /***********************************************************************************************
    937  * SidebarClass::Recalc -- Examines the sidebar data and updates it as necessary.              *
    938  *                                                                                             *
    939  *    Occasionally a factory gets destroyed. This routine must be called in such a case        *
    940  *    because it might be possible that sidebar object need to be removed. This routine will   *
    941  *    examine all existing objects in the sidebar class and if no possible factory can         *
    942  *    produce it, then it will be removed.                                                     *
    943  *                                                                                             *
    944  * INPUT:   none                                                                               *
    945  *                                                                                             *
    946  * OUTPUT:  none                                                                               *
    947  *                                                                                             *
    948  * WARNINGS:   This routine is exhaustive and thus time consuming. Only call it when really    *
    949  *             necessary. Such as when a factory is destroyed rather than when a non-factory   *
    950  *             is destroyed.                                                                   *
    951  *                                                                                             *
    952  * HISTORY:                                                                                    *
    953  *   11/30/1994 JLB : Created.                                                                 *
    954  *=============================================================================================*/
    955 void SidebarClass::Recalc(void)
    956 {
    957 	bool redraw = false;
    958 
    959 	// Done elsewhere for new multiplayer. ST - 8/7/2019 10:49AM
    960 	if (Session.Type == GAME_GLYPHX_MULTIPLAYER) {
    961 		return;
    962 	}
    963 
    964 	redraw |= Column[0].Recalc();
    965 	redraw |= Column[1].Recalc();
    966 
    967 	if (redraw) {
    968 		IsToRedraw = true;
    969 		Flag_To_Redraw(false);
    970 	}
    971 }
    972 
    973 
    974 /***********************************************************************************************
    975  * SidebarClass::Activate -- Controls the sidebar activation.                                  *
    976  *                                                                                             *
    977  *    Use this routine to turn the sidebar on or off. This routine handles updating the        *
    978  *    necessary flags.                                                                         *
    979  *                                                                                             *
    980  * INPUT:   control  -- Tells what to do with the sidebar according to the following:          *
    981  *                         0 = Turn sidebar off.                                               *
    982  *                         1 = Turn sidebar on.                                                *
    983  *                         -1= Toggle sidebar on or off.                                       *
    984  *                                                                                             *
    985  * OUTPUT:  bool; Was the sidebar already on?                                                  *
    986  *                                                                                             *
    987  * WARNINGS:   none                                                                            *
    988  *                                                                                             *
    989  * HISTORY:                                                                                    *
    990  *   12/09/1994 JLB : Created.                                                                 *
    991  *=============================================================================================*/
    992 bool SidebarClass::Activate(int control)
    993 {
    994 	//
    995 	// We don't want the original sidebar to be visible. ST - 1/31/2019 11:28AM
    996 	//
    997 	if (control < 100) {
    998 		return IsSidebarActive;
    999 	}
   1000 
   1001 	bool old = IsSidebarActive;
   1002 
   1003 	if (Session.Play)
   1004 		return (old);
   1005 
   1006 	/*
   1007 	**	Determine the new state of the sidebar.
   1008 	*/
   1009 	switch (control) {
   1010 		case -1:
   1011 			IsSidebarActive = IsSidebarActive == false;
   1012 			break;
   1013 
   1014 		case 1:
   1015 			IsSidebarActive = true;
   1016 			break;
   1017 
   1018 		default:
   1019 		case 0:
   1020 			IsSidebarActive = false;
   1021 			break;
   1022 	}
   1023 
   1024 	/*
   1025 	**	Only if there is a change in the state of the sidebar will anything
   1026 	**	be done to change it.
   1027 	*/
   1028 	if (IsSidebarActive != old) {
   1029 
   1030 		/*
   1031 		**	If the sidebar is activated but was on the right side of the screen, then
   1032 		**	activate it on the left side of the screen.
   1033 		*/
   1034 		if (IsSidebarActive /*&& X*/) {
   1035 			Set_View_Dimensions(0, 8 * RESFACTOR, ((320-SIDE_WIDTH)/ICON_PIXEL_W) * RESFACTOR);
   1036 			IsToRedraw = true;
   1037 			Help_Text(TXT_NONE);
   1038 			Repair.Zap();
   1039 			Add_A_Button(Repair);
   1040 			Upgrade.Zap();
   1041 			Add_A_Button(Upgrade);
   1042 			Zoom.Zap();
   1043 			Add_A_Button(Zoom);
   1044 			Column[0].Activate();
   1045 			Column[1].Activate();
   1046 			Background.Zap();
   1047 			Add_A_Button(Background);
   1048 			Map.RadarButton.Zap();
   1049 			Add_A_Button(Map.RadarButton);
   1050 			Map.PowerButton.Zap();
   1051 			Add_A_Button(Map.PowerButton);
   1052 		} else  {
   1053 			Help_Text(TXT_NONE);
   1054 			Set_View_Dimensions(0, 8 * RESFACTOR);
   1055 			Remove_A_Button(Repair);
   1056 			Remove_A_Button(Upgrade);
   1057 			Remove_A_Button(Zoom);
   1058 			Remove_A_Button(Background);
   1059 			Column[0].Deactivate();
   1060 			Column[1].Deactivate();
   1061 			Remove_A_Button(Map.RadarButton);
   1062 			Remove_A_Button(Map.PowerButton);
   1063 		}
   1064 
   1065 		/*
   1066 		**	Since the sidebar status has changed, update the map so that the graphics
   1067 		**	will be rendered correctly.
   1068 		*/
   1069 		Flag_To_Redraw(true);
   1070 	}
   1071 
   1072 	return(old);
   1073 }
   1074 
   1075 
   1076 /***********************************************************************************************
   1077  * SidebarClass::StripClass::StripClass -- Default constructor for the side strip class.       *
   1078  *                                                                                             *
   1079  *    This constructor is used to reset the side strip to default empty state.                 *
   1080  *                                                                                             *
   1081  * INPUT:   none                                                                               *
   1082  *                                                                                             *
   1083  * OUTPUT:  none                                                                               *
   1084  *                                                                                             *
   1085  * WARNINGS:   none                                                                            *
   1086  *                                                                                             *
   1087  * HISTORY:                                                                                    *
   1088  *   12/31/1994 JLB : Created.                                                                 *
   1089  *=============================================================================================*/
   1090 SidebarClass::StripClass::StripClass(InitClass const & ) :
   1091 	X(0),
   1092 	Y(0),
   1093 	ID(0),
   1094 	IsToRedraw(true),
   1095 	IsBuilding(false),
   1096 	IsScrollingDown(false),
   1097 	IsScrolling(false),
   1098 	Flasher(-1),
   1099 	TopIndex(0),
   1100 	Scroller(0),
   1101 	Slid(0),
   1102 	BuildableCount(0)
   1103 {
   1104 	for (int index = 0; index < MAX_BUILDABLES; index++) {
   1105 		Buildables[index].BuildableID = 0;
   1106 		Buildables[index].BuildableType = RTTI_NONE;
   1107 		Buildables[index].Factory = -1;
   1108 		Buildables[index].BuildableViaCapture = false;		// Added for new sidebar functionality. ST - 9/24/2019 3:10PM 
   1109 	}
   1110 }
   1111 
   1112 
   1113 /***********************************************************************************************
   1114  * SidebarClass::StripClass::One_Time -- Performs one time actions necessary for the side stri *
   1115  *                                                                                             *
   1116  *    Call this routine ONCE at the beginning of the game. It handles retrieving pointers to   *
   1117  *    the shape files it needs for rendering.                                                  *
   1118  *                                                                                             *
   1119  * INPUT:   none                                                                               *
   1120  *                                                                                             *
   1121  * OUTPUT:  none                                                                               *
   1122  *                                                                                             *
   1123  * WARNINGS:   none                                                                            *
   1124  *                                                                                             *
   1125  * HISTORY:                                                                                    *
   1126  *   12/31/1994 JLB : Created.                                                                 *
   1127  *=============================================================================================*/
   1128 void SidebarClass::StripClass::One_Time(int )
   1129 {
   1130 	/*
   1131 	** Sidebar is player team specific in Hires
   1132 	*/
   1133 	ClockShapes = MFCD::Retrieve("CLOCK.SHP");
   1134 
   1135 	for (SpecialWeaponType lp = SPC_FIRST; lp < SPC_COUNT; lp++) {
   1136 		char buffer[_MAX_FNAME];
   1137 		sprintf(buffer, "%sICON", SpecialWeaponFile[lp]);
   1138 
   1139 		char	fullname[_MAX_FNAME+_MAX_EXT];
   1140 		_makepath(fullname, NULL, NULL, buffer, ".SHP");
   1141 		SpecialShapes[lp] = MFCD::Retrieve(fullname);
   1142 	}
   1143 }
   1144 
   1145 
   1146 /***********************************************************************************************
   1147  * SidebarClass::StripClass::Get_Special_Cameo -- Fetches the special event cameo shape.       *
   1148  *                                                                                             *
   1149  *    This routine will return with a pointer to the cameo data for the special objects that   *
   1150  *    can appear on the sidebar (e.g., nuclear bomb).                                          *
   1151  *                                                                                             *
   1152  * INPUT:   type  -- The special type to fetch the cameo imagery for.                          *
   1153  *                                                                                             *
   1154  * OUTPUT:  Returns with a pointer to the cameo imagery for the specified special object.      *
   1155  *                                                                                             *
   1156  * WARNINGS:   none                                                                            *
   1157  *                                                                                             *
   1158  * HISTORY:                                                                                    *
   1159  *   05/19/1995 JLB : commented                                                                *
   1160  *=============================================================================================*/
   1161 void const * SidebarClass::StripClass::Get_Special_Cameo(SpecialWeaponType type)
   1162 {
   1163 	if ((unsigned)type < SPC_COUNT) {
   1164 		return(SpecialShapes[type]);
   1165 	}
   1166 	return(0);
   1167 }
   1168 
   1169 
   1170 /***********************************************************************************************
   1171  * SidebarClass::StripClass::Init_Clear -- Sets sidebar to a known (and deactivated) state     *
   1172  *                                                                                             *
   1173  * INPUT:   none                                                                               *
   1174  *                                                                                             *
   1175  * OUTPUT:  none                                                                               *
   1176  *                                                                                             *
   1177  * WARNINGS:   none                                                                            *
   1178  *                                                                                             *
   1179  * HISTORY:                                                                                    *
   1180  *   12/24/1994 JLB : Created.                                                                 *
   1181  *=============================================================================================*/
   1182 void SidebarClass::StripClass::Init_Clear(void)
   1183 {
   1184 	IsScrollingDown = false;
   1185 	IsScrolling = false;
   1186 	IsBuilding = false;
   1187 	Flasher = -1;
   1188 	TopIndex = 0;
   1189 	Slid = 0;
   1190 	BuildableCount = 0;
   1191 
   1192 	/*
   1193 	** Since we're resetting the strips, clear out all the buildables & factory pointers.
   1194 	*/
   1195 	for (int index = 0; index < MAX_BUILDABLES; index++) {
   1196 		Buildables[index].BuildableID = 0;
   1197 		Buildables[index].BuildableType = RTTI_NONE;
   1198 		Buildables[index].Factory = -1;
   1199 		Buildables[index].BuildableViaCapture = false;		// Added for new sidebar functionality. ST - 9/24/2019 3:10PM 
   1200 	}
   1201 }
   1202 
   1203 
   1204 /***********************************************************************************************
   1205  * SidebarClass::StripClass::Init_IO -- Initializes the strip's buttons                        *
   1206  *                                                                                             *
   1207  * This routine doesn't actually add any buttons to the list.                                  *
   1208  *                                                                                             *
   1209  * INPUT:   none                                                                               *
   1210  *                                                                                             *
   1211  * OUTPUT:  none                                                                               *
   1212  *                                                                                             *
   1213  * WARNINGS:   none                                                                            *
   1214  *                                                                                             *
   1215  * HISTORY:                                                                                    *
   1216  *   12/24/1994 JLB : Created.                                                                 *
   1217  *=============================================================================================*/
   1218 void SidebarClass::StripClass::Init_IO(int id)
   1219 {
   1220 	ID = id;
   1221 
   1222 	UpButton[ID].IsSticky = true;
   1223 	UpButton[ID].ID = BUTTON_UP+id;
   1224 	UpButton[ID].X = X+(UP_X_OFFSET * RESFACTOR);
   1225 	UpButton[ID].Y = Y+(UP_Y_OFFSET * RESFACTOR);
   1226 
   1227 #if (FRENCH)
   1228 #ifdef WIN32
   1229 	UpButton[ID].Set_Shape(MFCD::Retrieve("STRIPUP.SHP"));
   1230 #else
   1231 	UpButton[ID].Set_Shape(MFCD::Retrieve("STUP_FIX.SHP"));
   1232 #endif
   1233 #else	//FRENCH
   1234 	UpButton[ID].Set_Shape(MFCD::Retrieve("STRIPUP.SHP"));
   1235 #endif	//FRENCH
   1236 
   1237 	DownButton[ID].IsSticky = true;
   1238 	DownButton[ID].ID = BUTTON_DOWN+id;
   1239 	DownButton[ID].X = X+(DOWN_X_OFFSET * RESFACTOR);
   1240 	DownButton[ID].Y = Y+(DOWN_Y_OFFSET * RESFACTOR);
   1241 
   1242 	/*
   1243 	** Buttons are in a slightly different position in the new sidebar
   1244 	*/
   1245 	UpButton[ID].Y--;
   1246 	DownButton[ID].Y--;
   1247 
   1248 	DownButton[ID].Set_Shape(MFCD::Retrieve("STRIPDN.SHP"));
   1249 
   1250 	for (int index = 0; index < MAX_VISIBLE; index++) {
   1251 		SelectClass & g = SelectButton[ID][index];
   1252 		g.ID = BUTTON_SELECT;
   1253 		g.X = X;
   1254 		g.Y = Y + ((OBJECT_HEIGHT*index) * RESFACTOR);
   1255 		g.Width = OBJECT_WIDTH * RESFACTOR;
   1256 		g.Height = OBJECT_HEIGHT * RESFACTOR;
   1257 		g.Set_Owner(*this, index);
   1258 	}
   1259 
   1260 }
   1261 
   1262 
   1263 /***********************************************************************************************
   1264  * SidebarClass::StripClass::Init_Theater -- Performs theater-specific initialization          *
   1265  *                                                                                             *
   1266  * INPUT:   theater                                                                            *
   1267  *                                                                                             *
   1268  * OUTPUT:  none                                                                               *
   1269  *                                                                                             *
   1270  * WARNINGS:   none                                                                            *
   1271  *                                                                                             *
   1272  * HISTORY:                                                                                    *
   1273  *   12/24/1994 JLB : Created.                                                                 *
   1274  *=============================================================================================*/
   1275 void SidebarClass::StripClass::Init_Theater(TheaterType theater)
   1276 {
   1277 
   1278 	Reload_LogoShapes();
   1279 
   1280 	if ( (theater != THEATER_NONE) && (theater != ::LastTheater)) {
   1281 
   1282 		static TLucentType const ClockCols[1] = {
   1283 			{GREEN, BLACK, 100, 0}
   1284 //			{GREEN, LTGREY, 180, 0}
   1285 		};
   1286 
   1287 		/*
   1288 		**	Make sure that remapping doesn't occur on the colors that cycle.
   1289 		*/
   1290 		PaletteClass pal = OriginalPalette;
   1291 		memset(&pal[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3);
   1292 		Build_Translucent_Table(pal, &ClockCols[0], 1, (void*)ClockTranslucentTable);
   1293 
   1294 //		Mem_Copy(GamePalette, OriginalPalette, 768);
   1295 //		memset(&GamePalette[CYCLE_COLOR_START*3], 0x3f, CYCLE_COLOR_COUNT*3);
   1296 
   1297 		/*
   1298 		**	Create the translucent table used for the sidebar.
   1299 		*/
   1300 //		Build_Translucent_Table(GamePalette, &ClockCols[0], 1, (void*)ClockTranslucentTable);
   1301 //		GamePalette = OriginalPalette;
   1302 
   1303 		Conquer_Build_Fading_Table(GamePalette, &ClockTranslucentTable[256], BLACK, 100);
   1304 	}
   1305 }
   1306 
   1307 void SidebarClass::StripClass::Reload_LogoShapes(void)
   1308 {
   1309 	/*
   1310 	** Load hi-res strip art here since it is player side specific
   1311 	*/
   1312 	static char * stripnames[]={
   1313 		"stripna.shp",		//Nato
   1314 		"stripna.shp",
   1315 		"stripus.shp",		//USSR
   1316 		"stripna.shp",
   1317 		"stripus.shp",		//UKRAINE
   1318 		"stripna.shp",
   1319 		"stripna.shp",
   1320 		"stripna.shp",
   1321 		"stripna.shp",		//HOUSE_GOOD
   1322 		"stripus.shp",		//HOUSE_BAD
   1323 	};
   1324 	int houseloaded = 0;
   1325 
   1326 	/*
   1327 	** Sidebar art is dependent on the side of the player
   1328 	*/
   1329 
   1330 	if(PlayerPtr) {
   1331 		houseloaded = PlayerPtr->ActLike;
   1332 	}
   1333 	LogoShapes = (void*)MFCD::Retrieve(stripnames[houseloaded]);
   1334 }
   1335 
   1336 /***********************************************************************************************
   1337  * SidebarClass::StripClass::Activate -- Adds the strip buttons to the input system.           *
   1338  *                                                                                             *
   1339  *    This routine will add the side strip buttons to the map's input system. This routine     *
   1340  *    should be called once when the sidebar activates.                                        *
   1341  *                                                                                             *
   1342  * INPUT:   none                                                                               *
   1343  *                                                                                             *
   1344  * OUTPUT:  none                                                                               *
   1345  *                                                                                             *
   1346  * WARNINGS:   Never call this routine a second time without first calling Deactivate().       *
   1347  *                                                                                             *
   1348  * HISTORY:                                                                                    *
   1349  *   01/19/1995 JLB : Created.                                                                 *
   1350  *=============================================================================================*/
   1351 void SidebarClass::StripClass::Activate(void)
   1352 {
   1353 	UpButton[ID].Zap();
   1354 	Map.Add_A_Button(UpButton[ID]);
   1355 
   1356 	DownButton[ID].Zap();
   1357 	Map.Add_A_Button(DownButton[ID]);
   1358 
   1359 	for (int index = 0; index < MAX_VISIBLE; index++) {
   1360 		SelectButton[ID][index].Zap();
   1361 		Map.Add_A_Button(SelectButton[ID][index]);
   1362 	}
   1363 }
   1364 
   1365 
   1366 /***********************************************************************************************
   1367  * SidebarClass::StripClass::Deactivate -- Removes the side strip buttons from the input syste *
   1368  *                                                                                             *
   1369  *    Call this routine to remove all the buttons on the side strip from the map's input       *
   1370  *    system.                                                                                  *
   1371  *                                                                                             *
   1372  * INPUT:   none                                                                               *
   1373  *                                                                                             *
   1374  * OUTPUT:  none                                                                               *
   1375  *                                                                                             *
   1376  * WARNINGS:   Never call this routine unless the Activate() function was previously called.   *
   1377  *                                                                                             *
   1378  * HISTORY:                                                                                    *
   1379  *   01/19/1995 JLB : Created.                                                                 *
   1380  *=============================================================================================*/
   1381 void SidebarClass::StripClass::Deactivate(void)
   1382 {
   1383 	Map.Remove_A_Button(UpButton[ID]);
   1384 	Map.Remove_A_Button(DownButton[ID]);
   1385 	for (int index = 0; index < MAX_VISIBLE; index++) {
   1386 		Map.Remove_A_Button(SelectButton[ID][index]);
   1387 	}
   1388 }
   1389 
   1390 
   1391 /***********************************************************************************************
   1392  * SidebarClass::StripClass::Add -- Add an object to the side strip.                           *
   1393  *                                                                                             *
   1394  *    Use this routine to add a buildable object to the side strip.                            *
   1395  *                                                                                             *
   1396  * INPUT:   object   -- Pointer to the object type that can be built and is to be added to     *
   1397  *                      the side strip.                                                        *
   1398  *                                                                                             *
   1399  * OUTPUT:  bool; Was the object successfully added to the side strip? Failure could be the    *
   1400  *                result of running out of room in the side strip array or the object might    *
   1401  *                already be in the list.                                                      *
   1402  *                                                                                             *
   1403  * WARNINGS:   none.                                                                           *
   1404  *                                                                                             *
   1405  * HISTORY:                                                                                    *
   1406  *   12/31/1994 JLB : Created.                                                                 *
   1407  *   9/24/2019 3:17PM : Added via capture parameter for new sidebar functionality              *
   1408  *=============================================================================================*/
   1409 bool SidebarClass::StripClass::Add(RTTIType type, int id, bool via_capture)
   1410 {
   1411 	if (BuildableCount <= MAX_BUILDABLES) {
   1412 		for (int index = 0; index < BuildableCount; index++) {
   1413 			if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
   1414 				return(false);
   1415 			}
   1416 		}
   1417 		if (!ScenarioInit && type != RTTI_SPECIAL) {
   1418 			Speak(VOX_NEW_CONSTRUCT);
   1419 		}
   1420 		Buildables[BuildableCount].BuildableType = type;
   1421 		Buildables[BuildableCount].BuildableID = id;
   1422 		Buildables[BuildableCount].BuildableViaCapture = via_capture;
   1423 		BuildableCount++;
   1424 		IsToRedraw = true;
   1425 		return(true);
   1426 	}
   1427 	return(false);
   1428 }
   1429 
   1430 
   1431 /***********************************************************************************************
   1432  * SidebarClass::StripClass::Scroll -- Causes the side strip to scroll.                        *
   1433  *                                                                                             *
   1434  *    Use this routine to flag the side strip to scroll. The direction scrolled is controlled  *
   1435  *    by the parameter. Scrolling is merely initiated by this routine. Subsequent calls to     *
   1436  *    the AI function and the Draw_It function are required to properly give the appearance    *
   1437  *    of scrolling.                                                                            *
   1438  *                                                                                             *
   1439  * INPUT:   bool; Should the side strip scroll UP? If it is to scroll down then pass false.    *
   1440  *                                                                                             *
   1441  * OUTPUT:  bool; Was the side strip started to scroll in the desired direction?               *
   1442  *                                                                                             *
   1443  * WARNINGS:   none                                                                            *
   1444  *                                                                                             *
   1445  * HISTORY:                                                                                    *
   1446  *   12/31/1994 JLB : Created.                                                                 *
   1447  *   07/29/1995 JLB : Simplified scrolling logic.                                              *
   1448  *=============================================================================================*/
   1449 bool SidebarClass::StripClass::Scroll(bool up)
   1450 {
   1451 	if (up) {
   1452 		if (!TopIndex) return(false);
   1453 		Scroller--;
   1454 	} else {
   1455 		if (TopIndex+MAX_VISIBLE >= BuildableCount) return(false);
   1456 		Scroller++;
   1457 	}
   1458 	return(true);
   1459 }
   1460 
   1461 
   1462 /***********************************************************************************************
   1463  * SidebarClass::StripClass::Flag_To_Redra -- Flags the sidebar strip to be redrawn.           *
   1464  *                                                                                             *
   1465  *    This utility routine is called when something changes on the sidebar and it must be      *
   1466  *    reflected the next time drawing is performed.                                            *
   1467  *                                                                                             *
   1468  * INPUT:   none                                                                               *
   1469  *                                                                                             *
   1470  * OUTPUT:  none                                                                               *
   1471  *                                                                                             *
   1472  * WARNINGS:   none                                                                            *
   1473  *                                                                                             *
   1474  * HISTORY:                                                                                    *
   1475  *   05/18/1995 JLB : Created.                                                                 *
   1476  *=============================================================================================*/
   1477 void SidebarClass::StripClass::Flag_To_Redraw(void)
   1478 {
   1479 	IsToRedraw = true;
   1480 	//Map.SidebarClass::IsToRedraw = true;
   1481 	Map.Flag_To_Redraw(false);
   1482 }
   1483 
   1484 
   1485 /***********************************************************************************************
   1486  * SidebarClass::StripClass::AI -- Input and AI processing for the side strip.                 *
   1487  *                                                                                             *
   1488  *    The side strip AI processing is performed by this function. This function not only       *
   1489  *    checks for player input, but also handles any graphic logic updating necessary as a      *
   1490  *    result of flashing or construction animation.                                            *
   1491  *                                                                                             *
   1492  * INPUT:   input -- The player input code.                                                    *
   1493  *                                                                                             *
   1494  *          x,y   -- Mouse coordinate to use.                                                  *
   1495  *                                                                                             *
   1496  * OUTPUT:  bool; Did the AI detect that it will need a rendering change? If this routine      *
   1497  *                returns true, then the Draw_It function should be called at the              *
   1498  *                earliest opportunity.                                                        *
   1499  *                                                                                             *
   1500  * WARNINGS:   none                                                                            *
   1501  *                                                                                             *
   1502  * HISTORY:                                                                                    *
   1503  *   12/31/1994 JLB : Created.                                                                 *
   1504  *   12/31/1994 JLB : Uses mouse coordinate parameters.                                        *
   1505  *=============================================================================================*/
   1506 bool SidebarClass::StripClass::AI(KeyNumType & input, int , int )
   1507 {
   1508 	bool redraw = false;
   1509 
   1510 	/*
   1511 	**	If this is scroll button for this side strip, then scroll the strip as
   1512 	**	indicated.
   1513 	*/
   1514 	if (input == (UpButton[ID].ID|KN_BUTTON)) {	// && !IsScrolling
   1515 		UpButton[ID].IsPressed = false;
   1516 		if (!Scroll(true)) {
   1517 			Sound_Effect(VOC_SCOLD);
   1518 		}
   1519 	}
   1520 	if (input == (DownButton[ID].ID|KN_BUTTON)) {	// && !IsScrolling
   1521 		DownButton[ID].IsPressed = false;
   1522 		if (!Scroll(false)) {
   1523 			Sound_Effect(VOC_SCOLD);
   1524 		}
   1525 	}
   1526 
   1527 	/*
   1528 	**	Reflect the scroll desired direction/value into the scroll
   1529 	**	logic handler. This might result in up or down scrolling.
   1530 	*/
   1531 	if (!IsScrolling && Scroller) {
   1532 		if (BuildableCount <= MAX_VISIBLE) {
   1533 			Scroller = 0;
   1534 		} else {
   1535 
   1536 			/*
   1537 			**	Top of list is moving toward lower ordered entries in the object list. It looks like
   1538 			**	the "window" to the object list is moving up even though the actual object images are
   1539 			**	scrolling downward.
   1540 			*/
   1541 			if (Scroller < 0) {
   1542 				if (!TopIndex) {
   1543 					Scroller = 0;
   1544 				} else {
   1545 					Scroller++;
   1546 					IsScrollingDown = false;
   1547 					IsScrolling = true;
   1548 					TopIndex--;
   1549 					Slid = 0;
   1550 				}
   1551 
   1552 			} else {
   1553 				if (TopIndex+MAX_VISIBLE >= BuildableCount) {
   1554 					Scroller = 0;
   1555 				} else {
   1556 					Scroller--;
   1557 					Slid = OBJECT_HEIGHT;
   1558 					IsScrollingDown = true;
   1559 					IsScrolling = true;
   1560 				}
   1561 			}
   1562 		}
   1563 	}
   1564 
   1565 	/*
   1566 	**	Scroll logic is handled here.
   1567 	*/
   1568 	if (IsScrolling) {
   1569 		if (IsScrollingDown) {
   1570 			Slid -= SCROLL_RATE;
   1571 			if (Slid <= 0) {
   1572 				IsScrolling = false;
   1573 				Slid = 0;
   1574 				TopIndex++;
   1575 			}
   1576 		} else {
   1577 			Slid += SCROLL_RATE;
   1578 			if (Slid >= OBJECT_HEIGHT) {
   1579 				IsScrolling = false;
   1580 				Slid = 0;
   1581 			}
   1582 		}
   1583 		redraw = true;
   1584 	}
   1585 
   1586 	/*
   1587 	**	Handle any flashing logic. Flashing occurs when the player selects an object
   1588 	**	and provides the visual feedback of a recognized and legal selection.
   1589 	*/
   1590 	if (Flasher != -1) {
   1591 		if (Graphic_Logic()) {
   1592 			redraw = true;
   1593 			if (Fetch_Stage() >= 7) {
   1594 				Set_Rate(0);
   1595 				Set_Stage(0);
   1596 				Flasher = -1;
   1597 			}
   1598 		}
   1599 	}
   1600 
   1601 	/*
   1602 	**	Handle any building clock animation logic.
   1603 	*/
   1604 	if (IsBuilding) {
   1605 		for (int index = 0; index < BuildableCount; index++) {
   1606 			int factoryid = Buildables[index].Factory;
   1607 
   1608 			if (factoryid != -1) {
   1609 				FactoryClass * factory = Factories.Raw_Ptr(factoryid);
   1610 
   1611 				if (factory && (factory->Has_Changed() || factory->Is_Blocked())) {
   1612 					redraw = true;
   1613 					if (factory->Has_Completed()) {
   1614 
   1615 						/*
   1616 						**	Construction has been completed. Announce this fact to the player and
   1617 						**	try to get the object to automatically leave the factory. Buildings are
   1618 						**	the main exception to the ability to leave the factory under their own
   1619 						**	power.
   1620 						*/
   1621 						TechnoClass * pending = factory->Get_Object();
   1622 						if (pending != NULL) {
   1623 							switch (pending->What_Am_I()) {
   1624 								case RTTI_VESSEL:
   1625 								case RTTI_UNIT:
   1626 								case RTTI_AIRCRAFT:
   1627 									OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
   1628 									if (!factory->Is_Blocked()) {
   1629 										Speak(VOX_UNIT_READY);
   1630 									}
   1631 									break;
   1632 
   1633 								case RTTI_BUILDING:
   1634 									Speak(VOX_CONSTRUCTION);
   1635 									break;
   1636 
   1637 								case RTTI_INFANTRY:
   1638 									OutList.Add(EventClass(EventClass::PLACE, pending->What_Am_I(), -1));
   1639 									if (!factory->Is_Blocked()) {
   1640 										Speak(VOX_UNIT_READY);
   1641 									}
   1642 									break;
   1643 							}
   1644 						}
   1645 					}
   1646 				}
   1647 			}
   1648 		}
   1649 	}
   1650 
   1651 	/*
   1652 	**	If any of the logic determined that this side strip needs to be redrawn, then
   1653 	**	set the redraw flag for this side strip.
   1654 	*/
   1655 	if (redraw) {
   1656 		Flag_To_Redraw();
   1657 	}
   1658 	return(redraw);
   1659 }
   1660 
   1661 
   1662 /***********************************************************************************************
   1663  * SidebarClass::StripClass::Draw_It -- Render the sidebar display.                            *
   1664  *                                                                                             *
   1665  *    Use this routine to render the sidebar display. It checks to see if it needs to be       *
   1666  *    redrawn and only redraw if necessary. If the "complete" parameter is true, then it       *
   1667  *    will force redraw the entire strip.                                                      *
   1668  *                                                                                             *
   1669  * INPUT:   complete -- Should the redraw be forced? A force redraw will ignore the redraw     *
   1670  *                      flag.                                                                  *
   1671  *                                                                                             *
   1672  * OUTPUT:  none                                                                               *
   1673  *                                                                                             *
   1674  * WARNINGS:   none                                                                            *
   1675  *                                                                                             *
   1676  * HISTORY:                                                                                    *
   1677  *   12/31/1994 JLB : Created.                                                                 *
   1678  *   08/06/1995 JLB : Handles multi factory tracking in same strip.                            *
   1679  *=============================================================================================*/
   1680 void SidebarClass::StripClass::Draw_It(bool complete)
   1681 {
   1682 	if (IsToRedraw || complete) {
   1683 		IsToRedraw = false;
   1684 
   1685 		if (RunningAsDLL) {
   1686 			return;
   1687 		}
   1688 
   1689 		SidebarRedraws++;
   1690 
   1691 		/*
   1692 		**	Fills the background to the side strip. We shouldnt need to do this if the strip
   1693 		** has a full complement of icons.
   1694 		*/
   1695 		/*
   1696 		** New sidebar needs to be drawn not filled
   1697 		*/
   1698 		if (BuildableCount < MAX_VISIBLE) {
   1699 			CC_Draw_Shape(LogoShapes, ID,	X+(2*RESFACTOR),	Y,	WINDOW_MAIN, SHAPE_WIN_REL|SHAPE_NORMAL,	0);
   1700 		}
   1701 
   1702 		/*
   1703 		**	Redraw the scroll buttons.
   1704 		*/
   1705 		UpButton[ID].Draw_Me(true);
   1706 		DownButton[ID].Draw_Me(true);
   1707 
   1708 		/*
   1709 		**	Loop through all the buildable objects that are visible in the strip and render
   1710 		**	them. Their Y offset may be adjusted if the strip is in the process of scrolling.
   1711 		*/
   1712 		for (int i = 0; i < MAX_VISIBLE + (IsScrolling ? 1 : 0); i++) {
   1713 			bool production;
   1714 			bool completed;
   1715 			int  stage;
   1716 			bool darken = false;
   1717 			void const * shapefile = 0;
   1718 			int shapenum = 0;
   1719 			void const * remapper = 0;
   1720 			FactoryClass * factory = 0;
   1721 			int index = i+TopIndex;
   1722 			int x = X;
   1723 			int y = Y + (i*OBJECT_HEIGHT * RESFACTOR);
   1724 
   1725 			/*
   1726 			**	If the strip is scrolling, then the offset is adjusted accordingly.
   1727 			*/
   1728 			if (IsScrolling) {
   1729 				y -= (OBJECT_HEIGHT - Slid)  * RESFACTOR;
   1730 //				y -= OBJECT_HEIGHT - Slid;
   1731 			}
   1732 
   1733 			/*
   1734 			**	Fetch the shape number for the object type located at this current working
   1735 			**	slot. This shape pointer is used to draw the underlying graphic there.
   1736 			*/
   1737 			if (index < BuildableCount) {
   1738 				ObjectTypeClass const * obj = NULL;
   1739 				SpecialWeaponType spc = SPC_NONE;
   1740 
   1741 				if (Buildables[index].BuildableType != RTTI_SPECIAL) {
   1742 
   1743 					obj = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
   1744 					if (obj != NULL) {
   1745 
   1746 						/*
   1747 						**	Fetch the remap table that is appropriate for this object
   1748 						**	type.
   1749 						*/
   1750 						remapper = PlayerPtr->Remap_Table(false, ((TechnoTypeClass const *)obj)->Remap);
   1751 
   1752 						/*
   1753 						**	If there is already a factory producing this kind of object, then all
   1754 						**	objects of this type are displays in a disabled state.
   1755 						*/
   1756 						bool isbusy = (PlayerPtr->Fetch_Factory(Buildables[index].BuildableType) != NULL);
   1757 						if (!isbusy && PlayerPtr->Is_Hack_Prevented(Buildables[index].BuildableType, Buildables[index].BuildableID)) {
   1758 							isbusy = true;
   1759 						}
   1760 
   1761 						/*
   1762 						**	Infantry don't get remapped in the sidebar (special case).
   1763 						*/
   1764 						if (Buildables[index].BuildableType == RTTI_INFANTRYTYPE) {
   1765 							remapper = 0;
   1766 						}
   1767 
   1768 						shapefile = obj->Get_Cameo_Data();
   1769 						shapenum  = 0;
   1770 						if (Buildables[index].Factory != -1) {
   1771 							factory 		= Factories.Raw_Ptr(Buildables[index].Factory);
   1772 							production	= true;
   1773 							completed	= factory->Has_Completed();
   1774 							stage			= factory->Completion();
   1775 							darken		= false;
   1776 						} else {
   1777 							production  = false;
   1778 //							darken      = IsBuilding;
   1779 
   1780 							/*
   1781 							**	Darken the imagery if a factory of a matching type is
   1782 							**	already busy.
   1783 							*/
   1784 							darken = isbusy;
   1785 						}
   1786 					} else {
   1787 						darken = PlayerPtr->Is_Hack_Prevented(Buildables[index].BuildableType, Buildables[index].BuildableID);
   1788 					}
   1789 
   1790 				} else  {
   1791 
   1792 					spc = SpecialWeaponType(Buildables[index].BuildableID);
   1793 					shapefile = Get_Special_Cameo(spc);
   1794 					shapenum = 0;
   1795 
   1796 					production = true;
   1797 					completed = PlayerPtr->SuperWeapon[spc].Is_Ready();
   1798 					stage = PlayerPtr->SuperWeapon[spc].Anim_Stage();
   1799 					darken = false;
   1800 				}
   1801 
   1802 				if (obj != NULL || spc != SPC_NONE) {
   1803 					/*
   1804 					** If this item is flashing then take care of it.
   1805 					**
   1806 					*/
   1807 					if (Flasher == index && (Fetch_Stage() & 0x01)) {
   1808 						remapper = Map.FadingLight;
   1809 					}
   1810 
   1811 				} else {
   1812 					shapefile	= LogoShapes;
   1813 					if (!darken) {
   1814 						shapenum		= SB_BLANK;
   1815 					}
   1816 				}
   1817 			} else {
   1818 				shapefile	= LogoShapes;
   1819 				shapenum		= SB_BLANK;
   1820 				production	= false;
   1821 			}
   1822 
   1823 			remapper = 0;
   1824 			/*
   1825 			**	Now that the shape of the object at the current working slot has been found,
   1826 			**	draw it and any graphic overlays as necessary.
   1827 			**
   1828 			** Don't draw blank shapes over the new 640x400 sidebar art - ST 5/1/96 6:01PM
   1829 			*/
   1830 			if (shapenum != SB_BLANK || shapefile != LogoShapes) {
   1831 				CC_Draw_Shape(shapefile, shapenum,
   1832 					x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
   1833 					y-WindowList[WINDOW_SIDEBAR][WINDOWY],
   1834 					WINDOW_SIDEBAR,
   1835 					SHAPE_NORMAL|SHAPE_WIN_REL| (remapper ? SHAPE_FADING : SHAPE_NORMAL),
   1836 					remapper);
   1837 
   1838 				/*
   1839 				**	Darken this object because it cannot be produced or is otherwise
   1840 				**	unavailable.
   1841 				*/
   1842 				if (darken) {
   1843 					CC_Draw_Shape(ClockShapes, 0,
   1844 							x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
   1845 							y-WindowList[WINDOW_SIDEBAR][WINDOWY],
   1846 							WINDOW_SIDEBAR,
   1847 							SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
   1848 							NULL, ClockTranslucentTable);
   1849 				}
   1850 			}
   1851 
   1852 			/*
   1853 			**	Draw the overlapping clock shape if this is object is being constructed.
   1854 			**	If the object is completed, then display "Ready" with no clock shape.
   1855 			*/
   1856 			if (production) {
   1857 				if (completed) {
   1858 
   1859 					/*
   1860 					**	Display text showing that the object is ready to place.
   1861 					*/
   1862 					CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_READY,
   1863 					(x-(WindowList[WINDOW_SIDEBAR][WINDOWX]))+(LEFT_EDGE_OFFSET+15) * RESFACTOR,
   1864 					(y-WindowList[WINDOW_SIDEBAR][WINDOWY])+(4 * RESFACTOR),
   1865 					WINDOW_SIDEBAR, SHAPE_CENTER);
   1866 				} else {
   1867 
   1868 					CC_Draw_Shape(ClockShapes, stage+1,
   1869 							x-(WindowList[WINDOW_SIDEBAR][WINDOWX])+(LEFT_EDGE_OFFSET * RESFACTOR),
   1870 							y-WindowList[WINDOW_SIDEBAR][WINDOWY],
   1871 							WINDOW_SIDEBAR,
   1872 							SHAPE_NORMAL|SHAPE_WIN_REL|SHAPE_GHOST,
   1873 							NULL, ClockTranslucentTable);
   1874 
   1875 					/*
   1876 					**	Display text showing that the construction is temporarily on hold.
   1877 					*/
   1878 					if (factory && !factory->Is_Building()) {
   1879 						CC_Draw_Shape(ObjectTypeClass::PipShapes, PIP_HOLDING,
   1880 						(x-(WindowList[WINDOW_SIDEBAR][WINDOWX])) + ((LEFT_EDGE_OFFSET+15) * RESFACTOR),
   1881 						(y-WindowList[WINDOW_SIDEBAR][WINDOWY])+(4 * RESFACTOR),
   1882 						WINDOW_SIDEBAR, SHAPE_CENTER);
   1883 					}
   1884 				}
   1885 			}
   1886 
   1887 		}
   1888 
   1889 		LastSlid = Slid;
   1890 	}
   1891 }
   1892 
   1893 
   1894 /***********************************************************************************************
   1895  * SidebarClass::StripClass::Recalc -- Revalidates the current sidebar list of objects.        *
   1896  *                                                                                             *
   1897  *    This routine will revalidate all the buildable objects in the sidebar. This routine      *
   1898  *    comes in handy when a factory has been destroyed, and the sidebar needs to reflect any   *
   1899  *    change that this requires. It checks every object to see if there is a factory available *
   1900  *    that could produce it. If none can be found, then the object is removed from the         *
   1901  *    sidebar.                                                                                 *
   1902  *                                                                                             *
   1903  * INPUT:   none                                                                               *
   1904  *                                                                                             *
   1905  * OUTPUT:  bool; The sidebar has changed as a result of this call?                            *
   1906  *                                                                                             *
   1907  * WARNINGS:   none                                                                            *
   1908  *                                                                                             *
   1909  * HISTORY:                                                                                    *
   1910  *   01/19/1995 JLB : Created.                                                                 *
   1911  *   06/26/1995 JLB : Doesn't collapse sidebar when buildables removed.                        *
   1912  *=============================================================================================*/
   1913 bool SidebarClass::StripClass::Recalc(void)
   1914 {
   1915 	int ok;
   1916 
   1917 	if (Debug_Map || !BuildableCount) {
   1918 		return(false);
   1919 	}
   1920 
   1921 	/*
   1922 	**	Sweep through all objects listed in the sidebar. If any of those object can
   1923 	**	not be created -- even in theory -- then they must be removed form the sidebar and
   1924 	**	any current production must be abandoned.
   1925 	*/
   1926 	bool redraw = false;
   1927 	for (int index = 0; index < BuildableCount; index++) {
   1928 		TechnoTypeClass const * tech = Fetch_Techno_Type(Buildables[index].BuildableType, Buildables[index].BuildableID);
   1929 		if (tech != NULL) {
   1930 			ok = tech->Who_Can_Build_Me(true, false, PlayerPtr->Class->House) != NULL;
   1931 		} else {
   1932 			if ((unsigned)Buildables[index].BuildableID < SPC_COUNT) {
   1933 				ok = PlayerPtr->SuperWeapon[Buildables[index].BuildableID].Is_Present();
   1934 			} else {
   1935 				ok = false;
   1936 			}
   1937 		}
   1938 
   1939 		if (!ok) {
   1940 
   1941 			/*
   1942 			**	Removes this entry from the list.
   1943 			*/
   1944 			if (BuildableCount > 1 && index < BuildableCount-1) {
   1945 				memcpy(&Buildables[index], &Buildables[index+1], sizeof(Buildables[0])*((BuildableCount-index)-1));
   1946 			}
   1947 			TopIndex = 0;
   1948 			IsToRedraw = true;
   1949 			redraw = true;
   1950 			BuildableCount--;
   1951 			index--;
   1952 		}
   1953 	}
   1954 
   1955 #ifdef NEVER
   1956 	/*
   1957 	**	If there are no more buildable objects to display, make the sidebar go away.
   1958 	*/
   1959 	if (!BuildableCount) {
   1960 		Map.SidebarClass::Activate(0);
   1961 	}
   1962 #endif
   1963 	return(redraw);
   1964 }
   1965 
   1966 
   1967 /***********************************************************************************************
   1968  * SidebarClass::StripClass::SelectClass::SelectClass -- Default constructor.                  *
   1969  *                                                                                             *
   1970  *    This is the default constructor for the button that controls the buildable cameos on     *
   1971  *    the sidebar strip.                                                                       *
   1972  *                                                                                             *
   1973  * INPUT:   none                                                                               *
   1974  *                                                                                             *
   1975  * OUTPUT:  none                                                                               *
   1976  *                                                                                             *
   1977  * WARNINGS:   The coordinates are set to zero by this routine. They must be set to the        *
   1978  *             correct values before this button will function.                                *
   1979  *                                                                                             *
   1980  * HISTORY:                                                                                    *
   1981  *   01/19/1995 JLB : Created.                                                                 *
   1982  *=============================================================================================*/
   1983 SidebarClass::StripClass::SelectClass::SelectClass(void) :
   1984 	ControlClass(0, 0, 0, (OBJECT_WIDTH-1) * RESFACTOR, OBJECT_HEIGHT * RESFACTOR, LEFTPRESS|RIGHTPRESS|LEFTUP),
   1985 	Strip(0),
   1986 	Index(0)
   1987 {
   1988 }
   1989 
   1990 
   1991 /***********************************************************************************************
   1992  * SidebarClass::StripClass::SelectClass:: -- Assigns special values to a buildable select but *
   1993  *                                                                                             *
   1994  *    Use this routine to set custom buildable vars for this particular select button. It      *
   1995  *    uses this information to properly know what buildable object to start or stop production *
   1996  *    on.                                                                                      *
   1997  *                                                                                             *
   1998  * INPUT:   strip    -- Reference to the strip that owns this buildable button.                *
   1999  *                                                                                             *
   2000  *          index    -- The index (0 .. MAX_VISIBLE-1) of this button. This is used to let     *
   2001  *                      the owning strip know what index this button refers to.                *
   2002  *                                                                                             *
   2003  * OUTPUT:  none                                                                               *
   2004  *                                                                                             *
   2005  * WARNINGS:   none                                                                            *
   2006  *                                                                                             *
   2007  * HISTORY:                                                                                    *
   2008  *   01/19/1995 JLB : Created.                                                                 *
   2009  *=============================================================================================*/
   2010 void SidebarClass::StripClass::SelectClass::Set_Owner(StripClass & strip, int index)
   2011 {
   2012 	Strip = &strip;
   2013 	Index = index;
   2014 	X = strip.X;
   2015 	Y = strip.Y + ((index * OBJECT_HEIGHT) * RESFACTOR);
   2016 }
   2017 
   2018 
   2019 /***********************************************************************************************
   2020  * SidebarClass::StripClass::SelectClass:: -- Action function when buildable cameo is selected *
   2021  *                                                                                             *
   2022  *    This function is called when the buildable icon (cameo) is clicked on. It handles        *
   2023  *    starting and stopping production as indicated.                                           *
   2024  *                                                                                             *
   2025  * INPUT:   flags -- The input event that triggered the call.                                  *
   2026  *                                                                                             *
   2027  *          key   -- The keyboard value at the time of the input.                              *
   2028  *                                                                                             *
   2029  * OUTPUT:  Returns with whether the input list should be scanned further.                     *
   2030  *                                                                                             *
   2031  * WARNINGS:   none                                                                            *
   2032  *                                                                                             *
   2033  * HISTORY:                                                                                    *
   2034  *   01/19/1995 JLB : Created.                                                                 *
   2035  *   10/09/1996 JLB : Sonar pulse converted to regular event type.                             *
   2036  *=============================================================================================*/
   2037 int SidebarClass::StripClass::SelectClass::Action(unsigned flags, KeyNumType & key)
   2038 {
   2039 	int index = Strip->TopIndex + Index;
   2040 	RTTIType otype = Strip->Buildables[index].BuildableType;
   2041 	int oid = Strip->Buildables[index].BuildableID;
   2042 	int fnumber = Strip->Buildables[index].Factory;
   2043 	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
   2044 
   2045 	ObjectTypeClass const * choice = NULL;
   2046 	SpecialWeaponType spc = SPC_NONE;
   2047 
   2048 	/*
   2049 	**	Determine the factory number that would apply to objects of the type
   2050 	**	the mouse is currently addressing. This doesn't mean that the factory number
   2051 	**	fetched is actually producing the indicated object, merely that that particular
   2052 	**	kind of factory is specified by the "genfactory" value. This can be used to see
   2053 	**	if the factory type is currently busy or not.
   2054 	*/
   2055 	FactoryClass * factory = PlayerPtr->Fetch_Factory(otype);
   2056 
   2057 	Map.Override_Mouse_Shape(MOUSE_NORMAL);
   2058 
   2059 	if (index < Strip->BuildableCount) {
   2060 		if (otype != RTTI_SPECIAL) {
   2061 			choice  = Fetch_Techno_Type(otype, oid);
   2062 		} else {
   2063 			spc = SpecialWeaponType(oid);
   2064 		}
   2065 
   2066 		if (fnumber != -1) {
   2067 			factory = Factories.Raw_Ptr(fnumber);
   2068 		}
   2069 
   2070   	} else {
   2071   		Map.Help_Text(TXT_NONE);
   2072   	}
   2073 
   2074 	if (spc != SPC_NONE) {
   2075 
   2076 		/*
   2077 		**	Display the help text if the mouse is over the button.
   2078 		*/
   2079 		if (flags & LEFTUP) {
   2080 			Map.Help_Text(SpecialWeaponHelp[spc], X, Y, scheme->Color, true);
   2081 			flags &= ~LEFTUP;
   2082 		}
   2083 
   2084 		/*
   2085 		**	A right mouse button signals "cancel".  If we are in targeting
   2086 		** mode then we don't want to be any more.
   2087 		*/
   2088 		if (flags & RIGHTPRESS) {
   2089 			Map.IsTargettingMode = SPC_NONE;
   2090 		}
   2091 		/*
   2092 		**	A left mouse press signal "activate".  If our weapon type is
   2093 		** available then we should activate it.
   2094 		*/
   2095 		if (flags & LEFTPRESS) {
   2096 
   2097 			if ((unsigned)spc < SPC_COUNT) {
   2098 				if (PlayerPtr->SuperWeapon[spc].Is_Ready()) {
   2099 					if (spc != SPC_SONAR_PULSE) {
   2100 						Map.IsTargettingMode = spc;
   2101 						Unselect_All();
   2102 						Speak(VOX_SELECT_TARGET);
   2103 					} else {
   2104 						OutList.Add(EventClass(EventClass::SPECIAL_PLACE, SPC_SONAR_PULSE, 0));
   2105 					}
   2106 				} else {
   2107 					PlayerPtr->SuperWeapon[spc].Impatient_Click();
   2108 				}
   2109 			}
   2110 		}
   2111 
   2112 	} else {
   2113 
   2114 		if (choice != NULL) {
   2115 
   2116 			/*
   2117 			**	Display the help text if the mouse is over the button.
   2118 			*/
   2119 			if (flags & LEFTUP) {
   2120 				Map.Help_Text(choice->Full_Name(), X, Y, scheme->Color, true);
   2121 				Map.Set_Cost(choice->Cost_Of() * PlayerPtr->CostBias);
   2122 				flags &= ~LEFTUP;
   2123 			}
   2124 
   2125 			/*
   2126 			**	A right mouse button signals "cancel".
   2127 			*/
   2128 			if (flags & RIGHTPRESS) {
   2129 
   2130 				/*
   2131 				**	If production is in progress, put it on hold. If production is already
   2132 				**	on hold, then abandon it. Money will be refunded, the factory
   2133 				**	manager deleted, and the object under construction is returned to
   2134 				**	the free pool.
   2135 				*/
   2136 				if (factory != NULL) {
   2137 
   2138 					/*
   2139 					**	Cancels placement mode if the sidebar factory is abandoned or
   2140 					**	suspended.
   2141 					*/
   2142 					if (Map.PendingObjectPtr && Map.PendingObjectPtr->Is_Techno()) {
   2143 						Map.PendingObjectPtr = 0;
   2144 						Map.PendingObject = 0;
   2145 						Map.PendingHouse = HOUSE_NONE;
   2146 						Map.Set_Cursor_Shape(0);
   2147 					}
   2148 
   2149 					if (!factory->Is_Building()) {
   2150 						Speak(VOX_CANCELED);
   2151 						OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
   2152 					} else {
   2153 						Speak(VOX_SUSPENDED);
   2154 						OutList.Add(EventClass(EventClass::SUSPEND, otype, oid));
   2155 						Map.Column[0].IsToRedraw = true;
   2156 						Map.Column[1].IsToRedraw = true;
   2157 					}
   2158 				}
   2159 			}
   2160 
   2161 			if (flags & LEFTPRESS) {
   2162 
   2163 				/*
   2164 				**	If there is already a factory attached to this strip but the player didn't click
   2165 				**	on the icon that has the attached factory, then say that the factory is busy and
   2166 				**	ignore the click.
   2167 				*/
   2168 				if (fnumber == -1 && factory != NULL) {
   2169 					Speak(VOX_NO_FACTORY);
   2170 					ControlClass::Action(flags, key);
   2171 					return(true);
   2172 				}
   2173 
   2174 				if (factory != NULL) {
   2175 
   2176 					/*
   2177 					**	If this object is currently being built, then give a scold sound and text and then
   2178 					**	bail.
   2179 					*/
   2180 					if (factory->Is_Building()) {
   2181 						Speak(VOX_NO_FACTORY);
   2182 					} else {
   2183 
   2184 						/*
   2185 						**	If production has completed, then attempt to have the object exit
   2186 						**	the factory or go into placement mode.
   2187 						*/
   2188 						if (factory->Has_Completed()) {
   2189 
   2190 							TechnoClass * pending = factory->Get_Object();
   2191 							if (!pending && factory->Get_Special_Item()) {
   2192 								Map.IsTargettingMode = SPC_ANY;
   2193 							} else {
   2194 								BuildingClass * builder = pending->Who_Can_Build_Me(false, false);
   2195 								if (!builder) {
   2196 									OutList.Add(EventClass(EventClass::ABANDON, otype, oid));
   2197 									Speak(VOX_NO_FACTORY);
   2198 								} else {
   2199 
   2200 									/*
   2201 									**	If the completed object is a building, then change the
   2202 									**	game state into building placement mode. This fact is
   2203 									**	not transmitted to any linked computers until the moment
   2204 									**	the building is actually placed down.
   2205 									*/
   2206 									if (pending->What_Am_I() == RTTI_BUILDING) {
   2207 								 		PlayerPtr->Manual_Place(builder, (BuildingClass *)pending);
   2208 									} else {
   2209 
   2210 										/*
   2211 										**	For objects that can leave the factory under their own
   2212 										**	power, queue this event and process through normal house
   2213 										**	production channels.
   2214 										*/
   2215 										OutList.Add(EventClass(EventClass::PLACE, otype, -1));
   2216 									}
   2217 								}
   2218 							}
   2219 						} else {
   2220 
   2221 							if (PlayerPtr->Is_Hack_Prevented(otype, oid)) {
   2222 								// Eva scolds the player here.
   2223 							} else {
   2224 								/*
   2225 								**	The factory must have been in a suspended state. Resume construction
   2226 								**	normally.
   2227 								*/
   2228 								if (otype == RTTI_INFANTRYTYPE) {
   2229 									Speak(VOX_TRAINING);
   2230 								} else {
   2231 									Speak(VOX_BUILDING);
   2232 								}
   2233 								OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
   2234 							}
   2235 						}
   2236 					}
   2237 
   2238 				} else {
   2239 
   2240 					if (PlayerPtr->Is_Hack_Prevented(otype, oid)) {
   2241 						// Eva scolds the player here.
   2242 					} else {
   2243 
   2244 						/*
   2245 						**	If this side strip is already busy with production, then ignore the
   2246 						**	input and announce this fact.
   2247 						*/
   2248 						if (otype == RTTI_INFANTRYTYPE) {
   2249 							Speak(VOX_TRAINING);
   2250 						} else {
   2251 							Speak(VOX_BUILDING);
   2252 						}
   2253 						OutList.Add(EventClass(EventClass::PRODUCE, Strip->Buildables[index].BuildableType, Strip->Buildables[index].BuildableID));
   2254 					}
   2255 				}
   2256 			}
   2257 		} else {
   2258 			flags = 0;
   2259 		}
   2260 	}
   2261 
   2262 	ControlClass::Action(flags, key);
   2263 	return(true);
   2264 }
   2265 
   2266 
   2267 /***********************************************************************************************
   2268  * SidebarClass::SBGadgetClass::Action -- Special function that controls the mouse over the si *
   2269  *                                                                                             *
   2270  *    This routine is called whenever the mouse is over the sidebar. It makes sure that the    *
   2271  *    mouse is always the normal shape while over the sidebar.                                 *
   2272  *                                                                                             *
   2273  * INPUT:   flags -- The event flags that resulted in this routine being called.               *
   2274  *                                                                                             *
   2275  *          key   -- Reference the keyboard code that may be present.                          *
   2276  *                                                                                             *
   2277  * OUTPUT:  Returns that no further keyboard processing is necessary.                          *
   2278  *                                                                                             *
   2279  * WARNINGS:   none                                                                            *
   2280  *                                                                                             *
   2281  * HISTORY:                                                                                    *
   2282  *   03/28/1995 JLB : Created.                                                                 *
   2283  *=============================================================================================*/
   2284 int SidebarClass::SBGadgetClass::Action(unsigned , KeyNumType & )
   2285 {
   2286 	Map.Help_Text(TXT_NONE);
   2287 	Map.Override_Mouse_Shape(MOUSE_NORMAL, false);
   2288 	return(true);
   2289 }
   2290 
   2291 
   2292 /***********************************************************************************************
   2293  * SidebarClass::StripClass::Factory_Link -- Links a factory to a sidebar button.              *
   2294  *                                                                                             *
   2295  *    This routine will link the specified factory to this sidebar strip. The exact button to  *
   2296  *    link to is determined from the object type and id specified. A linked button is one that *
   2297  *    will show appropriate construction animation (clock shape) that matches the state of     *
   2298  *    the factory.                                                                             *
   2299  *                                                                                             *
   2300  * INPUT:   factory  -- The factory number to link to the sidebar.                             *
   2301  *                                                                                             *
   2302  *          type     -- The object type that this factory refers to.                           *
   2303  *                                                                                             *
   2304  *          id       -- The object sub-type that this factory refers to.                       *
   2305  *                                                                                             *
   2306  * OUTPUT:  Was the factory successfully attached? Failure would indicate that there is no     *
   2307  *          object of the specified type and sub-type in the sidebar list.                     *
   2308  *                                                                                             *
   2309  * WARNINGS:   none                                                                            *
   2310  *                                                                                             *
   2311  * HISTORY:                                                                                    *
   2312  *   05/18/1995 JLB : Created.                                                                 *
   2313  *=============================================================================================*/
   2314 bool SidebarClass::StripClass::Factory_Link(int factory, RTTIType type, int id)
   2315 {
   2316 	for (int index = 0; index < BuildableCount; index++) {
   2317 		if (Buildables[index].BuildableType == type && Buildables[index].BuildableID == id) {
   2318 			Buildables[index].Factory = factory;
   2319 			IsBuilding = true;
   2320 			/*
   2321 			** Flag that all the icons on this strip need to be redrawn
   2322 			*/
   2323 			Flag_To_Redraw();
   2324 			return(true);
   2325 		}
   2326 	}
   2327 	return(false);
   2328 }
   2329 
   2330 
   2331 /***********************************************************************************************
   2332  * SidebarClass::Abandon_Production -- Stops production of the object specified.               *
   2333  *                                                                                             *
   2334  *    This routine is used to abandon production of the object specified. The factory will     *
   2335  *    be completely disabled by this call.                                                     *
   2336  *                                                                                             *
   2337  * INPUT:   type     -- The object type that is to be abandoned. The sub-type is not needed    *
   2338  *                      since it is presumed there can be only one type in production at any   *
   2339  *                      one time.                                                              *
   2340  *                                                                                             *
   2341  *          factory  -- The factory number that is doing the production.                       *
   2342  *                                                                                             *
   2343  * OUTPUT:  Was the factory successfully abandoned?                                            *
   2344  *                                                                                             *
   2345  * WARNINGS:   none                                                                            *
   2346  *                                                                                             *
   2347  * HISTORY:                                                                                    *
   2348  *   05/18/1995 JLB : Created.                                                                 *
   2349  *=============================================================================================*/
   2350 bool SidebarClass::Abandon_Production(RTTIType type, int factory)
   2351 {
   2352 	return(Column[Which_Column(type)].Abandon_Production(factory));
   2353 }
   2354 
   2355 
   2356 /***********************************************************************************************
   2357  * SidebarClass::StripClass::Abandon_Produ -- Abandons production associated with sidebar.     *
   2358  *                                                                                             *
   2359  *    Production of the object associated with this sidebar is abandoned when this routine is  *
   2360  *    called.                                                                                  *
   2361  *                                                                                             *
   2362  * INPUT:   factory  -- The factory index that is to be suspended.                             *
   2363  *                                                                                             *
   2364  * OUTPUT:  Was the production abandonment successful?                                         *
   2365  *                                                                                             *
   2366  * WARNINGS:   none                                                                            *
   2367  *                                                                                             *
   2368  * HISTORY:                                                                                    *
   2369  *   05/18/1995 JLB : Created.                                                                 *
   2370  *   08/06/1995 JLB : More intelligent abandon logic for multiple factories.                   *
   2371  *=============================================================================================*/
   2372 bool SidebarClass::StripClass::Abandon_Production(int factory)
   2373 {
   2374 	bool noprod = true;
   2375 	bool abandon = false;
   2376 	for (int index = 0; index < BuildableCount; index++) {
   2377 		if (Buildables[index].Factory == factory) {
   2378 			Factories.Raw_Ptr(factory)->Abandon();
   2379 			Buildables[index].Factory = -1;
   2380 			abandon = true;
   2381 		} else {
   2382 			if (Buildables[index].Factory != -1) {
   2383 				noprod = false;
   2384 			}
   2385 		}
   2386 	}
   2387 
   2388 	/*
   2389 	**	If there was a change to the strip, then flag the strip to be redrawn.
   2390 	*/
   2391 	if (abandon) {
   2392 		Flag_To_Redraw();
   2393 	}
   2394 
   2395 	/*
   2396 	**	If there is no production whatsoever on this strip, then flag it so.
   2397 	*/
   2398 	if (noprod) {
   2399 		IsBuilding = false;
   2400 	}
   2401 	return(abandon);
   2402 }
   2403 
   2404 
   2405 /***********************************************************************************************
   2406  * SidebarClass::Zoom_Mode_Control -- Handles the zoom mode toggle operation.                  *
   2407  *                                                                                             *
   2408  *    This is the function that is called when the map button is pressed. It will toggle       *
   2409  *    between the different modes that the radar map can assume.                               *
   2410  *                                                                                             *
   2411  * INPUT:   none                                                                               *
   2412  *                                                                                             *
   2413  * OUTPUT:  none                                                                               *
   2414  *                                                                                             *
   2415  * WARNINGS:   none                                                                            *
   2416  *                                                                                             *
   2417  * HISTORY:                                                                                    *
   2418  *   07/31/1996 JLB : Created.                                                                 *
   2419  *=============================================================================================*/
   2420 void SidebarClass::Zoom_Mode_Control(void)
   2421 {
   2422 #ifdef WIN32
   2423 	/*
   2424 	** If radar is active, cycle as follows:
   2425 	** Zoomed => not zoomed
   2426 	** not zoomed => player status (multiplayer only)
   2427 	** player status => radar spying readout
   2428 	** radar spying readout => zoomed
   2429 	*/
   2430 	if (IsRadarActive) {
   2431 		if (Is_Zoomed() || Session.Type==GAME_NORMAL) {
   2432 			if (Is_Zoomed() || !Spy_Next_House()) {
   2433 				Zoom_Mode(Coord_Cell(TacticalCoord));
   2434 			}
   2435 		} else {
   2436 			if (!Spying_On_House() && !Is_Player_Names()) {
   2437 				Player_Names(1);
   2438 			} else {
   2439 				Player_Names(0);
   2440 				if (!Spy_Next_House()) {
   2441 					Zoom_Mode(Coord_Cell(TacticalCoord));
   2442 				}
   2443 			}
   2444 		}
   2445 	} else {
   2446 		if (Session.Type!=GAME_NORMAL) {
   2447 			Player_Names(Is_Player_Names()==0);
   2448 		}
   2449 	}
   2450 #else
   2451 	/*
   2452 	** If radar is active, cycle as follows:
   2453 	** not zoomed => player status (multiplayer only)
   2454 	** player status => radar spying readout
   2455 	** radar spying readout => not zoomed
   2456 	*/
   2457 	if (IsRadarActive) {
   2458 		if (Session.Type==GAME_NORMAL) {
   2459 			if (!Spy_Next_House()) {
   2460 				Zoom_Mode(Coord_Cell(TacticalCoord));
   2461 			}
   2462 		} else {
   2463 			if (!Spying_On_House() && !Is_Player_Names()) {
   2464 				Player_Names(1);
   2465 			} else {
   2466 				Player_Names(0);
   2467 				if (!Spy_Next_House()) {
   2468 					Zoom_Mode(Coord_Cell(TacticalCoord));
   2469 				}
   2470 			}
   2471 		}
   2472 	} else {
   2473 		if (Session.Type!=GAME_NORMAL) {
   2474 			Player_Names(Is_Player_Names()==0);
   2475 		}
   2476 	}
   2477 #endif
   2478 }