#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 "Multi Language Graphic Utils.h" #include "Map Information.h" #include "Sys Globals.h" #include "insurance.h" #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); // 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 NextPage(); void PreviousPage(); 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; RenderScreen(); //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 = 0, 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 = 0, usPosX; UINT16 usWidth = 0; UINT8 count; CHAR16 sPage[60]; //Get and display the background image if (GetVideoObject(&hPixHandle, guiFeaturesBackGroundImage)) BltVideoObject(FRAME_BUFFER, hPixHandle, 0, iScreenWidthOffset, iScreenHeightOffset, VO_BLT_SRCTRANSPARENCY, NULL); //Get and display the titla image if (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); // set the colour of the toggle box text UINT8 fontColor = (count == 0 && OptionsList_Column_Offset == 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 'q': case 'Q': //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); break; 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; // toggle between features and options screen case TAB: SetExitScreen(OPTIONS_SCREEN); break; // page left case 'a': case 'A': case LEFTARROW: PreviousPage(); break; // page right case 'd': case 'D': case RIGHTARROW: NextPage(); 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 } } } // mousewheel input if (OptionsList_Column_Offset > 0) { BOOL act = FALSE; // check general screen mouseregion if (gSelectedToggleBoxAreaRegion.WheelState > 0) { act = TRUE; } // check toggle box mouseregions for (int i = 0; i < MAX_NUMBER_OF_OPTION_TOGGLES; ++i) { if (act) break; if (gSelectedOptionTextRegion[i].WheelState > 0) { act = TRUE; } } if (act) PreviousPage(); } if (OptionsList_Column_Offset < Max_Number_Of_Pages-2) { BOOL act = FALSE; // check general screen mouseregion if (gSelectedToggleBoxAreaRegion.WheelState < 0) { act = TRUE; } // check toggle box mouseregions for (int i = 0; i < MAX_NUMBER_OF_OPTION_TOGGLES; ++i) { if (act) break; if (gSelectedOptionTextRegion[i].WheelState < 0) { act = TRUE; } } if (act) NextPage(); } } void NextPage() { ExitScreen(); OptionsList_Column_Offset++; if (OptionsList_Column_Offset >= Max_Number_Of_Pages - 1) // ary-05/05/2009 : Max_Number_Of_Pages OptionsList_Column_Offset = (Max_Number_Of_Pages - 2); Init(); } void PreviousPage() { ExitScreen(); OptionsList_Column_Offset--; if(OptionsList_Column_Offset < 0) OptionsList_Column_Offset = 0; Init(); } 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 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_DROP_ALL and FF_DROP_ALL_DAMAGED are mutually exclusive case FF_DROP_ALL: gGameSettings.fFeatures[FF_DROP_ALL_DAMAGED] = FALSE; break; case FF_DROP_ALL_DAMAGED: gGameSettings.fFeatures[FF_DROP_ALL] = FALSE; break; // counterattack/aggressive AI mutual exclusive toggles case FF_AGGRESSIVE_STRATEGIC_AI: gGameSettings.fFeatures[FF_AGGRESSIVE_STRATEGIC_AI_2] = FALSE; break; case FF_AGGRESSIVE_STRATEGIC_AI_2: gGameSettings.fFeatures[FF_AGGRESSIVE_STRATEGIC_AI] = FALSE; break; // 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; // dynamic opinions and dialogue case FF_DYNAMIC_DIALOGUE: gGameSettings.fFeatures[FF_DYNAMIC_OPINIONS] = 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; // rain/lightning case FF_ALLOW_LIGHTNING: gGameSettings.fFeatures[FF_ALLOW_RAIN] = TRUE; break; } gGameSettings.fFeatures[Button_UserData_1] = TRUE; if (fDown) DrawCheckBoxButtonOn(guiFeaturesToggles[Button_UserData_0]); } 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; // dynamic opinions and dialogue case FF_DYNAMIC_OPINIONS: gGameSettings.fFeatures[FF_DYNAMIC_DIALOGUE] = 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; // rain/lightning case FF_ALLOW_RAIN: gGameSettings.fFeatures[FF_ALLOW_LIGHTNING] = 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]]) { if (ButtonList[guiFeaturesToggles[counter]]) { ButtonList[guiFeaturesToggles[counter]]->uiFlags |= BUTTON_CLICKED_ON; } } else { if (ButtonList[guiFeaturesToggles[counter]]) { 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 && toggle_box_array[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