#include "Types.h" #include "SaveLoadScreen.h" #include "Video.h" #include "Font Control.h" #include "Game Clock.h" #include "Render Dirty.h" #include "Text Input.h" #include "SaveLoadGame.h" #include "Stdio.h" #include "WordWrap.h" #include "StrategicMap.h" #include "Finances.h" #include "WCheck.h" #include "Utilities.h" #include "Cursors.h" #include "VObject.h" #include "Merc Hiring.h" #include "LaptopSave.h" #include "Options Screen.h" #include "GameVersion.h" #include "SysUtil.h" #include "Tactical Save.h" #include "OverHead.h" #include "gamescreen.h" #include "GameSettings.h" #include "fade screen.h" #include "English.h" #include "Gameloop.h" #include "Game Init.h" #include "Text.h" #include "Message.h" #include "Map Screen Interface.h" #include "Multi Language Graphic Utils.h" #include "Campaign Types.h" #include "PostalService.h" #include "connect.h" #include "FileMan.h" #include #include #ifdef JA2UB #include "Strategic Movement.h" //#include "Strategic Movement Costs.h" #include "LuaInitNPCs.h" #endif BOOLEAN gfSchedulesHosed = FALSE; extern UINT32 guiBrokenSaveGameVersion; UINT16 NUM_SLOT; ////////////////////////////////////////////////////// // // Defines // ////////////////////////////////////////////////////// #define SAVE_LOAD_TITLE_FONT FONT14ARIAL #define SAVE_LOAD_TITLE_COLOR FONT_MCOLOR_WHITE #define SAVE_LOAD_NORMAL_FONT FONT12ARIAL #define SAVE_LOAD_NORMAL_COLOR FONT_GRAY2 #define SAVE_LOAD_NORMAL_SHADOW_COLOR FONT_NEARBLACK #define SAVE_LOAD_QUICKSAVE_FONT FONT12ARIAL #define SAVE_LOAD_QUICKSAVE_COLOR 2 #define SAVE_LOAD_QUICKSAVE_SHADOW_COLOR 189 #define SAVE_LOAD_EMPTYSLOT_FONT FONT12ARIAL #define SAVE_LOAD_EMPTYSLOT_COLOR 2 #define SAVE_LOAD_EMPTYSLOT_SHADOW_COLOR 189 #define SAVE_LOAD_HIGHLIGHTED_FONT FONT12ARIAL #define SAVE_LOAD_HIGHLIGHTED_COLOR FONT_MCOLOR_WHITE #define SAVE_LOAD_HIGHLIGHTED_SHADOW_COLOR 2 #define SAVE_LOAD_SELECTED_FONT FONT12ARIAL #define SAVE_LOAD_SELECTED_COLOR 2 #define SAVE_LOAD_SELECTED_SHADOW_COLOR 130 #define SAVE_LOAD_NUMBER_FONT FONT12ARIAL #define SAVE_LOAD_NUMBER_COLOR FONT_MCOLOR_WHITE #define SLG_SELECTED_COLOR FONT_MCOLOR_WHITE #define SLG_UNSELECTED_COLOR FONT_MCOLOR_DKWHITE #define SLG_SAVELOCATION_WIDTH 605 #define SLG_FIRST_SAVED_SPOT_X iScreenWidthOffset + 17 #define SLG_FIRST_SAVED_SPOT_Y iScreenHeightOffset + 49 #define SLG_DATE_OFFSET_X 13 #define SLG_SECTOR_OFFSET_X 95 #define SLG_SECTOR_OFFSET_Y SLG_DATE_OFFSET_Y #define SLG_SECTOR_WIDTH 98 #define SLG_NUM_MERCS_OFFSET_X 196 #define SLG_NUM_MERCS_OFFSET_Y SLG_DATE_OFFSET_Y #define SLG_BALANCE_OFFSET_X 260 #define SLG_BALANCE_OFFSET_Y SLG_DATE_OFFSET_Y #define SLG_SAVE_GAME_DESC_X 318 #define SLG_SAVE_GAME_DESC_Y SLG_DATE_OFFSET_Y #define SLG_TITLE_POS_X iScreenWidthOffset #define SLG_TITLE_POS_Y iScreenHeightOffset #define SLG_SAVE_CANCEL_POS_X iScreenWidthOffset + 226 #define SLG_LOAD_CANCEL_POS_X iScreenWidthOffset + 329 #define SLG_CANCEL_POS_Y iScreenHeightOffset + 438 #define SLG_SAVE_LOAD_BTN_POS_X iScreenWidthOffset + 123 #define SLG_SAVE_LOAD_BTN_POS_Y iScreenHeightOffset + 438 #define SLG_SAVE_LOAD_PAGE_POS_X SLG_SAVE_LOAD_BTN_POS_X + 195 #define SLG_SAVE_LOAD_PAGE_POS_Y SLG_SAVE_LOAD_BTN_POS_Y + 10 #define SLG_DOUBLE_CLICK_DELAY 500 //defines for saved game version status enum { SLS_HEADER_OK, SLS_SAVED_GAME_VERSION_OUT_OF_DATE, SLS_GAME_VERSION_OUT_OF_DATE, SLS_BOTH_SAVE_GAME_AND_GAME_VERSION_OUT_OF_DATE, }; ////////////////////////////////////////////////////// // // Global Variables // ////////////////////////////////////////////////////// extern void NextLoopCheckForEnoughFreeHardDriveSpace(); BOOLEAN gfSaveLoadScreenEntry = TRUE; BOOLEAN gfSaveLoadScreenExit = FALSE; BOOLEAN gfRedrawSaveLoadScreen = TRUE; BOOLEAN gfExitAfterMessageBox = FALSE; INT32 giSaveLoadMessageBox = -1; // SaveLoad pop up messages index value UINT32 guiSaveLoadExitScreen = SAVE_LOAD_SCREEN; //Contains the array of valid save game locations BOOLEAN gbSaveGameArray[ NUM_SAVE_GAMES ]; // anv: read times of modification to show them later SYSTEMTIME gstSaveGameCreationTimeArray[ NUM_SAVE_GAMES ]; BOOLEAN gfDoingQuickLoad = FALSE; BOOLEAN gfFailedToSaveGameWhenInsideAMessageBox = FALSE; //This flag is used to diferentiate between loading a game and saveing a game. // gfSaveGame=TRUE For saving a game // gfSaveGame=FALSE For loading a game BOOLEAN gfSaveGame=TRUE; BOOLEAN gfSaveLoadScreenButtonsCreated = FALSE; INT8 gbSaveGameSelectedLocation[ NUM_SAVE_GAMES ]; INT32 gbSelectedSaveLocation=-1; INT8 gbHighLightedLocation=-1; INT8 gbLastHighLightedLocation=-1; INT32 gbSetSlotToBeSelected=-1; UINT32 guiSlgBackGroundImage; UINT32 guiBackGroundAddOns; UINT32 guiBackGroundAddOns_New; UINT32 SLG_SAVELOCATION_HEIGHT; UINT32 SLG_GAP_BETWEEN_LOCATIONS; UINT32 SLG_DATE_OFFSET_Y; UINT32 SLG_SELECTED_SLOT_GRAPHICS_NUMBER; UINT32 SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER; // The string that will contain the game desc text CHAR16 gzGameDescTextField[ SIZE_OF_SAVE_GAME_DESC ] = {0} ; BOOLEAN gfUserInTextInputMode = FALSE; UINT8 gubSaveGameNextPass=0; BOOLEAN gfStartedFadingOut = FALSE; BOOLEAN gfCameDirectlyFromGame = FALSE; BOOLEAN gfLoadedGame = FALSE; //Used to know when a game has been loaded, the flag in gtacticalstatus might have been reset already BOOLEAN gfLoadGameUponEntry = FALSE; BOOLEAN gfGettingNameFromSaveLoadScreen = FALSE; #ifdef JA2BETAVERSION extern BOOLEAN gfDisplaySaveGamesNowInvalidatedMsg; #endif // //Buttons // INT32 guiSlgButtonImage; // Cancel Button void BtnSlgCancelCallback(GUI_BUTTON *btn,INT32 reason); UINT32 guiSlgCancelBtn; // Save game Button void BtnSlgSaveLoadCallback(GUI_BUTTON *btn,INT32 reason); UINT32 guiSlgSaveLoadBtn; INT32 guiSaveLoadImage; INT32 guiNewButtonImage; INT32 guiPrevButton, guiNextButton; void BtnNewPrevButtonCallback(GUI_BUTTON *btn,INT32 reason); void BtnNewNextButtonCallback(GUI_BUTTON *btn,INT32 reason); UINT16 PAGE_SLOT = 0; UINT16 VAL_SLOT_START = 0; UINT16 VAL_SLOT_END = 0; BOOLEAN RenderImage = TRUE; BOOLEAN DoAutoSave( int ubSaveGameID, STR16 pGameDesc ); BOOLEAN AutoSaveToSlot[5]; // WANNE: Used For auto save games UINT32 lastLoadedSaveGameDay = 0; UINT8 lastLoadedSaveGameHour = 0; #define MAX_PAGE_SLOT 12 //Mouse regions for the currently selected save game MOUSE_REGION gSelectedSaveRegion[ NUM_SAVE_GAMES ]; void SelectedSaveRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); void SelectedSaveRegionMovementCallBack(MOUSE_REGION * pRegion, INT32 reason ); MOUSE_REGION gSLSEntireScreenRegion; void SelectedSLSEntireRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); #ifdef JA2BETAVERSION extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode ); #endif extern BOOLEAN fFirstTimeInGameScreen; // added by Flugente extern UINT32 uiSoundSample; ////////////////////////////////////////////////////// // // Function Prototypes // ////////////////////////////////////////////////////// BOOLEAN EnterSaveLoadScreen(); void RenderSaveLoadScreen(); void ExitSaveLoadScreen(); void HandleSaveLoadScreen(); void GetSaveLoadScreenUserInput(); void SaveLoadGameNumber( INT32 bSaveGameID ); BOOLEAN LoadSavedGameHeader( INT32 bEntry, SAVED_GAME_HEADER *pSaveGameHeader ); BOOLEAN DisplaySaveGameEntry( INT32 bEntryID );//, UINT16 usPosY ); BOOLEAN DisplaySaveGameList(); void InitSaveLoadScreenTextInputBoxes(); void DestroySaveLoadTextInputBoxes(); void SetSelection( UINT8 ubNewSelection ); UINT8 CompareSaveGameVersion( INT32 bSaveGameID ); void LoadSavedGameWarningMessageBoxCallBack( UINT8 bExitValue ); void LoadSavedGameDeleteAllSaveGameMessageBoxCallBack( UINT8 bExitValue ); void DeleteAllSaveGameFile( ); void DisplayOnScreenNumber( BOOLEAN fErase ); void DisableSelectedSlot(); void ConfirmSavedGameMessageBoxCallBack( UINT8 bExitValue ); void ConfirmLoadSavedGameMessageBoxCallBack( UINT8 bExitValue ); void FailedLoadingGameCallBack( UINT8 bExitValue ); void SetSaveLoadExitScreen( UINT32 uiScreen ); void NotEnoughHardDriveSpaceForQuickSaveMessageBoxCallBack( UINT8 bExitValue ); void NotEnoughHardDriveSpaceForNormalSaveMessageBoxCallBack( UINT8 bExitValue ); void RedrawSaveLoadScreenAfterMessageBox( UINT8 bExitValue ); void ClearSelectedSaveSlot(); void MoveSelectionUpOrDown( BOOLEAN fUp ); void SaveGameToSlotNum(); void StartFadeOutForSaveLoadScreen(); #ifdef JA2UB extern void MakeBadSectorListFromMapsOnHardDrive( BOOLEAN fDisplayMessages ); // ja25 UB #endif ////////////////////////////////////////////////////// // // Code // ////////////////////////////////////////////////////// void LoadSaveGameOldOrNew() { if (gGameExternalOptions.fSaveGameSlot == TRUE) { NUM_SLOT = NUM_SAVE_GAMES_NEW; SLG_SAVELOCATION_HEIGHT = 15; SLG_GAP_BETWEEN_LOCATIONS = 20; SLG_DATE_OFFSET_Y = 5; SLG_SELECTED_SLOT_GRAPHICS_NUMBER = 1; SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER = 0; } else { NUM_SLOT = NUM_SAVE_GAMES_OLD; SLG_SAVELOCATION_HEIGHT = 30; SLG_GAP_BETWEEN_LOCATIONS = 35; SLG_DATE_OFFSET_Y = 11; SLG_SELECTED_SLOT_GRAPHICS_NUMBER = 3; SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER = 2; } } UINT32 SaveLoadScreenInit() { //Set so next time we come in, we can set up gfSaveLoadScreenEntry = TRUE; memset( gbSaveGameArray, -1, NUM_SAVE_GAMES); ClearSelectedSaveSlot(); gbHighLightedLocation=-1; return( TRUE ); } UINT32 SaveLoadScreenHandle() { StartFrameBufferRender(); if( gfSaveLoadScreenEntry ) { EnterSaveLoadScreen(); gfSaveLoadScreenEntry = FALSE; gfSaveLoadScreenExit = FALSE; PauseGame(); //save the new rect BlitBufferToBuffer(guiRENDERBUFFER, guiSAVEBUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); } RestoreBackgroundRects(); //to guarentee that we do not accept input when we are fading out if( !gfStartedFadingOut ) { GetSaveLoadScreenUserInput(); } else gfRedrawSaveLoadScreen = FALSE; //if we have exited the save load screen, exit if( !gfSaveLoadScreenButtonsCreated ) return( guiSaveLoadExitScreen ); RenderAllTextFields(); HandleSaveLoadScreen(); if( gfRedrawSaveLoadScreen ) { RenderSaveLoadScreen(); MarkButtonsDirty( ); RenderButtons(); gfRedrawSaveLoadScreen = FALSE; } if( gubSaveGameNextPass != 0 ) { gubSaveGameNextPass++; if( gubSaveGameNextPass == 5 ) { gubSaveGameNextPass = 0; SaveLoadGameNumber( gbSelectedSaveLocation ); } } //If we are not exiting the screen, render the buttons if( !gfSaveLoadScreenExit && guiSaveLoadExitScreen == SAVE_LOAD_SCREEN ) { // render buttons marked dirty RenderButtons( ); } // ATE: Put here to save RECTS before any fast help being drawn... SaveBackgroundRects( ); RenderButtonsFastHelp(); ExecuteBaseDirtyRectQueue( ); EndFrameBufferRender( ); if ( HandleFadeOutCallback( ) ) { return( guiSaveLoadExitScreen ); } if ( HandleBeginFadeOut( SAVE_LOAD_SCREEN ) ) { return( SAVE_LOAD_SCREEN ); } if( gfSaveLoadScreenExit ) { ExitSaveLoadScreen(); } if ( HandleFadeInCallback( ) ) { // Re-render the scene! RenderSaveLoadScreen(); } if ( HandleBeginFadeIn( SAVE_LOAD_SCREEN ) ) { } return( guiSaveLoadExitScreen ); } UINT32 SaveLoadScreenShutdown() { return( TRUE ); } void SetSaveLoadExitScreen( UINT32 uiScreen ) { if( uiScreen == GAME_SCREEN ) { EnterTacticalScreen( ); } gfSaveLoadScreenExit = TRUE; guiSaveLoadExitScreen = uiScreen; SetPendingNewScreen( uiScreen ); ExitSaveLoadScreen(); DestroySaveLoadTextInputBoxes(); } void InitMSysButtons(BOOLEAN delRegion) { UINT16 usPosX = SLG_FIRST_SAVED_SPOT_X; UINT16 usPosY = SLG_FIRST_SAVED_SPOT_Y; UINT8 i; CHAR16 zString[512]; CHAR16 zString2[512]; CHAR16 zString3[512]; if ( delRegion == TRUE ) { for(i=0; i= SAVE__TIMED_AUTOSAVE_SLOT1 && i <= SAVE__TIMED_AUTOSAVE_SLOT5 ) { swprintf( zString, pMessageStrings[MSG_SAVE_AUTOSAVE_SLOT], VAL_SLOT_START + i ); } else if ( PAGE_SLOT == 0 && i >= SAVE__END_TURN_NUM_1 && i <= SAVE__END_TURN_NUM_2 ) { swprintf( zString, pMessageStrings[MSG_SAVE_AUTOSAVE_ENDTURN_SLOT], VAL_SLOT_START - SAVE__TIMED_AUTOSAVE_SLOT5 - 1 + i ); } else { swprintf( zString, pMessageStrings[MSG_SAVE_NORMAL_SLOT], VAL_SLOT_START + i - SAVE__END_TURN_NUM_2 ); } // anv: add modification date if( gbSaveGameArray[ VAL_SLOT_START + i ] ) { swprintf( zString2, L"%04d", gstSaveGameCreationTimeArray[ VAL_SLOT_START + i ].wYear ); wcscpy( zString3, zString2 ); swprintf( zString2, L"/%02d", gstSaveGameCreationTimeArray[ VAL_SLOT_START + i ].wMonth ); wcscat( zString3, zString2 ); swprintf( zString2, L"/%02d ", gstSaveGameCreationTimeArray[ VAL_SLOT_START + i ].wDay ); wcscat( zString3, zString2 ); swprintf( zString2, L"%02d", gstSaveGameCreationTimeArray[ VAL_SLOT_START + i ].wHour ); wcscat( zString3, zString2 ); swprintf( zString2, L":%02d ", gstSaveGameCreationTimeArray[ VAL_SLOT_START + i ].wMinute ); wcscat( zString3, zString2 ); wcscat( zString3, zString ); wcscpy( zString, zString3 ); } wcscpy( zString2,zString ); SetRegionFastHelpText( &gSelectedSaveRegion[ i ], zString2 ); //if we are to Load a game if( !gfSaveGame ) { //We cannot load a game that hasnt been saved if( !gbSaveGameArray[ VAL_SLOT_START + i ] ) MSYS_DisableRegion( &gSelectedSaveRegion[ i ] ); } usPosY += SLG_GAP_BETWEEN_LOCATIONS; } } BOOLEAN NewEnterSaveLoadScreen() { VOBJECT_DESC VObjectDesc; UINT16 usPosX = SLG_FIRST_SAVED_SPOT_X; UINT16 usPosY = SLG_FIRST_SAVED_SPOT_Y; RenderImage = FALSE; if (guiBackGroundAddOns_New != -1) DeleteVideoObjectFromIndex( guiBackGroundAddOns_New ); VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\LOADSCREENADDONS_SAVEGAME.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiBackGroundAddOns_New)); //init the list InitSaveGameArray(); //Clear out all the saved background rects EmptyBackgroundRects( ); //if the user has asked to load the selected save if( gfLoadGameUponEntry ) { //make sure the save is valid if( gGameSettings.bLastSavedGameSlot != -1 && gbSaveGameArray[ gGameSettings.bLastSavedGameSlot ] ) { gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot; //load the saved game ConfirmLoadSavedGameMessageBoxCallBack( MSG_BOX_RETURN_YES ); } else { //else the save isnt valid, so dont load it gfLoadGameUponEntry = FALSE; } } if (PAGE_SLOT == 0 || PAGE_SLOT < 0 ) DisableButton( guiPrevButton ); if (PAGE_SLOT == MAX_PAGE_SLOT || PAGE_SLOT > MAX_PAGE_SLOT ) DisableButton( guiNextButton ); SpecifyDisabledButtonStyle( guiSlgSaveLoadBtn, DISABLED_STYLE_HATCHED ); if( gbSetSlotToBeSelected == -1 ) DisableButton( guiSlgSaveLoadBtn ); InitMSysButtons(TRUE); ClearSelectedSaveSlot(); //Reset the highlight gbHighLightedLocation = -1; gzGameDescTextField[0] = '\0'; SpecifyDisabledButtonStyle( guiSlgSaveLoadBtn, DISABLED_STYLE_HATCHED ); //if the last saved game slot is ok, set the selected slot to the last saved slot] if( gGameSettings.bLastSavedGameSlot != -1 ) { //if the slot is valid if( gbSaveGameArray[ gGameSettings.bLastSavedGameSlot ] ) { SAVED_GAME_HEADER SaveGameHeader; memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); //if it is not the Quick Save slot, and we are loading if( !gfSaveGame || gfSaveGame && gGameSettings.bLastSavedGameSlot != 0 ) { gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot%NUM_SLOT; gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_SELECTED_SLOT_GRAPHICS_NUMBER; //load the save gamed header string //Get the heade for the saved game if( !LoadSavedGameHeader( gbSelectedSaveLocation, &SaveGameHeader ) ) { memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER; if (gbSelectedSaveLocation != SAVE__END_TURN_NUM) { gbSaveGameArray[ gbSelectedSaveLocation ] = FALSE; } gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot = -1; } wcscpy( gzGameDescTextField, SaveGameHeader.sSavedGameDesc ); } } } //if we are loading and the there is no slot selected if( gbSelectedSaveLocation == -1 ) DisableButton( guiSlgSaveLoadBtn ); else EnableButton( guiSlgSaveLoadBtn ); RenderSaveLoadScreen(); // Save load buttons are created gfSaveLoadScreenButtonsCreated = TRUE; gfDoingQuickLoad = FALSE; //reset gfStartedFadingOut = FALSE; DisableScrollMessages(); gfLoadedGame = FALSE; if( gfLoadGameUponEntry ) { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; //unmark the 2 buttons from being dirty ButtonList[ guiSlgCancelBtn ]->uiFlags |= BUTTON_FORCE_UNDIRTY; ButtonList[ guiSlgSaveLoadBtn ]->uiFlags |= BUTTON_FORCE_UNDIRTY; // CLEAR THE FRAME BUFFER pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); memset(pDestBuf, 0, SCREEN_HEIGHT * uiDestPitchBYTES ); UnLockVideoSurface( FRAME_BUFFER ); // CLEAR THE guiRENDERBUFFER pDestBuf = LockVideoSurface( guiRENDERBUFFER, &uiDestPitchBYTES ); memset(pDestBuf, 0, SCREEN_HEIGHT * uiDestPitchBYTES ); UnLockVideoSurface( guiRENDERBUFFER ); } gfGettingNameFromSaveLoadScreen = FALSE; return( TRUE ); } BOOLEAN EnterSaveLoadScreen() { VOBJECT_DESC VObjectDesc; UINT16 usPosX = SLG_FIRST_SAVED_SPOT_X; UINT16 usPosY = SLG_FIRST_SAVED_SPOT_Y; PAGE_SLOT = 0; VAL_SLOT_START = 0; RenderImage = TRUE; // this is where we came from; if loading of resources fails, this is also where we go next/back extern UINT32 guiPreviousScreen; guiSaveLoadExitScreen = guiPreviousScreen; //init the list InitSaveGameArray(); //Clear out all the saved background rects EmptyBackgroundRects( ); //if the user has asked to load the selected save if( gfLoadGameUponEntry ) { //make sure the save is valid if( gGameSettings.bLastSavedGameSlot != -1 && gbSaveGameArray[ gGameSettings.bLastSavedGameSlot ] ) { gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot; //load the saved game ConfirmLoadSavedGameMessageBoxCallBack( MSG_BOX_RETURN_YES ); } else { //else the save isnt valid, so dont load it gfLoadGameUponEntry = FALSE; } } // load Main background graphic and add it VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\LoadScreen.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiSlgBackGroundImage)); // load Load Screen Add ons graphic and add it VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; GetMLGFilename( VObjectDesc.ImageFile, MLG_LOADSAVEHEADER ); CHECKF(AddVideoObject(&VObjectDesc, &guiBackGroundAddOns)); if (gGameExternalOptions.fSaveGameSlot == TRUE) { VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\LOADSCREENADDONS_SAVEGAME.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiBackGroundAddOns_New)); } guiSlgButtonImage = LoadButtonImage("INTERFACE\\LoadScreenAddOns.sti", -1,6,-1,9,-1 ); usPosX = SLG_LOAD_CANCEL_POS_X; guiSlgCancelBtn = CreateIconAndTextButton( guiSlgButtonImage, zSaveLoadText[SLG_CANCEL], OPT_BUTTON_FONT, OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, TEXT_CJUSTIFIED, usPosX, SLG_CANCEL_POS_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, BtnSlgCancelCallback ); //Either the save or load button if( gfSaveGame ) { //If we are saving, dont have the save game button guiSaveLoadImage = UseLoadedButtonImage( guiSlgButtonImage, -1,5,-1,8,-1 ); guiSlgSaveLoadBtn = CreateIconAndTextButton( guiSaveLoadImage, zSaveLoadText[SLG_SAVE_GAME], OPT_BUTTON_FONT, OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, TEXT_CJUSTIFIED, SLG_SAVE_LOAD_BTN_POS_X, SLG_SAVE_LOAD_BTN_POS_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, BtnSlgSaveLoadCallback ); } else { guiSaveLoadImage = UseLoadedButtonImage( guiSlgButtonImage, -1,4,-1,7,-1 ); guiSlgSaveLoadBtn = CreateIconAndTextButton( guiSaveLoadImage, zSaveLoadText[SLG_LOAD_GAME], OPT_BUTTON_FONT, OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, TEXT_CJUSTIFIED, SLG_SAVE_LOAD_BTN_POS_X, SLG_SAVE_LOAD_BTN_POS_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, BtnSlgSaveLoadCallback ); } guiNewButtonImage = LoadButtonImage("INTERFACE\\LoadScreenButtons.sti", -1,0,-1,1,-1 ); guiPrevButton = CreateIconAndTextButton( guiNewButtonImage, zOptionsText[4], OPT_BUTTON_FONT, OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, TEXT_CJUSTIFIED, SLG_SAVE_LOAD_BTN_POS_X-105, SLG_SAVE_LOAD_BTN_POS_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, BtnNewPrevButtonCallback ); guiNextButton = CreateIconAndTextButton( guiNewButtonImage, zOptionsText[3], OPT_BUTTON_FONT, OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW, OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW, TEXT_CJUSTIFIED, SLG_SAVE_LOAD_BTN_POS_X+395, SLG_SAVE_LOAD_BTN_POS_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK, BtnNewNextButtonCallback ); if (PAGE_SLOT == 0 || PAGE_SLOT < 0 ) DisableButton( guiPrevButton ); if (PAGE_SLOT == MAX_PAGE_SLOT || PAGE_SLOT > MAX_PAGE_SLOT ) DisableButton( guiNextButton ); SpecifyDisabledButtonStyle( guiSlgSaveLoadBtn, DISABLED_STYLE_HATCHED ); if( gbSetSlotToBeSelected == -1 ) DisableButton( guiSlgSaveLoadBtn ); InitMSysButtons(FALSE); //Create the screen mask to enable ability to righ click to cancel the sace game MSYS_DefineRegion( &gSLSEntireScreenRegion, 0, 0, SCREEN_WIDTH , SCREEN_HEIGHT , MSYS_PRIORITY_HIGH-10, CURSOR_NORMAL, MSYS_NO_CALLBACK, SelectedSLSEntireRegionCallBack ); MSYS_AddRegion(&gSLSEntireScreenRegion); ClearSelectedSaveSlot(); //Remove the mouse region over the clock RemoveMouseRegionForPauseOfClock( ); //Reset the highlight gbHighLightedLocation = -1; gzGameDescTextField[0] = '\0'; SpecifyDisabledButtonStyle( guiSlgSaveLoadBtn, DISABLED_STYLE_HATCHED ); //if the last saved game slot is ok, set the selected slot to the last saved slot] if( gGameSettings.bLastSavedGameSlot != -1 ) { //if the slot is valid if( gbSaveGameArray[ gGameSettings.bLastSavedGameSlot ] ) { SAVED_GAME_HEADER SaveGameHeader; memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); //if it is not the Quick Save slot, and we are loading if( !gfSaveGame || gfSaveGame && gGameSettings.bLastSavedGameSlot != 0 ) { gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot; gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_SELECTED_SLOT_GRAPHICS_NUMBER; //Get the heade for the saved game if( !LoadSavedGameHeader( gbSelectedSaveLocation, &SaveGameHeader ) ) { memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER; if (gbSelectedSaveLocation != SAVE__END_TURN_NUM) { gbSaveGameArray[ gbSelectedSaveLocation ] = FALSE; } gbSelectedSaveLocation = gGameSettings.bLastSavedGameSlot = -1; } wcscpy( gzGameDescTextField, SaveGameHeader.sSavedGameDesc ); } } } //if we are loading and the there is no slot selected if( gbSelectedSaveLocation == -1 ) DisableButton( guiSlgSaveLoadBtn ); else EnableButton( guiSlgSaveLoadBtn ); RenderSaveLoadScreen(); // Save load buttons are created gfSaveLoadScreenButtonsCreated = TRUE; // OK, loading of resources was successfull; time to enter the SAVE_LOAD screen guiSaveLoadExitScreen = SAVE_LOAD_SCREEN; gfDoingQuickLoad = FALSE; //reset gfStartedFadingOut = FALSE; DisableScrollMessages(); gfLoadedGame = FALSE; if( gfLoadGameUponEntry ) { UINT32 uiDestPitchBYTES; UINT8 *pDestBuf; //unmark the 2 buttons from being dirty ButtonList[ guiSlgCancelBtn ]->uiFlags |= BUTTON_FORCE_UNDIRTY; ButtonList[ guiSlgSaveLoadBtn ]->uiFlags |= BUTTON_FORCE_UNDIRTY; // CLEAR THE FRAME BUFFER pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); memset(pDestBuf, 0, SCREEN_HEIGHT * uiDestPitchBYTES ); UnLockVideoSurface( FRAME_BUFFER ); // CLEAR THE guiRENDERBUFFER pDestBuf = LockVideoSurface( guiRENDERBUFFER, &uiDestPitchBYTES ); memset(pDestBuf, 0, SCREEN_HEIGHT * uiDestPitchBYTES ); UnLockVideoSurface( guiRENDERBUFFER ); } gfGettingNameFromSaveLoadScreen = FALSE; //Go to page with last saved game if ( gGameSettings.bLastSavedGameSlot >= NUM_SLOT) { PAGE_SLOT = gGameSettings.bLastSavedGameSlot/NUM_SLOT; VAL_SLOT_START = (PAGE_SLOT * NUM_SLOT); if ( PAGE_SLOT > 0 ) EnableButton( guiPrevButton ); if (PAGE_SLOT == MAX_PAGE_SLOT || PAGE_SLOT > MAX_PAGE_SLOT ) DisableButton( guiNextButton ); DestroySaveLoadTextInputBoxes(); NewEnterSaveLoadScreen(); } return( TRUE ); } void ExitSaveLoadScreen() { UINT8 i; PAGE_SLOT = 0; VAL_SLOT_START = 0; RenderImage = TRUE; gfLoadGameUponEntry = FALSE; if( !gfSaveLoadScreenButtonsCreated ) return; gfSaveLoadScreenExit = FALSE; gfSaveLoadScreenEntry = TRUE; gfExitAfterMessageBox = FALSE; UnloadButtonImage( guiSlgButtonImage ); RemoveButton( guiSlgCancelBtn ); RemoveButton( guiNextButton ); RemoveButton( guiPrevButton ); UnloadButtonImage( guiNewButtonImage ); RemoveButton( guiSlgSaveLoadBtn ); UnloadButtonImage( guiSaveLoadImage ); for(i=0; i 0 ) { PAGE_SLOT = PAGE_SLOT - 1; if ( PAGE_SLOT == 0 || PAGE_SLOT < 0 ) VAL_SLOT_START = 0; else if ( PAGE_SLOT >= 1 ) VAL_SLOT_START = (PAGE_SLOT * 19); if (PAGE_SLOT == 0 || PAGE_SLOT < 0 ) { DisableButton( guiPrevButton ); EnableButton( guiNextButton ); PAGE_SLOT = 0; } else if (PAGE_SLOT < MAX_PAGE_SLOT) { EnableButton( guiNextButton ); } DestroySaveLoadTextInputBoxes(); NewEnterSaveLoadScreen(); } break; case PGDN: // next page, RIGHTARROW not used due to interference with textbox navigation if ( PAGE_SLOT < MAX_PAGE_SLOT ) { PAGE_SLOT = PAGE_SLOT + 1; if ( PAGE_SLOT >= 1 ) VAL_SLOT_START = (PAGE_SLOT * 19); else if ( PAGE_SLOT >= MAX_PAGE_SLOT ) { VAL_SLOT_START = (MAX_PAGE_SLOT * 19); PAGE_SLOT = MAX_PAGE_SLOT; } if (PAGE_SLOT > 0 ) EnableButton( guiPrevButton ); if (PAGE_SLOT > MAX_PAGE_SLOT || PAGE_SLOT == MAX_PAGE_SLOT ) DisableButton( guiNextButton ); DestroySaveLoadTextInputBoxes(); NewEnterSaveLoadScreen(); } break; case ESC: if( gbSelectedSaveLocation == -1 ) { if( gfCameDirectlyFromGame ) SetSaveLoadExitScreen( guiPreviousOptionScreen ); else if( guiPreviousOptionScreen == MAINMENU_SCREEN ) SetSaveLoadExitScreen( MAINMENU_SCREEN ); else SetSaveLoadExitScreen( OPTIONS_SCREEN ); } else { //Reset the selected slot background graphic gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER; //reset selected slot gbSelectedSaveLocation = -1; gfRedrawSaveLoadScreen = TRUE; DestroySaveLoadTextInputBoxes(); DisableButton( guiSlgSaveLoadBtn ); } break; case ENTER: if( gfSaveGame ) { bActiveTextField = (INT32)GetActiveFieldID(); if( bActiveTextField && bActiveTextField != -1 ) { Get16BitStringFromField( (UINT8)bActiveTextField, gzGameDescTextField, 128 ); SetActiveField(0); DestroySaveLoadTextInputBoxes(); SaveLoadGameNumber( gbSelectedSaveLocation ); return; } else { if( gbSelectedSaveLocation != -1 ) { SaveLoadGameNumber( gbSelectedSaveLocation ); return; } } //Enable the save/load button if( gbSelectedSaveLocation != -1 ) if( !gfSaveGame ) EnableButton( guiSlgSaveLoadBtn ); gfRedrawSaveLoadScreen = TRUE; } else SaveLoadGameNumber( gbSelectedSaveLocation ); break; } } } } void SaveLoadGameNumber( INT32 bSaveGameID ) { UINT8 ubRetVal=0; if( bSaveGameID >= NUM_SAVE_GAMES || bSaveGameID < 0 ) { return; } if( gfSaveGame ) { INT8 bActiveTextField; bActiveTextField = (INT32)GetActiveFieldID(); if( bActiveTextField && bActiveTextField != -1 ) { Get16BitStringFromField( (UINT8)bActiveTextField, gzGameDescTextField, 128 ); } //if there is save game in the slot, ask for confirmation before overwriting if( gbSaveGameArray[ VAL_SLOT_START + bSaveGameID ] ) { CHAR16 sText[512]; swprintf( sText, zSaveLoadText[SLG_CONFIRM_SAVE], VAL_SLOT_START + bSaveGameID ); DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, sText, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, ConfirmSavedGameMessageBoxCallBack ); } else { //Save the game SaveGameToSlotNum(); } } else { //Check to see if the save game headers are the same ubRetVal = CompareSaveGameVersion( bSaveGameID ); if( ubRetVal != SLS_HEADER_OK ) { if( ubRetVal == SLS_GAME_VERSION_OUT_OF_DATE ) { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_GAME_VERSION_DIF], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, LoadSavedGameWarningMessageBoxCallBack ); } else if( ubRetVal == SLS_SAVED_GAME_VERSION_OUT_OF_DATE ) { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVED_GAME_VERSION_DIF], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, LoadSavedGameWarningMessageBoxCallBack ); } else { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_BOTH_GAME_AND_SAVED_GAME_DIF], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, LoadSavedGameWarningMessageBoxCallBack ); } } else { //Setup up the fade routines StartFadeOutForSaveLoadScreen(); } } } BOOLEAN DoSaveLoadMessageBoxWithRect( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT32 usFlags, MSGBOX_CALLBACK ReturnCallback, SGPRect *pCenteringRect ) { // do message box and return giSaveLoadMessageBox = DoMessageBox(ubStyle,zString,uiExitScreen,( UINT8 )( usFlags| MSG_BOX_FLAG_USE_CENTERING_RECT ), ReturnCallback, pCenteringRect ); // send back return state return( ( giSaveLoadMessageBox != -1 ) ); } BOOLEAN DoSaveLoadMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback ) { SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 }; // do message box and return giSaveLoadMessageBox = DoMessageBox(ubStyle,zString,uiExitScreen,( UINT8 ) ( usFlags| MSG_BOX_FLAG_USE_CENTERING_RECT ),ReturnCallback, &CenteringRect ); // send back return state return( ( giSaveLoadMessageBox != -1 ) ); } BOOLEAN InitSaveGameArray() { UINT8 cnt,cnt2; UINT8 i; CHAR8 zSaveGameName[ 512 ]; SAVED_GAME_HEADER SaveGameHeader; for( i=0; i_getRealPath(vfsPath); string str = vfsPath.to_string(); LPCSTR lpSaveGamePath = str.c_str(); // get file handle HANDLE hFile = CreateFile( lpSaveGamePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); // read time attributes FILETIME ftCreationTime, ftLastAccessedTime, ftLastWriteTime; SYSTEMTIME stSystemTime; GetFileTime( hFile, &ftCreationTime, &ftLastAccessedTime, &ftLastWriteTime ); // remember time FileTimeToSystemTime( &ftLastWriteTime, &stSystemTime ); SystemTimeToTzSpecificLocalTime( NULL, &stSystemTime, &gstSaveGameCreationTimeArray[VAL_SLOT_START + cnt] ); // close CloseHandle( hFile ); rfile->close(); #endif } } else gbSaveGameArray[VAL_SLOT_START + cnt] = FALSE; } return( TRUE ); } BOOLEAN DisplaySaveGameList() { UINT8 bLoop1; UINT16 usPosY = SLG_FIRST_SAVED_SPOT_Y; for( bLoop1=0; bLoop1 NUM_SAVE_GAMES /*NUM_SLOT*/ ) { //memset( &pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); memset( pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); return( FALSE ); } //Get the name of the file newSlot = VAL_SLOT_START + bEntry; CreateSavedGameFileNameFromNumber( newSlot, zSavedGameName ); if( FileExists( zSavedGameName ) ) { // create the save game file hFile = FileOpen( zSavedGameName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); if( !hFile ) { FileClose( hFile ); gbSaveGameArray[ VAL_SLOT_START + bEntry ] = FALSE; return(FALSE); } //Load the Save Game header file FileRead( hFile, pSaveGameHeader, sizeof( SAVED_GAME_HEADER ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( SAVED_GAME_HEADER ) ) { FileClose( hFile ); gbSaveGameArray[ VAL_SLOT_START + bEntry ] = FALSE; return(FALSE); } FileClose( hFile ); // // Do some Tests on the header to make sure it is valid // //Check to see if the desc field is bigger then it should be, ie no null char if( wcslen( pSaveGameHeader->sSavedGameDesc ) >= SIZE_OF_SAVE_GAME_DESC ) { memset( pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); gbSaveGameArray[ VAL_SLOT_START + bEntry ] = FALSE; return(FALSE); } //Check to see if the version # field is bigger then it should be, ie no null char if( strlen( pSaveGameHeader->zGameVersionNumber ) >= GAME_VERSION_LENGTH ) { memset( pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); gbSaveGameArray[ bEntry ] = FALSE; return(FALSE); } } else { memset( pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); #ifdef JA2BETAVERSION wcscpy( pSaveGameHeader->sSavedGameDesc, L"ERROR loading saved game header, file doesn't exist!!" ); #endif } return( TRUE ); } void BtnSlgCancelCallback(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 ); //Exit back if( gfCameDirectlyFromGame ) SetSaveLoadExitScreen( guiPreviousOptionScreen ); else if( guiPreviousOptionScreen == MAINMENU_SCREEN ) SetSaveLoadExitScreen( MAINMENU_SCREEN ); else if( guiPreviousOptionScreen == GAME_INIT_OPTIONS_SCREEN )//hayden SetSaveLoadExitScreen( GAME_INIT_OPTIONS_SCREEN ); else SetSaveLoadExitScreen( 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); } } void BtnSlgSaveLoadCallback(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 ); SaveLoadGameNumber( gbSelectedSaveLocation ); 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 BtnNewPrevButtonCallback(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 ); PAGE_SLOT = PAGE_SLOT - 1; if ( PAGE_SLOT == 0 || PAGE_SLOT < 0 ) VAL_SLOT_START = 0; else if ( PAGE_SLOT >= 1 ) VAL_SLOT_START = (PAGE_SLOT * 19); if (PAGE_SLOT == 0 || PAGE_SLOT < 0 ) { DisableButton( guiPrevButton ); EnableButton( guiNextButton ); PAGE_SLOT = 0; } else if (PAGE_SLOT < MAX_PAGE_SLOT) { EnableButton( guiNextButton ); } DestroySaveLoadTextInputBoxes(); NewEnterSaveLoadScreen(); 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 BtnNewNextButtonCallback(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 ); PAGE_SLOT = PAGE_SLOT + 1; if ( PAGE_SLOT >= 1 ) VAL_SLOT_START = (PAGE_SLOT * 19); else if ( PAGE_SLOT >= MAX_PAGE_SLOT ) { VAL_SLOT_START = (MAX_PAGE_SLOT * 19); PAGE_SLOT = MAX_PAGE_SLOT; } if (PAGE_SLOT > 0 ) EnableButton( guiPrevButton ); if (PAGE_SLOT > MAX_PAGE_SLOT || PAGE_SLOT == MAX_PAGE_SLOT ) DisableButton( guiNextButton ); DestroySaveLoadTextInputBoxes(); NewEnterSaveLoadScreen(); 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 SelectedSaveRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) { INT8 bActiveTextField; CHAR16 zString[128]; if (iReason & MSYS_CALLBACK_REASON_INIT) { } else if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { UINT8 bSelected = (UINT8)MSYS_GetRegionUserData( pRegion, 0 ); static UINT32 uiLastTime = 0; UINT32 uiCurTime = GetJA2Clock(); INT32 i; //If we are saving and this is the quick save slot if( gfSaveGame && bSelected == 0 && PAGE_SLOT == 0 ) { //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, pMessageStrings[ MSG_QUICK_SAVE_RESERVED_FOR_TACTICAL ], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__TIMED_AUTOSAVE_SLOT1 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__TIMED_AUTOSAVE_SLOT2 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__TIMED_AUTOSAVE_SLOT3 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__TIMED_AUTOSAVE_SLOT4 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__TIMED_AUTOSAVE_SLOT5 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s %d", pMessageStrings[ MSG_SAVE_AUTOSAVE_TEXT_INFO ],SAVE__TIMED_AUTOSAVE_SLOT5); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //If we are saving and this is the auto save slot if( gfSaveGame && bSelected == SAVE__END_TURN_NUM_1 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_ENDTURN_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } if( gfSaveGame && bSelected == SAVE__END_TURN_NUM_2 && PAGE_SLOT == 0 ) { swprintf( zString, L"%s", pMessageStrings[ MSG_SAVE_AUTOSAVE_ENDTURN_TEXT_INFO ]); //Display a pop up telling user what the quick save slot is DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zString, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, RedrawSaveLoadScreenAfterMessageBox ); return; } //Reset the regions for( i=0; iuiFlags &= (~BUTTON_CLICKED_ON ); INT8 bTemp = gbHighLightedLocation; gbHighLightedLocation = -1; DisplaySaveGameEntry( bTemp ); InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); } else if( reason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) { pRegion->uiFlags |= BUTTON_CLICKED_ON ; //If we are saving and this is the quick save slot, leave if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 0 ) { return; } //Auto save slot 1-5 else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 1 ) { return; } else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 2 ) { return; } else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 3 ) { return; } else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 4 ) { return; } else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 5 ) { return; } //This slot is reserved for end turn Auto Saves else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 6 ) { return; } else if( gfSaveGame && MSYS_GetRegionUserData( pRegion, 0 ) != 7 ) { return; } gbLastHighLightedLocation = gbHighLightedLocation; gbHighLightedLocation = (UINT8)MSYS_GetRegionUserData( pRegion, 0 ); DisplaySaveGameEntry( gbLastHighLightedLocation ); DisplaySaveGameEntry( gbHighLightedLocation );//, usPosY ); InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); } } void InitSaveLoadScreenTextInputBoxes() { UINT16 usPosY; SAVED_GAME_HEADER SaveGameHeader; if( gbSelectedSaveLocation == -1 ) return; if( !gfSaveGame ) return; //if we are exiting, dont create the fields if( gfSaveLoadScreenExit || guiSaveLoadExitScreen != SAVE_LOAD_SCREEN ) return; InitTextInputMode(); SetTextInputCursor( CUROSR_IBEAM_WHITE ); SetTextInputFont( (UINT16) FONT12ARIALFIXEDWIDTH ); Set16BPPTextFieldColor( Get16BPPColor(FROMRGB( 0, 0, 0) ) ); SetBevelColors( Get16BPPColor(FROMRGB(136, 138, 135)), Get16BPPColor(FROMRGB(24, 61, 81)) ); SetTextInputRegularColors( FONT_WHITE, 2 ); SetTextInputHilitedColors( 2, FONT_WHITE, FONT_WHITE ); SetCursorColor( Get16BPPColor(FROMRGB(255, 255, 255) ) ); AddUserInputField( NULL ); usPosY = SLG_FIRST_SAVED_SPOT_Y + SLG_GAP_BETWEEN_LOCATIONS * gbSelectedSaveLocation; //if there is already a string here, use its string if( gbSaveGameArray[ VAL_SLOT_START + gbSelectedSaveLocation ] ) { //if we are modifying a previously modifed string, use it if( gzGameDescTextField[0] != '\0' ) { } else { //Get the header for the specified saved game LoadSavedGameHeader( gbSelectedSaveLocation, &SaveGameHeader ); wcscpy( gzGameDescTextField, SaveGameHeader.sSavedGameDesc ); } } else gzGameDescTextField[0] = '\0'; //Game Desc Field AddTextInputField( SLG_FIRST_SAVED_SPOT_X+SLG_SAVE_GAME_DESC_X, (INT16)(usPosY+SLG_SAVE_GAME_DESC_Y-5), SLG_SAVELOCATION_WIDTH-SLG_SAVE_GAME_DESC_X-7, 17, MSYS_PRIORITY_HIGH+2, gzGameDescTextField, 46, INPUTTYPE_ASCII );//23 SetActiveField( 1 ); gfUserInTextInputMode = TRUE; } void DestroySaveLoadTextInputBoxes() { gfUserInTextInputMode = FALSE; KillAllTextInputModes(); SetTextInputCursor( CURSOR_IBEAM ); } void SetSelection( UINT8 ubNewSelection ) { //if we are loading and there is no entry, return if( !gfSaveGame ) { if( !gbSaveGameArray[VAL_SLOT_START + ubNewSelection] ) return; } //Reset the selected slot background graphic if( gbSelectedSaveLocation != -1 ) { gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER; //reset the slots help text SetRegionFastHelpText( &gSelectedSaveRegion[ gbSelectedSaveLocation ], L"\0" ); } gfRedrawSaveLoadScreen = TRUE; DestroySaveLoadTextInputBoxes(); //if we are loading, if( !gfSaveGame ) { //Enable the save/load button EnableButton( guiSlgSaveLoadBtn ); } //if we are to save if( gfSaveGame ) { if( gbSelectedSaveLocation != ubNewSelection ) { //Destroy the previous region DestroySaveLoadTextInputBoxes(); //reset selected slot gbSelectedSaveLocation = ubNewSelection; //Null out the currently selected save game gzGameDescTextField[0] = '\0'; //Init the text field for the game desc InitSaveLoadScreenTextInputBoxes(); } //Enable the save/load button EnableButton( guiSlgSaveLoadBtn ); } //reset selected slot gbSelectedSaveLocation = ubNewSelection; //Set the selected slot background graphic gbSaveGameSelectedLocation[ gbSelectedSaveLocation ] = SLG_SELECTED_SLOT_GRAPHICS_NUMBER; } UINT8 CompareSaveGameVersion( INT32 bSaveGameID ) { UINT8 ubRetVal=SLS_HEADER_OK; SAVED_GAME_HEADER SaveGameHeader; //Get the heade for the saved game LoadSavedGameHeader( bSaveGameID, &SaveGameHeader ); // check to see if the saved game version in the header is the same as the current version if( SaveGameHeader.uiSavedGameVersion != SAVE_GAME_VERSION ) { ubRetVal = SLS_SAVED_GAME_VERSION_OUT_OF_DATE; } if( strcmp( SaveGameHeader.zGameVersionNumber, czVersionString ) != 0 ) { if( ubRetVal == SLS_SAVED_GAME_VERSION_OUT_OF_DATE ) ubRetVal = SLS_BOTH_SAVE_GAME_AND_GAME_VERSION_OUT_OF_DATE; else ubRetVal = SLS_GAME_VERSION_OUT_OF_DATE; } return( ubRetVal ); } void LoadSavedGameWarningMessageBoxCallBack( UINT8 bExitValue ) { // yes, load the game if( bExitValue == MSG_BOX_RETURN_YES ) { //Setup up the fade routines StartFadeOutForSaveLoadScreen(); } //The user does NOT want to continue.. else { //ask if the user wants to delete all the saved game files DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_DELETE_ALL_SAVE_GAMES], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, LoadSavedGameDeleteAllSaveGameMessageBoxCallBack ); } } void LoadSavedGameDeleteAllSaveGameMessageBoxCallBack( UINT8 bExitValue ) { // yes, Delete all the save game files if( bExitValue == MSG_BOX_RETURN_YES ) { DeleteAllSaveGameFile( ); gfSaveLoadScreenExit = TRUE; } gfExitAfterMessageBox = TRUE; SetSaveLoadExitScreen( OPTIONS_SCREEN ); gbSelectedSaveLocation=-1; } void DeleteAllSaveGameFile( ) { UINT8 cnt,cnt2; for( cnt=0; cnt= _640x480 && iResolution < _800x600) { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_INV_RES_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); NextLoopCheckForEnoughFreeHardDriveSpace(); } else if(UsingNewInventorySystem() == true && IsNIVModeValid(false) == FALSE) { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_INV_CUSTUM_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); NextLoopCheckForEnoughFreeHardDriveSpace(); } else if ((gGameOptions.ubSquadSize == 8 && iResolution < _800x600) || (gGameOptions.ubSquadSize == 10 && iResolution < _1024x768)) { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SQUAD_SIZE_RES_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); NextLoopCheckForEnoughFreeHardDriveSpace(); } else { DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_LOAD_GAME_ERROR], SAVE_LOAD_SCREEN, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack ); NextLoopCheckForEnoughFreeHardDriveSpace(); } } } else { SUCCESSFULLY_CORRECTED_SAVE: #ifdef JA2BETAVERSION ValidateSoldierInitLinks( 1 ); { #endif //If we are to go to map screen after loading the game if( guiScreenToGotoAfterLoadingSavedGame == MAP_SCREEN ) { gFadeInDoneCallback = DoneFadeInForSaveLoadScreen; SetSaveLoadExitScreen( guiScreenToGotoAfterLoadingSavedGame ); FadeInNextFrame( ); } else { //if we are to go to the Tactical screen after loading gFadeInDoneCallback = DoneFadeInForSaveLoadScreen; SetSaveLoadExitScreen( guiScreenToGotoAfterLoadingSavedGame ); PauseTime( FALSE ); FadeInGameScreen( ); } #ifdef JA2UB //JA25 UB // ATE: Validate any new maps... // OK, if we're a camapign, check for new maps //if ( !InDefaultCampaign( ) ) //{ MakeBadSectorListFromMapsOnHardDrive( TRUE ); LetLuaMakeBadSectorListFromMapsOnHardDrive( 0 ); //} #endif #ifdef JA2BETAVERSION } #endif } // Flugente: enforce screen redraw (observed an issue where, on loading a savegame repeatedly, this was not reset, resulting in teampanel not being drawn, causing subsequent crashes) fFirstTimeInGameScreen = TRUE; gfStartedFadingOut = FALSE; } void DoneFadeInForSaveLoadScreen( void ) { //Leave the screen //if we are supposed to stay in tactical, due nothing, //if we are supposed to goto mapscreen, leave tactical and go to mapscreen if( guiScreenToGotoAfterLoadingSavedGame == MAP_SCREEN ) { if( !gfPauseDueToPlayerGamePause ) { UnLockPauseState( ); UnPauseGame( ); } } else { //if the game is currently paused if( GamePaused() ) { //need to call it twice HandlePlayerPauseUnPauseOfGame(); HandlePlayerPauseUnPauseOfGame(); } } } void SelectedSLSEntireRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) { if (iReason & MSYS_CALLBACK_REASON_INIT) { } else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP) { DisableSelectedSlot(); } } void DisableSelectedSlot() { //reset selected slot gbSelectedSaveLocation = -1; gfRedrawSaveLoadScreen = TRUE; DestroySaveLoadTextInputBoxes(); if( !gfSaveGame ) DisableButton( guiSlgSaveLoadBtn ); //reset the selected graphic ClearSelectedSaveSlot(); } void ConfirmSavedGameMessageBoxCallBack( UINT8 bExitValue ) { Assert( gbSelectedSaveLocation != -1 ); // yes, load the game if( bExitValue == MSG_BOX_RETURN_YES ) { SaveGameToSlotNum(); } } void ConfirmLoadSavedGameMessageBoxCallBack( UINT8 bExitValue ) { Assert( gbSelectedSaveLocation != -1 ); // yes, load the game if( bExitValue == MSG_BOX_RETURN_YES ) { //Setup up the fade routines StartFadeOutForSaveLoadScreen(); } else { gfExitAfterMessageBox = FALSE; } } #ifdef JA2BETAVERSION void ErrorDetectedInSaveCallback( UINT8 bValue ) { //If we are to go to map screen after loading the game if( guiScreenToGotoAfterLoadingSavedGame == MAP_SCREEN ) { gFadeInDoneCallback = DoneFadeInForSaveLoadScreen; SetSaveLoadExitScreen( guiScreenToGotoAfterLoadingSavedGame ); FadeInNextFrame( ); } else { //if we are to go to the Tactical screen after loading gFadeInDoneCallback = DoneFadeInForSaveLoadScreen; SetSaveLoadExitScreen( guiScreenToGotoAfterLoadingSavedGame ); FadeInGameScreen( ); } gfStartedFadingOut = TRUE; } #endif void FailedLoadingGameCallBack( UINT8 bExitValue ) { // yes if( bExitValue == MSG_BOX_RETURN_OK ) { //if the current screen is tactical if( guiPreviousOptionScreen == MAP_SCREEN ) { SetPendingNewScreen( MAINMENU_SCREEN ); } else { LeaveTacticalScreen( MAINMENU_SCREEN ); } SetSaveLoadExitScreen( MAINMENU_SCREEN ); //We want to reinitialize the game ReStartingGame(); } } BOOLEAN DoAutoSave( int ubSaveGameID, STR16 pGameDesc ) { if( !SaveGame( ubSaveGameID, pGameDesc ) ) { //Unset the fact that we are saving a game gTacticalStatus.uiFlags &= ~LOADING_SAVED_GAME; if( guiPreviousOptionScreen == MAP_SCREEN ) DoMapMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVE_GAME_ERROR], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL ); else DoMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVE_GAME_ERROR], GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL ); } return( TRUE ); } BOOLEAN DoQuickSave() { gzGameDescTextField[0] = '\0'; if( !SaveGame( 0, gzGameDescTextField ) ) { //Unset the fact that we are saving a game gTacticalStatus.uiFlags &= ~LOADING_SAVED_GAME; if( guiPreviousOptionScreen == MAP_SCREEN ) DoMapMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVE_GAME_ERROR], MAP_SCREEN, MSG_BOX_FLAG_OK, NULL ); else DoMessageBox( MSG_BOX_BASIC_STYLE, zSaveLoadText[SLG_SAVE_GAME_ERROR], GAME_SCREEN, MSG_BOX_FLAG_OK, NULL, NULL ); } return( TRUE ); } BOOLEAN DoQuickLoad() { //Build the save game array InitSaveGameArray(); //if there is no save in the quick save slot if( !gbSaveGameArray[ 0 ] ) return( FALSE ); //Set the selection to be the quick save slot gbSelectedSaveLocation = 0; //if the game is paused, and we are in tactical, unpause if( guiCurrentScreen == GAME_SCREEN ) { PauseTime( FALSE ); } // Remove sound if (uiSoundSample != NO_SAMPLE) { SoundStop(uiSoundSample); } //Do a fade out before we load the game gFadeOutDoneCallback = DoneFadeOutForSaveLoadScreen; FadeOutNextFrame( ); gfStartedFadingOut = TRUE; gfDoingQuickLoad = TRUE; return( TRUE ); } BOOLEAN IsThereAnySavedGameFiles() { UINT8 cnt,newSlot; CHAR8 zSaveGameName[ 512 ]; for( cnt=0; cnt pSlot ) { SetSelection( (UINT8)(gbSelectedSaveLocation-1) ); } } else { //if the selected slot is invalid if( gbSelectedSaveLocation == -1 ) { SetSelection( pSlot ); } else { if( gbSelectedSaveLocation >= pSlot && gbSelectedSaveLocation < NUM_SLOT-1 ) { SetSelection( (UINT8)(gbSelectedSaveLocation + 1) ); } } } } else { if( fUp ) { for( i=gbSelectedSaveLocation-1; i>=0; i--) { if( gbSaveGameArray[VAL_SLOT_START + i] ) { ClearSelectedSaveSlot(); SetSelection( (UINT8)i ); break; } } } else { //if there is no selected slot, move the selected slot to the first slot if( gbSelectedSaveLocation == -1 ) { ClearSelectedSaveSlot(); SetSelection( 0 ); } else { for( i=gbSelectedSaveLocation+1; i