#ifdef PRECOMPILEDHEADERS #include "JA2 All.h" #else #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 "Sys Globals.h" #include "Text.h" #include "Message.h" #include "Map Screen Interface.h" #include "Multi Language Graphic Utils.h" #endif #include "Campaign Init.h" BOOLEAN gfSchedulesHosed = FALSE; extern UINT32 guiBrokenSaveGameVersion; ////////////////////////////////////////////////////// // // 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 2//FONT_MCOLOR_DKWHITE//2//FONT_MCOLOR_WHITE #define SAVE_LOAD_NORMAL_SHADOW_COLOR 118//121//118//125 /*#define SAVE_LOAD_NORMAL_FONT FONT12ARIAL #define SAVE_LOAD_NORMAL_COLOR FONT_MCOLOR_DKWHITE//2//FONT_MCOLOR_WHITE #define SAVE_LOAD_NORMAL_SHADOW_COLOR 2//125 */ #define SAVE_LOAD_QUICKSAVE_FONT FONT12ARIAL #define SAVE_LOAD_QUICKSAVE_COLOR 2//FONT_MCOLOR_DKGRAY//FONT_MCOLOR_WHITE #define SAVE_LOAD_QUICKSAVE_SHADOW_COLOR 189//248//2 #define SAVE_LOAD_EMPTYSLOT_FONT FONT12ARIAL #define SAVE_LOAD_EMPTYSLOT_COLOR 2//125//FONT_MCOLOR_WHITE #define SAVE_LOAD_EMPTYSLOT_SHADOW_COLOR 121//118 #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//145//FONT_MCOLOR_WHITE #define SAVE_LOAD_SELECTED_SHADOW_COLOR 130//2 #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_SAVELOCATION_HEIGHT 30//46 #define SLG_FIRST_SAVED_SPOT_X iScreenWidthOffset + 17 #define SLG_FIRST_SAVED_SPOT_Y iScreenHeightOffset + 49 #define SLG_GAP_BETWEEN_LOCATIONS 35//47 #define SLG_DATE_OFFSET_X 13 #define SLG_DATE_OFFSET_Y 11 #define SLG_SECTOR_OFFSET_X 95//105//114 #define SLG_SECTOR_OFFSET_Y SLG_DATE_OFFSET_Y #define SLG_SECTOR_WIDTH 98 #define SLG_NUM_MERCS_OFFSET_X 196//190//SLG_DATE_OFFSET_X #define SLG_NUM_MERCS_OFFSET_Y SLG_DATE_OFFSET_Y//26 #define SLG_BALANCE_OFFSET_X 260//SLG_SECTOR_OFFSET_X #define SLG_BALANCE_OFFSET_Y SLG_DATE_OFFSET_Y//SLG_NUM_MERCS_OFFSET_Y #define SLG_SAVE_GAME_DESC_X 318//320//204 #define SLG_SAVE_GAME_DESC_Y SLG_DATE_OFFSET_Y//SLG_DATE_OFFSET_Y + 7 #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_SELECTED_SLOT_GRAPHICS_NUMBER 3 #define SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER 2 #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 ]; 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 ]; INT8 gbSelectedSaveLocation=-1; INT8 gbHighLightedLocation=-1; INT8 gbLastHighLightedLocation=-1; INT8 gbSetSlotToBeSelected=-1; UINT32 guiSlgBackGroundImage; UINT32 guiBackGroundAddOns; // The string that will contain the game desc text wchar_t 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 gfHadToMakeBasementLevels = 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; //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 ); ////////////////////////////////////////////////////// // // Function Prototypes // ////////////////////////////////////////////////////// BOOLEAN EnterSaveLoadScreen(); void RenderSaveLoadScreen(); void ExitSaveLoadScreen(); void HandleSaveLoadScreen(); void GetSaveLoadScreenUserInput(); void SaveLoadGameNumber( INT8 bSaveGameID ); BOOLEAN LoadSavedGameHeader( INT8 bEntry, SAVED_GAME_HEADER *pSaveGameHeader ); BOOLEAN DisplaySaveGameEntry( INT8 bEntryID );//, UINT16 usPosY ); BOOLEAN DisplaySaveGameList(); void InitSaveLoadScreenTextInputBoxes(); void DestroySaveLoadTextInputBoxes(); void SetSelection( UINT8 ubNewSelection ); UINT8 CompareSaveGameVersion( INT8 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 FailedSavingGameCallBack( 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(); //ppp ////////////////////////////////////////////////////// // // Code // ////////////////////////////////////////////////////// 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( ); } //If we are currently in the Message box loop // if( gfExitAfterMessageBox ) // ExitSaveLoadScreen(); gfSaveLoadScreenExit = TRUE; guiSaveLoadExitScreen = uiScreen; SetPendingNewScreen( uiScreen ); if( gfDoingQuickLoad ) { fFirstTimeInGameScreen = TRUE; SetPendingNewScreen( uiScreen ); } ExitSaveLoadScreen(); DestroySaveLoadTextInputBoxes(); } BOOLEAN EnterSaveLoadScreen() { INT8 i; VOBJECT_DESC VObjectDesc; UINT16 usPosX = SLG_FIRST_SAVED_SPOT_X; UINT16 usPosY = SLG_FIRST_SAVED_SPOT_Y; // WANNE // Black background //ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0 ); // if( guiPreviousOptionScreen != MAINMENU_SCREEN ) // gbSetSlotToBeSelected = -1; // This is a hack to get sector names , but... if the underground sector is NOT loaded if( !gpUndergroundSectorInfoHead ) { BuildUndergroundSectorInfoList(); gfHadToMakeBasementLevels = TRUE; } else { gfHadToMakeBasementLevels = FALSE; } guiSaveLoadExitScreen = SAVE_LOAD_SCREEN; //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)); guiSlgButtonImage = LoadButtonImage("INTERFACE\\LoadScreenAddOns.sti", -1,6,-1,9,-1 ); // guiSlgButtonImage = UseLoadedButtonImage( guiBackGroundAddOns, -1,9,-1,6,-1 ); //Cancel button // if( gfSaveGame ) // usPosX = SLG_SAVE_CANCEL_POS_X; // else 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 ); } //if we are loading, disable the load button // if( !gfSaveGame ) { SpecifyDisabledButtonStyle( guiSlgSaveLoadBtn, DISABLED_STYLE_HATCHED ); if( gbSetSlotToBeSelected == -1 ) DisableButton( guiSlgSaveLoadBtn ); } usPosX = SLG_FIRST_SAVED_SPOT_X; usPosY = SLG_FIRST_SAVED_SPOT_Y; for(i=0; iuiFlags |= 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 ); } void ExitSaveLoadScreen() { INT8 i; gfLoadGameUponEntry = FALSE; if( !gfSaveLoadScreenButtonsCreated ) return; gfSaveLoadScreenExit = FALSE; gfSaveLoadScreenEntry = TRUE; gfExitAfterMessageBox = FALSE; UnloadButtonImage( guiSlgButtonImage ); RemoveButton( guiSlgCancelBtn ); //Remove the save / load button // if( !gfSaveGame ) { RemoveButton( guiSlgSaveLoadBtn ); UnloadButtonImage( guiSaveLoadImage ); } for(i=0; i= NUM_SAVE_GAMES || bSaveGameID < 0 ) { return; } if( gfSaveGame ) { INT8 bActiveTextField; bActiveTextField = (INT8)GetActiveFieldID(); if( bActiveTextField && bActiveTextField != -1 ) { Get16BitStringFromField( (UINT8)bActiveTextField, gzGameDescTextField ); } //if there is save game in the slot, ask for confirmation before overwriting if( gbSaveGameArray[ bSaveGameID ] ) { CHAR16 sText[512]; swprintf( sText, zSaveLoadText[SLG_CONFIRM_SAVE], bSaveGameID ); DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, sText, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, ConfirmSavedGameMessageBoxCallBack ); } else { //else do NOT put up a confirmation //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 { /* IF YOU UNCOMMENT THIS -- LOCALIZE IT!!! CHAR16 sText[512]; swprintf( sText, L"%s%d?", zSaveLoadText[SLG_CONFIRM_LOAD], bSaveGameID ); DoSaveLoadMessageBox( MSG_BOX_BASIC_STYLE, sText, SAVE_LOAD_SCREEN, MSG_BOX_FLAG_YESNO, ConfirmLoadSavedGameMessageBoxCallBack ); */ //Setup up the fade routines StartFadeOutForSaveLoadScreen(); } } } BOOLEAN DoSaveLoadMessageBoxWithRect( UINT8 ubStyle, INT16 *zString, UINT32 uiExitScreen, UINT16 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 ) ); } template BOOLEAN DoSaveLoadMessageBox( UINT8 ubStyle, string2 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() { INT8 cnt; CHAR8 zSaveGameName[ 512 ]; SAVED_GAME_HEADER SaveGameHeader; for( cnt=0; cnt NUM_SAVE_GAMES ) { memset( &pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); return( FALSE ); } //Get the name of the file CreateSavedGameFileNameFromNumber( bEntry, zSavedGameName ); if( FileExists( zSavedGameName ) ) { // create the save game file hFile = FileOpen( zSavedGameName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE ); if( !hFile ) { FileClose( hFile ); gbSaveGameArray[ 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[ 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[ 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 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 BtnSlgLoadCallback(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 SelectedSaveRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ) { INT8 bActiveTextField; 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 ) { //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; } SetSelection( bSelected ); */ //If we are saving and this is the quick save slot if( gfSaveGame && bSelected == 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; } //Reset the regions for( i=0; iuiFlags &= (~BUTTON_CLICKED_ON ); bTemp = gbHighLightedLocation; gbHighLightedLocation = -1; // DisplaySaveGameList(); 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; } gbLastHighLightedLocation = gbHighLightedLocation; gbHighLightedLocation = (UINT8)MSYS_GetRegionUserData( pRegion, 0 ); DisplaySaveGameEntry( gbLastHighLightedLocation ); DisplaySaveGameEntry( gbHighLightedLocation );//, usPosY ); InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, pRegion->RegionBottomRightX, pRegion->RegionBottomRightY); } } void InitSaveLoadScreenTextInputBoxes() { UINT32 uiStartLoc=0; 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 ); //FONT12ARIAL //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[ 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 ) { // CHAR16 zMouseHelpTextString[256]; // SAVED_GAME_HEADER SaveGameHeader; //if we are loading and there is no entry, return if( !gfSaveGame ) { if( !gbSaveGameArray[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; /* //if we are saving AND it is the currently selected slot if( gfSaveGame && gbSelectedSaveLocation == ubNewSelection ) { //copy over the initial game options memcpy( &SaveGameHeader.sInitialGameOptions, &gGameOptions, sizeof( GAME_OPTIONS ) ); } else { //Get the header for the specified saved game if( !LoadSavedGameHeader( ubNewSelection, &SaveGameHeader ) ) { memset( &SaveGameHeader, 0, sizeof( SaveGameHeader ) ); } } swprintf( zMouseHelpTextString, L"%s: %s\n%s: %s\n%s: %s\n%s: %s", gzGIOScreenText[ GIO_DIF_LEVEL_TEXT ], gzGIOScreenText[ GIO_DIF_LEVEL_TEXT + SaveGameHeader.sInitialGameOptions.ubDifficultyLevel + 1 ], gzGIOScreenText[ GIO_TIMED_TURN_TITLE_TEXT ], gzGIOScreenText[ GIO_TIMED_TURN_TITLE_TEXT + SaveGameHeader.sInitialGameOptions.fTurnTimeLimit + 1], gzGIOScreenText[ GIO_GUN_OPTIONS_TEXT ], gzGIOScreenText[ GIO_GUN_OPTIONS_TEXT + 2 - SaveGameHeader.sInitialGameOptions.fGunNut ], gzGIOScreenText[ GIO_GAME_STYLE_TEXT ], gzGIOScreenText[ GIO_GAME_STYLE_TEXT + (SaveGameHeader.sInitialGameOptions.ubGameStyle == STYLE_SCIFI)?1:0; + 1 ] ); //set the slots help text SetRegionFastHelpText( &gSelectedSaveRegion[ gbSelectedSaveLocation ], zMouseHelpTextString ); */ } UINT8 CompareSaveGameVersion( INT8 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 != guiSavedGameVersion ) { ubRetVal = SLS_SAVED_GAME_VERSION_OUT_OF_DATE; } if( strcmp( SaveGameHeader.zGameVersionNumber, czVersionNumber ) != 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; for( cnt=0; cnt 1 ) { SetSelection( (UINT8)(gbSelectedSaveLocation-1) ); } } else { //if the selected slot is invalid if( gbSelectedSaveLocation == -1 ) { SetSelection( 1 ); } else { if( gbSelectedSaveLocation >= 1 && gbSelectedSaveLocation < NUM_SAVE_GAMES-1 ) { SetSelection( (UINT8)(gbSelectedSaveLocation + 1) ); } } } } else { if( fUp ) { for( i=gbSelectedSaveLocation-1; i>=0; i--) { if( gbSaveGameArray[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