diff --git a/FeaturesScreen.cpp b/FeaturesScreen.cpp new file mode 100644 index 00000000..2c43f151 --- /dev/null +++ b/FeaturesScreen.cpp @@ -0,0 +1,1488 @@ +#ifdef PRECOMPILEDHEADERS +#include "JA2 All.h" +#else +#include "Types.h" +#include "FeaturesScreen.h" +#include "Video.h" +#include "Font Control.h" +#include "Game Clock.h" +#include "Text Input.h" +#include "WordWrap.h" +#include "SaveLoadScreen.h" +#include "Render Dirty.h" +#include "WordWrap.h" +#include "WCheck.h" +#include "Utilities.h" +#include "Debug.h" +#include "Sound Control.h" +#include "Ambient Control.h" +#include "Worlddat.h" +#include "Worlddef.h" +#include "GameSettings.h" +#include "Game Init.h" +#include "English.h" +#include "Overhead.h" +#include "Gap.h" +#include "Cursors.h" +#include "SysUtil.h" +#include "Exit Grids.h" +#include "Text.h" +#include "Interface Control.h" +#include "Message.h" +#include "Language Defines.h" +#include "Multi Language Graphic Utils.h" +#include "Map Information.h" +#include "Sys Globals.h" +#include "insurance.h" +#endif + +#include "connect.h" +#include "WorldMan.h" +#include "Init.h" +#include "Game Events.h" + +extern UINT32 guiDoneButton; // symbol already declared globally in AimArchives.cpp (jonathanl) + +namespace FeaturesScreen +{ + +// this enum must be kept in sync with z113FeaturesScreenText +enum Text +{ + FST_TITLE, + FST_DESCRIPTION, + FST_HOVER_FOR_MORE_INFO, +}; + +///////////////////////////////// +// +// Global Variables +// +///////////////////////////////// + +UINT32 guiFeaturesBackGroundImage; +UINT32 guiFeaturesAddOnImages; + +BOOLEAN gfFeaturesScreenEntry = TRUE; +BOOLEAN gfFeaturesScreenExit = FALSE; +BOOLEAN gfRedrawFeaturesScreen = TRUE; + +BOOLEAN gfEnteredFromMapScreen = FALSE; // entered from options screen or new game screen + +UINT32 guiFeaturesScreen = FEATURES_SCREEN; +UINT32 guiPreviousScreen = FEATURES_SCREEN; + +BOOLEAN gfExitFeaturesDueToMessageBox = FALSE; +BOOLEAN gfExitFeaturesAfterMessageBox = FALSE; + +INT32 giFeaturesMessageBox = -1; // Options pop up messages index value + +INT8 gbHighLightedOptionText = -1; + +// Goto save game Button +void BtnOptGotoSaveGameCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiOptGotoSaveGameBtn; +INT32 giOptionsButtonImages; + +// Goto load game button +void BtnOptGotoLoadGameCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiOptGotoLoadGameBtn; +INT32 giGotoLoadBtnImage; + +// QuitButton +void BtnOptQuitCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiQuitButton; +INT32 giQuitBtnImage; + +// Options Button +void BtnOptionsCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiOptionsButton; +INT32 giOptionsBtnImage; + +// arynn : need more option screen toggles : Add in button that allow for options column paging +// Options Screen globals +INT16 OptionsList_Column_Offset = 0; // the first column's -or- "half page" start +INT16 Current_First_Option_Index; // index of the first (single) option in the first column, used in lookup option vs togglebox +INT16 Max_Number_Of_Pages = 0; // dynamic column counter per build/mode type +void Establish_Features_Screen_Rules(void); // define the display rules +void Build_Features_List_Reinterpretation(void); // interpret rules and build a set of which options are used for use in options screen +void Create_Toggle_Buttons(void); // these two are blcok removals from functions, an isolation of toggle create/destroy +void Destroy_Toggle_Buttons(void); +void Handle_ButtonStyle_Options(UINT8 Button_UserData_1); + +// Next Button +void BtnOptNextCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiOptNextButton; +INT32 giOptNextBtnImage; + +// Prev Button +void BtnOptPrevCallback(GUI_BUTTON* btn, INT32 reason); +UINT32 guiOptPrevButton; +INT32 giOptPrevBtnImage; + +// Done Button +void BtnDoneCallback(GUI_BUTTON* btn, INT32 reason); +INT32 giDoneBtnImage; + + +//checkbox to toggle tracking mode on or off +UINT32 guiFeaturesToggles[MAX_NUMBER_OF_OPTION_TOGGLES]; //array of ButtonID, index's for button list +BOOL Buttons_Exist_State = 0; +void BtnOptionsTogglesCallback(GUI_BUTTON* btn, INT32 reason); + + +//Mouse regions for the name of the option +MOUSE_REGION gSelectedOptionTextRegion[MAX_NUMBER_OF_OPTION_TOGGLES]; +void SelectedOptionTextRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason); +void SelectedOptionTextRegionMovementCallBack(MOUSE_REGION* pRegion, INT32 reason); + + +//Mouse regions for the area around the toggle boxs +MOUSE_REGION gSelectedToggleBoxAreaRegion; +void SelectedToggleBoxAreaRegionMovementCallBack(MOUSE_REGION* pRegion, INT32 reason); + +//toggle box correspondence to option tracker +//1 define the render rules, +//2 recast real options into new array under constraints of rules, +//3 then using a pager system, create a subset that will fit on screen +int toggle_box_feature_rules[NUM_FEATURE_FLAGS]; // index = game option value = render state +int toggle_box_gGameSettings_recast[NUM_FEATURE_FLAGS + OPT_FIRST_COLUMN_TOGGLE_CUT_OFF]; +// index = reinterpreted positions value = game_option or state +//" + OPT_FIRST_COLUMN_TOGGLE_CUT_OFF " to account for potential empty togglebox positions up to next whole column +int toggle_box_array[MAX_NUMBER_OF_OPTION_TOGGLES]; // index = option position on screen value = game_option or state +///////////////////////////////// +// +// Function ProtoTypes +// +///////////////////////////////// + +BOOLEAN EnterScreen(); +void RenderScreen(); +void ExitScreen(); +void HandleScreen(); +void GetUserInput(); +void SetToggleBoxes(); +void SetExitScreen(UINT32 uiExitScreen); + +void ConfirmQuitToMainMenuMessageBoxCallBack(UINT8 bExitValue); +void HandleOptionToggle(UINT8 Button_UserData_0, UINT8 Button_UserData_1, BOOLEAN fState, BOOLEAN fDown, BOOLEAN fPlaySound); +void HandleHighLightedText(BOOLEAN fHighLight); +void DrawLeftPanel(); + +///////////////////////////////// +// +// Code +// +///////////////////////////////// + +UINT32 Init() +{ + //Set so next time we come in, we can set up + gfFeaturesScreenEntry = TRUE; + + //init rules and paging extent + Establish_Features_Screen_Rules(); + Build_Features_List_Reinterpretation(); //need to calc paging max before next/prev button creation + + return(TRUE); +} + +UINT32 Handle() +{ + StartFrameBufferRender(); + + if (gfFeaturesScreenEntry) + { + EnterScreen(); + gfFeaturesScreenEntry = FALSE; + gfFeaturesScreenExit = FALSE; + gfRedrawFeaturesScreen = TRUE; + + //Blit the background to the save buffer + BlitBufferToBuffer(guiRENDERBUFFER, guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + InvalidateRegion(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + } + + RestoreBackgroundRects(); + + GetUserInput(); + + RenderScreen(); + + HandleScreen(); + + if (gfRedrawFeaturesScreen) + { + RenderButtons(); + + gfRedrawFeaturesScreen = FALSE; + } + + // render buttons marked dirty + MarkButtonsDirty(); + RenderButtons(); + + // ATE: Put here to save RECTS before any fast help being drawn... + SaveBackgroundRects(); + RenderButtonsFastHelp(); + + + ExecuteBaseDirtyRectQueue(); + EndFrameBufferRender(); + + + if (gfFeaturesScreenExit) + { + ExitScreen(); + gfFeaturesScreenExit = FALSE; + gfFeaturesScreenEntry = TRUE; + + UnPauseGame(); + } + + return(guiFeaturesScreen); +} + +UINT32 Shutdown() +{ + return(TRUE); +} + +void Establish_Features_Screen_Rules(void) +{ + UINT16 counter; + // ary-05/05/2009 : note : pre-emptive definition of "game options render state". Show/Hide/etc options on option screen. + // : note : enum of states possible : + // : note : state -2 = is a state defined later, after rules build-up, and denotes the unused spots that exceed the final page. + // : note : state -1 = used in toggle_box_array, after rules build-up. and denotes the unused spots that are within last page. + // : note : state 0 = skip this option, consider it to be non-existant.. do not render.. + // : note : state 1 = normal, default + // : note : state 2 = text only, no box, no option to toggle, a "header/divider" type rendering + + //Re-init toggle_box_feature_rules[] + for (counter = 0; counter < NUM_FEATURE_FLAGS; counter++) + { + //this loop will re-initialize toggle_box_feature_rules[counter1] to "display as normally" state + toggle_box_feature_rules[counter] = 1; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + ////// begining of features content rules //////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////////////////// +} + +void Build_Features_List_Reinterpretation(void) +{ + // This function fills out a recast of gGameSettings.fOptions[], + // it differs by constraint foun in Establish_Features_Screen_Rules() + + INT16 counter1, counter2, index_of_last_valid_option; + + for (counter1 = 0; counter1 < (NUM_FEATURE_FLAGS + OPT_FIRST_COLUMN_TOGGLE_CUT_OFF); counter1++) + { + toggle_box_gGameSettings_recast[counter1] = -2; + } + + index_of_last_valid_option = 0; //track where inside the recast we ran out of actual options, + //we then pad the rest with -1's + //also, this is the basis for column counting + +// ary-05/05/2009 : counter1 represents the position inside toggle_box_gGameSettings_recast[], we dont skip these until there are no more options +// : counter2 represents the position inside gGameSettings.fOptions[], skip invalids until valid or NUM_FEATURE_FLAGS + counter2 = 0; // init prior to the loop + for (counter1 = 0; counter1 < NUM_FEATURE_FLAGS; counter1++) + { + for (; counter2 < NUM_FEATURE_FLAGS; ) + { + if (toggle_box_feature_rules[counter2]) // might be change to bit_vect, or some other mechanic, but for only 0 is not rendered + { + toggle_box_gGameSettings_recast[counter1] = counter2; + index_of_last_valid_option = counter1; + counter2++; + break; + } + counter2++; + } + } + + // pick up final tail of toggle box up to the next whole column + if ((index_of_last_valid_option + 1) % OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + { + Max_Number_Of_Pages = ((index_of_last_valid_option + 1) / OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + 1; + for (counter1 = (index_of_last_valid_option + 1); + counter1 < (Max_Number_Of_Pages * OPT_FIRST_COLUMN_TOGGLE_CUT_OFF); + counter1++) + { + toggle_box_gGameSettings_recast[counter1] = -1; + } + } + else + { + Max_Number_Of_Pages = ((index_of_last_valid_option + 1) / OPT_FIRST_COLUMN_TOGGLE_CUT_OFF); + // no tail to fill out, index_of_last_valid_option is the last option up to a whole column + } + +} + + +void Create_Toggle_Buttons(void) +{ + UINT16 counter1; + UINT16 usPosY, usBoxPosX, usTextPosX; + UINT16 usTextWidth, usTextHeight; + + // + // Toggle Boxes + // + // Build up a set of options toggles for render and callbacks. and remember set for deletion of set. + // + // main events: + // fill toggle_box_feature_rules[] (content rules), and global state after conditions have been setup + // fill toggle_box_array[], with options based on content rule, or global rules + // show check_box images and text, create mouse regions, based on toggle_box_array[] + // see Destroy_Toggle_Buttons() for handling of deletion (this is all setup to prevent deletion of uncreated regions) + ///////////////////////////////////////////////////////////////////////////////////////////////////////// + Establish_Features_Screen_Rules(); + Build_Features_List_Reinterpretation(); // based on rules, build a options_screen version of gGameSetting[], and derive max_pages + +// at this point we have an array that describes how the toggle boxes will be handled +// only thing left now is to describe the array of toggle_boxes that is currently about to be displayed on screen +// this should be easy enough, just offset into toggle_box_gGameSettings_recast, and direct copy into toggle_box_array + + Current_First_Option_Index = OptionsList_Column_Offset * OPT_FIRST_COLUMN_TOGGLE_CUT_OFF; + + for (counter1 = 0; counter1 < MAX_NUMBER_OF_OPTION_TOGGLES; counter1++) + { + //counter1 represents index within toggle_box_array, we have to handle each one + toggle_box_array[counter1] = toggle_box_gGameSettings_recast[counter1 + Current_First_Option_Index]; + } + + // at this point toggle_box_array has been built properly to content rules. + // now it is time to create/render/keep track of the toggle box options + + usTextHeight = GetFontHeight(OPT_MAIN_FONT); + + for (counter1 = 0; counter1 < MAX_NUMBER_OF_OPTION_TOGGLES; counter1++) + { + // skip creating toggle box for cases : no option , option supression + if (toggle_box_array[counter1] < 0) // skip every thing for -1 + { + continue; + } + + if (toggle_box_feature_rules[toggle_box_array[counter1]] == 2) //skip creating the toggle box | mouse regions + { // this case isnt creating toggle box, but is still using positions on the list, so adjust the graphics cursor + + // init or re-init base points of where graphics/text/regions are going to be placed + if (counter1 % OPT_FIRST_COLUMN_TOGGLE_CUT_OFF == 0) + { + //reset the vertical position + usPosY = OPT_TOGGLE_BOX_FIRST_COLUMN_START_Y; + } + //skip over vertical portion + usPosY += OPT_GAP_BETWEEN_TOGGLE_BOXES; + + //init/reset horizontal + if (counter1 < OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + { + usBoxPosX = OPT_TOGGLE_BOX_FIRST_COLUMN_X; + usTextPosX = OPT_TOGGLE_BOX_FIRST_COL_TEXT_X; + } + else + { + usBoxPosX = OPT_TOGGLE_BOX_SECOND_COLUMN_X; + usTextPosX = OPT_TOGGLE_BOX_SECOND_TEXT_X; + } + + continue; + } + + // init or re-init base points of where graphics/text/regions are going to be placed + if (counter1 % OPT_FIRST_COLUMN_TOGGLE_CUT_OFF == 0) + { + //reset the vertical position + usPosY = OPT_TOGGLE_BOX_FIRST_COLUMN_START_Y; + } + if (counter1 < OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + { + usBoxPosX = OPT_TOGGLE_BOX_FIRST_COLUMN_X; + usTextPosX = OPT_TOGGLE_BOX_FIRST_COL_TEXT_X; + } + else + { + usBoxPosX = OPT_TOGGLE_BOX_SECOND_COLUMN_X; + usTextPosX = OPT_TOGGLE_BOX_SECOND_TEXT_X; + } + + // here is the point when the graphical toggle is drawn and associated with a mouse region + + //Check box ID stored to guiFeaturesToggles[] by toggle option + guiFeaturesToggles[counter1] = CreateCheckBoxButton(usBoxPosX, usPosY, + "INTERFACE\\OptionsCheckBoxes_12x12.sti", + MSYS_PRIORITY_HIGH + 10, + BtnOptionsTogglesCallback); + + //set the toggle box's UserData[0] to the toggle_box index (which toggle box it is) + //set the toggle box's UserData[1] to the option's index (which option the toggle box represents) + MSYS_SetBtnUserData(guiFeaturesToggles[counter1], 0, counter1); + MSYS_SetBtnUserData(guiFeaturesToggles[counter1], 1, toggle_box_array[counter1]); + + usTextWidth = StringPixLength(z113FeaturesToggleText[toggle_box_array[counter1]], OPT_MAIN_FONT); + + if (usTextWidth > OPT_TOGGLE_BOX_TEXT_WIDTH) + { + //Get how many lines will be used to display the string, without displaying the string + UINT8 ubNumLines = (UINT8)(DisplayWrappedString(0, 0, OPT_TOGGLE_BOX_TEXT_WIDTH, 2, OPT_MAIN_FONT, OPT_HIGHLIGHT_COLOR, + z113FeaturesToggleText[toggle_box_array[counter1]], FONT_MCOLOR_BLACK, TRUE, + LEFT_JUSTIFIED | DONT_DISPLAY_TEXT) / GetFontHeight(OPT_MAIN_FONT)); + + usTextWidth = OPT_TOGGLE_BOX_TEXT_WIDTH; + + //Create mouse regions for the option toggle text + MSYS_DefineRegion(&gSelectedOptionTextRegion[counter1], usBoxPosX + 13, usPosY, + (usTextPosX + usTextWidth), (UINT16)(usPosY + usTextHeight * ubNumLines), MSYS_PRIORITY_HIGH, + CURSOR_NORMAL, SelectedOptionTextRegionMovementCallBack, SelectedOptionTextRegionCallBack); + MSYS_AddRegion(&gSelectedOptionTextRegion[counter1]); + + //set the text's region's UserData[0] to the toggle_box index (which toggle box it is) + //set the text's region's UserData[1] to the option's index (which option the toggle box represents) + MSYS_SetRegionUserData(&gSelectedOptionTextRegion[counter1], 0, counter1); + MSYS_SetRegionUserData(&gSelectedOptionTextRegion[counter1], 1, toggle_box_array[counter1]); + } + else + { + //Create mouse regions for the option toggle text + MSYS_DefineRegion(&gSelectedOptionTextRegion[counter1], usBoxPosX + 13, usPosY, + (usTextPosX + usTextWidth), (UINT16)(usPosY + usTextHeight), MSYS_PRIORITY_HIGH, + CURSOR_NORMAL, SelectedOptionTextRegionMovementCallBack, SelectedOptionTextRegionCallBack); + MSYS_AddRegion(&gSelectedOptionTextRegion[counter1]); + + //set the text's region's UserData[0] to the toggle_box index (which toggle box it is) + //set the text's region's UserData[1] to the option's index (which option the toggle box represents) + MSYS_SetRegionUserData(&gSelectedOptionTextRegion[counter1], 0, counter1); + MSYS_SetRegionUserData(&gSelectedOptionTextRegion[counter1], 1, toggle_box_array[counter1]); + } + + SetRegionFastHelpText(&gSelectedOptionTextRegion[counter1], z113FeaturesHelpText[toggle_box_array[counter1]]); + SetButtonFastHelpText(guiFeaturesToggles[counter1], z113FeaturesHelpText[toggle_box_array[counter1]]); + + usPosY += OPT_GAP_BETWEEN_TOGGLE_BOXES; + } + + Buttons_Exist_State = 1; // ok check boxes now exist, its safe to allow text highlights +} + + + +void Destroy_Toggle_Buttons(void) +{ + UINT8 counter1; + + Buttons_Exist_State = 0; // set this to off, prevents HandleScreen() from causing a CTD when tring to + // higlight text for non-existing checkboxes + + //Remove the toggle buttons + for (counter1 = 0; counter1 < MAX_NUMBER_OF_OPTION_TOGGLES; counter1++) + { + if (toggle_box_array[counter1] == -1) + { + // dont delete non existing buttons + continue; + } + if (toggle_box_feature_rules[toggle_box_array[counter1]] == 2) + { + // dont delete non existing buttons + continue; + } + + RemoveButton(guiFeaturesToggles[counter1]); + + MSYS_RemoveRegion(&gSelectedOptionTextRegion[counter1]); + } + +} + +BOOLEAN EnterScreen() +{ + VOBJECT_DESC VObjectDesc; + + //if we are coming from mapscreen + if (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN) + { + guiTacticalInterfaceFlags &= ~INTERFACE_MAPSCREEN; + gfEnteredFromMapScreen = TRUE; + } + + // Stop ambients... + StopAmbients(); + + guiFeaturesScreen = FEATURES_SCREEN; + + if (gfExitFeaturesDueToMessageBox) + { + gfRedrawFeaturesScreen = TRUE; + gfExitFeaturesDueToMessageBox = FALSE; + return(TRUE); + } + + gfExitFeaturesDueToMessageBox = FALSE; + + // load the options screen background graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP("INTERFACE\\OptionScreenBase.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiFeaturesBackGroundImage)); + + // load button, title graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + GetMLGFilename(VObjectDesc.ImageFile, MLG_OPTIONHEADER); + CHECKF(AddVideoObject(&VObjectDesc, &guiFeaturesAddOnImages)); + + //Save game button + giOptionsButtonImages = LoadButtonImage("INTERFACE\\OptionScreenAddons2.sti", -1, 2, -1, 3, -1); + guiOptGotoSaveGameBtn = CreateIconAndTextButton(giOptionsButtonImages, zOptionsText[OPT_SAVE_GAME], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_SAVE_BTN_X, OPT_SAVE_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptGotoSaveGameCallback); + SpecifyDisabledButtonStyle(guiOptGotoSaveGameBtn, DISABLED_STYLE_HATCHED); + if (guiPreviousScreen == MAINMENU_SCREEN || !CanGameBeSaved() || guiPreviousScreen == GAME_INIT_OPTIONS_SCREEN) + { + DisableButton(guiOptGotoSaveGameBtn); + } + + //Load game button + giGotoLoadBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiOptGotoLoadGameBtn = CreateIconAndTextButton(giGotoLoadBtnImage, zOptionsText[OPT_LOAD_GAME], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_LOAD_BTN_X, OPT_LOAD_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptGotoLoadGameCallback); + + //Quit to main menu button + giQuitBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiQuitButton = CreateIconAndTextButton(giQuitBtnImage, zOptionsText[OPT_MAIN_MENU], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_QUIT_BTN_X, OPT_QUIT_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptQuitCallback); + SpecifyDisabledButtonStyle(guiQuitButton, DISABLED_STYLE_HATCHED); + + // Options Button + giOptionsBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiOptionsButton = CreateIconAndTextButton(giOptionsBtnImage, zOptionsText[OPT_OPTIONS], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_SWAP_BTN_X, OPT_SWAP_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptionsCallback); + + // ary-05/05/2009 : need more option screen toggles : Add in buttons that allow for options column paging + // Previous Column of options + giOptPrevBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiOptPrevButton = CreateIconAndTextButton(giOptPrevBtnImage, zOptionsText[OPT_PREV], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_PREV_BTN_X, OPT_PREV_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptPrevCallback); + SpecifyDisabledButtonStyle(guiOptPrevButton, DISABLED_STYLE_HATCHED); + if (OptionsList_Column_Offset == 0) + { + DisableButton(guiOptPrevButton); + } + + // Next Column of options + giOptNextBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiOptNextButton = CreateIconAndTextButton(giOptNextBtnImage, zOptionsText[OPT_NEXT], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_NEXT_BTN_X, OPT_NEXT_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnOptNextCallback); + SpecifyDisabledButtonStyle(guiOptNextButton, DISABLED_STYLE_HATCHED); + if (OptionsList_Column_Offset >= (Max_Number_Of_Pages - 2))// ary-05/05/2009 : "Max_Number_Of_Pages-2" becaues each "page" = 2 "columns" + { + DisableButton(guiOptNextButton); + } + + //Done button + giDoneBtnImage = UseLoadedButtonImage(giOptionsButtonImages, -1, 2, -1, 3, -1); + guiDoneButton = CreateIconAndTextButton(giDoneBtnImage, zOptionsText[OPT_DONE], OPT_BUTTON_FONT2, + OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, + OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + OPT_DONE_BTN_X, OPT_DONE_BTN_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnDoneCallback); + + Create_Toggle_Buttons(); // ary-05/05/2009 : moved block out of func + + //Create a mouse region so when the user leaves a togglebox text region we can detect it then unselect the region + MSYS_DefineRegion(&gSelectedToggleBoxAreaRegion, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_NORMAL, + CURSOR_NORMAL, SelectedToggleBoxAreaRegionMovementCallBack, MSYS_NO_CALLBACK); + MSYS_AddRegion(&gSelectedToggleBoxAreaRegion); + + //Remove the mouse region over the clock + RemoveMouseRegionForPauseOfClock(); + + //Draw the screen + gfRedrawFeaturesScreen = TRUE; + + //Set the screen toggle boxes + SetToggleBoxes(); + + DisableScrollMessages(); + + //reset + gbHighLightedOptionText = -1; + + return(TRUE); +} + +void ExitScreen() +{ + if (gfExitFeaturesDueToMessageBox) + { + gfFeaturesScreenExit = FALSE; + + if (!gfExitFeaturesAfterMessageBox) + return; + gfExitFeaturesAfterMessageBox = FALSE; + gfExitFeaturesDueToMessageBox = FALSE; + } + + //The save the current settings to disk + SaveFeatureFlags(); + + if (guiFeaturesScreen == GAME_SCREEN) + { + EnterTacticalScreen(); + } + + if (guiFeaturesScreen == SAVE_LOAD_SCREEN && guiPreviousScreen == MAINMENU_SCREEN) + { + giMAXIMUM_NUMBER_OF_PLAYER_SLOTS = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; + InitDependingGameStyleOptions(); + } + + RemoveButton(guiOptGotoSaveGameBtn); + RemoveButton(guiOptGotoLoadGameBtn); + RemoveButton(guiQuitButton); + RemoveButton(guiOptionsButton); + RemoveButton(guiOptNextButton);// ary-05/05/2009 : more option screen toggles + RemoveButton(guiOptPrevButton); + RemoveButton(guiDoneButton); + + UnloadButtonImage(giOptionsButtonImages); + UnloadButtonImage(giGotoLoadBtnImage); + UnloadButtonImage(giQuitBtnImage); + UnloadButtonImage(giOptionsBtnImage); + UnloadButtonImage(giOptNextBtnImage);// ary-05/05/2009 : more option screen toggles + UnloadButtonImage(giOptPrevBtnImage); + UnloadButtonImage(giDoneBtnImage); + + DeleteVideoObjectFromIndex(guiFeaturesBackGroundImage); + DeleteVideoObjectFromIndex(guiFeaturesAddOnImages); + + Destroy_Toggle_Buttons(); // ary-05/05/2009 : moved block out of func + + MSYS_RemoveRegion(&gSelectedToggleBoxAreaRegion); + + //if we are coming from mapscreen + if (gfEnteredFromMapScreen) + { + gfEnteredFromMapScreen = FALSE; + guiTacticalInterfaceFlags |= INTERFACE_MAPSCREEN; + } +} + +void HandleScreen() +{ + HandleHighLightedText(TRUE); +} + +void RenderScreen() +{ + HVOBJECT hPixHandle; + UINT16 usPosY, usPosX; + UINT16 usWidth = 0; + UINT8 count; + CHAR16 sPage[60]; + + //Get and display the background image + GetVideoObject(&hPixHandle, guiFeaturesBackGroundImage); + BltVideoObject(FRAME_BUFFER, hPixHandle, 0, iScreenWidthOffset, iScreenHeightOffset, VO_BLT_SRCTRANSPARENCY, NULL); + + //Get and display the titla image + GetVideoObject(&hPixHandle, guiFeaturesAddOnImages); + BltVideoObject(FRAME_BUFFER, hPixHandle, 0, iScreenWidthOffset, iScreenHeightOffset, VO_BLT_SRCTRANSPARENCY, NULL); + BltVideoObject(FRAME_BUFFER, hPixHandle, 1, iScreenWidthOffset, iScreenHeightOffset + 434, VO_BLT_SRCTRANSPARENCY, NULL); + + DrawLeftPanel(); + + // + // Text for the toggle boxes + // + + //Display the First column of toggles + for (count = 0; count < MAX_NUMBER_OF_OPTION_TOGGLES; count++) + { + if (toggle_box_array[count] == -1) + { + break; + }// no text for non existing buttons + +//setup base points of where graphics/text/regions are going to be placed + if (count % OPT_FIRST_COLUMN_TOGGLE_CUT_OFF == 0) + { + //reset the vertical position + usPosY = OPT_TOGGLE_BOX_FIRST_COLUMN_START_Y + OPT_TOGGLE_TEXT_OFFSET_Y; + } + if (count < OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + { + usPosX = OPT_TOGGLE_BOX_FIRST_COL_TEXT_X; + } + else + { + usPosX = OPT_TOGGLE_BOX_SECOND_TEXT_X; + } + + usWidth = StringPixLength(z113FeaturesToggleText[toggle_box_array[count]], OPT_MAIN_FONT); + + UINT8 fontColor = (count == 0 || gGameSettings.fFeatures[FF_FEATURES_SCREEN]) ? + OPT_MAIN_COLOR : FONT_GRAY7; + + //if the string is going to wrap, move the string up a bit + if (usWidth > OPT_TOGGLE_BOX_TEXT_WIDTH) + DisplayWrappedString(usPosX, usPosY, OPT_TOGGLE_BOX_TEXT_WIDTH, 2, OPT_MAIN_FONT, fontColor, + z113FeaturesToggleText[toggle_box_array[count]], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED); + else + DrawTextToScreen(z113FeaturesToggleText[toggle_box_array[count]], usPosX, usPosY, 0, + OPT_MAIN_FONT, fontColor, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED); + + usPosY += OPT_GAP_BETWEEN_TOGGLE_BOXES; + } + + //Display the option page numbers + swprintf(sPage, L"%d / %d", OptionsList_Column_Offset + 1, max(1, Max_Number_Of_Pages - 1)); + DisplayWrappedString(OPT_PAGE_X, OPT_PAGE_Y, OPT_SLIDER_TEXT_WIDTH, 2, OPT_BUTTON_FONT2, OPT_MAIN_COLOR, + sPage, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED); + + //Set the screen toggle boxes + SetToggleBoxes(); + + InvalidateRegion(OPTIONS__TOP_LEFT_X, OPTIONS__TOP_LEFT_Y, OPTIONS__BOTTOM_RIGHT_X, OPTIONS__BOTTOM_RIGHT_Y); + +} + +void GetUserInput() +{ + InputAtom Event; + POINT MousePos; + + GetCursorPos(&MousePos); + ScreenToClient(ghWindow, &MousePos); // In window coords! + + while (DequeueSpecificEvent(&Event, KEY_DOWN | KEY_UP | KEY_REPEAT)) + { + if (!HandleTextInput(&Event) && Event.usEvent == KEY_DOWN) + { + switch (Event.usParam) + { + case ESC: + SetExitScreen(guiPreviousScreen); + break; + + //Enter the save game screen + case 's': + case 'S': + //if the save game button isnt disabled + if (ButtonList[guiOptGotoSaveGameBtn]->uiFlags & BUTTON_ENABLED) + { + SetExitScreen(SAVE_LOAD_SCREEN); + gfSaveGame = TRUE; + } + break; + + //Enter the Load game screen + case 'l': + case 'L': + SetExitScreen(SAVE_LOAD_SCREEN); + gfSaveGame = FALSE; + break; + + +#ifdef JA2TESTVERSION + + case 'r': + gfRedrawFeaturesScreen = TRUE; + break; + + case 'i': + InvalidateRegion(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + break; + + //Test keys + + case 'y': + { + static UINT32 uiTest2 = NO_SAMPLE; + if (!SoundIsPlaying(uiTest2)) + uiTest2 = PlayJA2SampleFromFile("Sounds\\RAID Dive.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN); + } + break; + case 't': + { + /* + { + CHAR8 zCdromRootDrive[512]; + HWFILE hFile; + + if( !GetCdromLocationFromIniFile( zCdromRootDrive ) ) + return; + + //Check if a file exists on the cdrom + sprintf( zCdromRootDrive, "%sData\\NPC_Speech.slf", zCdromRootDrive ); + + // if( FileExistsNoDB( zCdromRootDrive ) ) + hFile = FileOpen( zCdromRootDrive, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); + if( hFile != 0 ) + { + FileClose( hFile ); + sprintf( zCdromRootDrive, "%sData\\NPC_Speech.slf", zCdromRootDrive ); + } + else + { + sprintf( zCdromRootDrive, "%sData\\NPC_Speech.slf", zCdromRootDrive ); + } + + uiLastTimeToCheckCDromDrive = GetJA2Clock(); + } + */ + } + break; + + + case 'z': + SetErrorMode(SEM_FAILCRITICALERRORS); + break; + + case 'q': + // ShouldMercSayPrecedentToRepeatOneSelf( 11, 99 ); + break; +#endif + } + } + } +} + +void SetExitScreen(UINT32 uiExitScreen) +{ + OptionsList_Column_Offset = 0; // reset the pager till next visit + guiFeaturesScreen = uiExitScreen; + gfFeaturesScreenExit = TRUE; +} + +void BtnOptGotoSaveGameCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + SetExitScreen(SAVE_LOAD_SCREEN); + gfSaveGame = TRUE; + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +void BtnOptGotoLoadGameCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + SetExitScreen(SAVE_LOAD_SCREEN); + gfSaveGame = FALSE; + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +void BtnOptQuitCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + //Confirm the Exit to the main menu screen + DoMessageBox(MSG_BOX_BASIC_STYLE, zOptionsText[OPT_RETURN_TO_MAIN], FEATURES_SCREEN, MSG_BOX_FLAG_YESNO, + ConfirmQuitToMainMenuMessageBoxCallBack); + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +void BtnOptionsCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + SetExitScreen(OPTIONS_SCREEN); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +// ary-05/05/2009 : need more option screen toggles : Functions for button callbacks +void BtnOptPrevCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + ExitScreen(); + + OptionsList_Column_Offset--; + if (OptionsList_Column_Offset < 0) OptionsList_Column_Offset = 0; + + Init(); // ary-05/05/2009 : This is important to refresh the screen properly, it stores a new SAVE_BUFFER + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +void BtnOptNextCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + ExitScreen(); + + OptionsList_Column_Offset++; + if (OptionsList_Column_Offset >= Max_Number_Of_Pages) // ary-05/05/2009 : Max_Number_Of_Pages + OptionsList_Column_Offset = (Max_Number_Of_Pages - 1); + + Init(); // ary-05/05/2009 : This is important to refresh the screen properly, it stores a new SAVE_BUFFER + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + + +void BtnDoneCallback(GUI_BUTTON* btn, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + btn->uiFlags |= BUTTON_CLICKED_ON; + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + + SetExitScreen(guiPreviousScreen); + + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + btn->uiFlags &= (~BUTTON_CLICKED_ON); + InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, + btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY); + } +} + +void BtnOptionsTogglesCallback(GUI_BUTTON* btn, INT32 reason) +{ + UINT8 Button_UserData_0 = (UINT8)MSYS_GetBtnUserData(btn, 0);// the toggle box + UINT8 Button_UserData_1 = (UINT8)MSYS_GetBtnUserData(btn, 1);// the option + + if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + if (btn->uiFlags & BUTTON_CLICKED_ON) + { + HandleOptionToggle(Button_UserData_0, Button_UserData_1, TRUE, FALSE, FALSE); + btn->uiFlags |= BUTTON_CLICKED_ON; + } + else + { + btn->uiFlags &= ~BUTTON_CLICKED_ON; + HandleOptionToggle(Button_UserData_0, Button_UserData_1, FALSE, FALSE, FALSE); + } + } + else if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) + { + if (btn->uiFlags & BUTTON_CLICKED_ON) + { + HandleOptionToggle(Button_UserData_0, Button_UserData_1, TRUE, TRUE, FALSE); + btn->uiFlags |= BUTTON_CLICKED_ON; + } + else + { + btn->uiFlags &= ~BUTTON_CLICKED_ON; + HandleOptionToggle(Button_UserData_0, Button_UserData_1, FALSE, TRUE, FALSE); + } + } +} + +void Handle_ButtonStyle_Options(UINT8 Button_UserData_1) +{ + // note : This function is where all immediately apply effects occur + // : These options represent button like applications. + // : They are meant to be clicked on, then performed, then reset to off +} + +void HandleOptionToggle(UINT8 Button_UserData_0, UINT8 Button_UserData_1, BOOLEAN fState, BOOLEAN fDown, BOOLEAN fPlaySound) +{ + //Button_UserData_0 = which toggle box within guiFeaturesToggles[Button_UserData_0] + //Button_UserData_1 = which option the toggle box represents + + static UINT32 uiOptionToggleSound = NO_SAMPLE; + + if (fState) + { + switch (Button_UserData_1) + { + // FF_MILITIA_USE_SECTOR_EQUIPMENT and FF_MILITIA_REQUIRE_RESOURCES are mutually exclusive + case FF_MILITIA_REQUIRE_RESOURCES: + gGameSettings.fFeatures[FF_MILITIA_USE_SECTOR_EQUIPMENT] = FALSE; + break; + case FF_MILITIA_USE_SECTOR_EQUIPMENT: + gGameSettings.fFeatures[FF_MILITIA_REQUIRE_RESOURCES] = FALSE; + break; + + // enemy role features + case FF_ENEMY_ROLE_MEDIC: + case FF_ENEMY_ROLE_OFFICER: + case FF_ENEMY_ROLE_GENERAL: + gGameSettings.fFeatures[FF_ENEMY_ROLES] = TRUE; + break; + + // arulco strategic division + case FF_ASD_HELICOPTERS: + gGameSettings.fFeatures[FF_ASD] = TRUE; + break; + + // zombies + case FF_ZOMBIE_RAIDS: + gGameSettings.fFeatures[FF_ZOMBIES] = TRUE; + break; + } + + gGameSettings.fFeatures[Button_UserData_1] = TRUE; + + if (fDown) + DrawCheckBoxButtonOn(guiFeaturesToggles[Button_UserData_0]); + + Handle_ButtonStyle_Options(Button_UserData_1); + + } + else + { + switch (Button_UserData_1) + { + // enemy role features + case FF_ENEMY_ROLES: + gGameSettings.fFeatures[FF_ENEMY_ROLE_MEDIC] = FALSE; + gGameSettings.fFeatures[FF_ENEMY_ROLE_OFFICER] = FALSE; + gGameSettings.fFeatures[FF_ENEMY_ROLE_GENERAL] = FALSE; + break; + + // arulco strategic division + case FF_ASD: + gGameSettings.fFeatures[FF_ASD_HELICOPTERS] = FALSE; + break; + + + // zombies + case FF_ZOMBIES: + gGameSettings.fFeatures[FF_ZOMBIE_RAIDS] = FALSE; + break; + } + + gGameSettings.fFeatures[Button_UserData_1] = FALSE; + + if (fDown) + DrawCheckBoxButtonOff(guiFeaturesToggles[Button_UserData_0]); + } + + //stop the sound if + SoundStop(uiOptionToggleSound); + + + if (fPlaySound) + { + if (fDown) + { + PlayJA2Sample(BIG_SWITCH3_IN, RATE_11025, BTNVOLUME, 1, MIDDLEPAN); + } + else + { + PlayJA2Sample(BIG_SWITCH3_OUT, RATE_11025, BTNVOLUME, 1, MIDDLEPAN); + } + } + + InvalidateRegion(OPTIONS__TOP_LEFT_X, OPTIONS__TOP_LEFT_Y, OPTIONS__BOTTOM_RIGHT_X, OPTIONS__BOTTOM_RIGHT_Y); + +} + +BOOLEAN DoMessageBoxWithRect(UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT32 usFlags, + MSGBOX_CALLBACK ReturnCallback, SGPRect* pCenteringRect) +{ + // reset exit mode + gfExitFeaturesDueToMessageBox = TRUE; + + // do message box and return + giFeaturesMessageBox = DoMessageBox(ubStyle, zString, uiExitScreen, (usFlags | MSG_BOX_FLAG_USE_CENTERING_RECT), + ReturnCallback, pCenteringRect); + + // send back return state + return((giFeaturesMessageBox != -1)); +} + +BOOLEAN DoMessageBox(UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback) +{ + SGPRect CenteringRect = { 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1 }; + + // reset exit mode + gfExitFeaturesDueToMessageBox = TRUE; + + // do message box and return + giFeaturesMessageBox = DoMessageBox(ubStyle, zString, uiExitScreen, (UINT16)(usFlags | MSG_BOX_FLAG_USE_CENTERING_RECT), + ReturnCallback, &CenteringRect); + + // send back return state + return((giFeaturesMessageBox != -1)); +} + +void ConfirmQuitToMainMenuMessageBoxCallBack(UINT8 bExitValue) +{ + // yes, Quit to main menu + if (bExitValue == MSG_BOX_RETURN_YES) + { + gfEnteredFromMapScreen = FALSE; + gfExitFeaturesAfterMessageBox = TRUE; + SetExitScreen(MAINMENU_SCREEN); + + if (is_networked) + { + // haydent + server_disconnect(); + client_disconnect(); + + } + + //We want to reinitialize the game + ReStartingGame(); + } + else + { + gfExitFeaturesAfterMessageBox = FALSE; + gfExitFeaturesDueToMessageBox = FALSE; + } +} + +void SetToggleBoxes() +{ + UINT8 counter; + + for (counter = 0; counter < MAX_NUMBER_OF_OPTION_TOGGLES; counter++) + { + if (toggle_box_array[counter] == -1) + { + continue; + }//there are no options to set for this toggle_box + if (toggle_box_feature_rules[toggle_box_array[counter]] == 2) + { + continue; + }//there are no options to set for this toggle_box + + if (gGameSettings.fFeatures[toggle_box_array[counter]]) + ButtonList[guiFeaturesToggles[counter]]->uiFlags |= BUTTON_CLICKED_ON; + else + ButtonList[guiFeaturesToggles[counter]]->uiFlags &= (~BUTTON_CLICKED_ON); + } +} + +void SelectedOptionTextRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason) +{ + //Region_UserData_0 = which toggle box within guiFeaturesToggles[Button_UserData_0] + //Region_UserData_1 = which option the toggle box represents + + UINT8 Region_UserData_0 = (UINT8)MSYS_GetRegionUserData(pRegion, 0); + UINT8 Region_UserData_1 = (UINT8)MSYS_GetRegionUserData(pRegion, 1); + + if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) + { + + + HandleOptionToggle(Region_UserData_0, Region_UserData_1, (BOOLEAN)(!gGameSettings.fFeatures[Region_UserData_1]), FALSE, TRUE); + + InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, + pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); + } + + + else if (iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN)//iReason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || + { + if (gGameSettings.fFeatures[Region_UserData_1]) + { + HandleOptionToggle(Region_UserData_0, Region_UserData_1, TRUE, TRUE, TRUE); + } + else + { + HandleOptionToggle(Region_UserData_0, Region_UserData_1, FALSE, TRUE, TRUE); + } + } + +} + +void SelectedOptionTextRegionMovementCallBack(MOUSE_REGION* pRegion, INT32 reason) +{ + INT8 Region_UserData_0 = (INT8)MSYS_GetRegionUserData(pRegion, 0); + + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + HandleHighLightedText(FALSE); + gbHighLightedOptionText = -1; + InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, + pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); + } + else if (reason & MSYS_CALLBACK_REASON_GAIN_MOUSE) + { + gbHighLightedOptionText = Region_UserData_0; + InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, + pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); + } +} + +void HandleHighLightedText(BOOLEAN fHighLight) +{ + UINT16 usPosX = 0; + UINT16 usPosY = 0; + UINT8 counter; + INT8 bHighLight = -1; + UINT16 usWidth; + + static INT8 bLastRegion = -1; + + if (!Buttons_Exist_State) + { + // there are no buttons/text to highlight, time to leave before any attempt to lookup non-existing pointer data + gbHighLightedOptionText = -1; + return; + } + + if (gbHighLightedOptionText == -1) + fHighLight = FALSE; + + //if the user has the mouse in one of the checkboxes + for (counter = 0; counter < MAX_NUMBER_OF_OPTION_TOGGLES; counter++) + { + if (toggle_box_array[counter] == -1) + { + continue; + }//there are no options to set for this toggle_box + if (toggle_box_feature_rules[toggle_box_array[counter]] == 2) + { + continue; + }//there are no options to set for this toggle_box + + if (ButtonList[guiFeaturesToggles[counter]]->Area.uiFlags & MSYS_MOUSE_IN_AREA) + { + gbHighLightedOptionText = counter; + fHighLight = TRUE; + } + } + + + // If there is a valid section being highlighted + if (gbHighLightedOptionText != -1) + { + bLastRegion = gbHighLightedOptionText; + } + + bHighLight = gbHighLightedOptionText; + + + if (bLastRegion != -1 && gbHighLightedOptionText == -1) + { + fHighLight = FALSE; + bHighLight = bLastRegion; + bLastRegion = -1; + } + + if (bHighLight != -1) + { + if (bHighLight < OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) + { + usPosX = OPT_TOGGLE_BOX_FIRST_COL_TEXT_X; + usPosY = OPT_TOGGLE_BOX_FIRST_COLUMN_START_Y + OPT_TOGGLE_TEXT_OFFSET_Y + + (bHighLight * OPT_GAP_BETWEEN_TOGGLE_BOXES); + } + else + { + usPosX = OPT_TOGGLE_BOX_SECOND_TEXT_X; + usPosY = OPT_TOGGLE_BOX_SECOND_COLUMN_START_Y + OPT_TOGGLE_TEXT_OFFSET_Y + + ((bHighLight - OPT_FIRST_COLUMN_TOGGLE_CUT_OFF) * OPT_GAP_BETWEEN_TOGGLE_BOXES); + } + + usWidth = StringPixLength(z113FeaturesToggleText[toggle_box_array[bHighLight]], OPT_MAIN_FONT); + + //if the string is going to wrap, move the string up a bit + if (usWidth > OPT_TOGGLE_BOX_TEXT_WIDTH) + { + if (fHighLight) + DisplayWrappedString(usPosX, usPosY, OPT_TOGGLE_BOX_TEXT_WIDTH, 2, OPT_MAIN_FONT, OPT_HIGHLIGHT_COLOR, + z113FeaturesToggleText[toggle_box_array[bHighLight]], FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED); + else + DisplayWrappedString(usPosX, usPosY, OPT_TOGGLE_BOX_TEXT_WIDTH, 2, OPT_MAIN_FONT, OPT_MAIN_COLOR, + z113FeaturesToggleText[toggle_box_array[bHighLight]], FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED); + } + else + { + if (fHighLight) + DrawTextToScreen(z113FeaturesToggleText[toggle_box_array[bHighLight]], usPosX, usPosY, 0, + OPT_MAIN_FONT, OPT_HIGHLIGHT_COLOR, FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED); + else + DrawTextToScreen(z113FeaturesToggleText[toggle_box_array[bHighLight]], usPosX, usPosY, 0, + OPT_MAIN_FONT, OPT_MAIN_COLOR, FONT_MCOLOR_BLACK, TRUE, LEFT_JUSTIFIED); + } + } +} + +void SelectedToggleBoxAreaRegionMovementCallBack(MOUSE_REGION* pRegion, INT32 reason) +{ + if (reason & MSYS_CALLBACK_REASON_LOST_MOUSE) + { + } + else if (reason & MSYS_CALLBACK_REASON_GAIN_MOUSE) + { + UINT8 counter; + + //loop through all the toggle box's and remove the in area flag + for (counter = 0; counter < MAX_NUMBER_OF_OPTION_TOGGLES; counter++) + { + if (toggle_box_array[counter] == -1) + { + continue; + }//there are no options to set for this toggle_box + if (toggle_box_feature_rules[toggle_box_array[counter]] == 2) + { + continue; + }//there are no options to set for this toggle_box + + ButtonList[guiFeaturesToggles[counter]]->Area.uiFlags &= ~MSYS_MOUSE_IN_AREA; + } + + gbHighLightedOptionText = -1; + + InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, + pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); + } +} + +void DrawLeftPanel() +{ + UINT16 uiPosX, uiPosY; + + // need to cover a 180x327 pixel background + uiPosX = OPT_SOUND_FX_TEXT_X - 4; + uiPosY = OPT_SOUND_FX_TEXT_Y - 10; + ColorFillVideoSurfaceArea(FRAME_BUFFER, uiPosX, uiPosY, uiPosX + 180, uiPosY + 327, Get16BPPColor(FROMRGB(0, 0, 0))); + + // draw the text + SetFontShadow(FONT_MCOLOR_BLACK); + DisplayWrappedString( iScreenWidthOffset + 36, iScreenHeightOffset + 80, 176, 0, FONT14ARIAL, FONT_MCOLOR_WHITE, z113FeaturesScreenText[ FST_TITLE ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + DisplayWrappedString( iScreenWidthOffset + 36, iScreenHeightOffset + 95, 176, 0, FONT10ARIAL, FONT_MCOLOR_LTGRAY, z113FeaturesScreenText[ FST_DESCRIPTION ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + + CHAR16 text[1000]; + swprintf(text, L"%s", gbHighLightedOptionText != -1 ? z113FeaturesPanelText[toggle_box_array[gbHighLightedOptionText]] : z113FeaturesScreenText[FST_HOVER_FOR_MORE_INFO]); + DisplayWrappedString( iScreenWidthOffset + 36, iScreenHeightOffset + 125, 176, 0, FONT12ARIAL, FONT_MCOLOR_WHITE, text, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + + SetFontShadow(DEFAULT_SHADOW); +} + +void SetPreviousScreen(UINT32 screenId, BOOLEAN setOptionsToo) +{ + guiPreviousScreen = screenId; + + if (setOptionsToo) + SetOptionsPreviousScreen(screenId, FALSE); +} + +} // namespace