diff --git a/GameSettings.cpp b/GameSettings.cpp index 3263243bc..e81704493 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1150,7 +1150,9 @@ void LoadGameExternalOptions() giTimerIntervals[ NEXTSCROLL ] = (INT16)(giTimerIntervals[ NEXTSCROLL ] / gGameExternalOptions.fScrollSpeedFactor); gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("Graphics Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE); - + + gGameExternalOptions.ubLoadscreenStretchMode = iniReader.ReadInteger("Graphics Settings", "LOADSCREEN_STRETCH_MODE", 0, 0, 2); + if (!is_networked) gGameExternalOptions.gfUseLoadScreenHints = iniReader.ReadBoolean("Graphics Settings","USE_LOADSCREENHINTS", TRUE); else diff --git a/GameSettings.h b/GameSettings.h index 207fa3daf..33c87d168 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -781,6 +781,7 @@ typedef struct INT32 ubEnemiesItemDrop; BOOLEAN gfUseExternalLoadscreens; + UINT32 ubLoadscreenStretchMode; // added by anv BOOLEAN gfUseLoadScreenHints; // added by Flugente UINT32 ubAdditionalDelayUntilLoadScreenDisposal; // added by WANNE to have time to read the load screen hints diff --git a/Loading Screen.cpp b/Loading Screen.cpp index a0641d3b5..2650cc9fb 100644 --- a/Loading Screen.cpp +++ b/Loading Screen.cpp @@ -23,6 +23,7 @@ extern BOOLEAN gfSchedulesHosed; #include "Ja25 Strategic Ai.h" #endif UINT8 gubLastLoadingScreenID = LOADINGSCREEN_NOTHING; +FLOAT fLoadingScreenAspectRatio; //BOOLEAN bShowSmallImage = FALSE; SECTOR_LOADSCREENS gSectorLoadscreens[MAX_SECTOR_LOADSCREENS]; @@ -343,6 +344,62 @@ static void BuildLoadscreenFilename(std::string& dst, const char* path, int reso dst.append(".sti"); } +std::string GetResolutionSuffix(SCREEN_RESOLUTION resolution) +{ + switch (resolution) + { + case _960x540: return "_960x540"; + case _800x600: return "_800x600"; + case _1024x600: return "_1024x600"; + case _1280x720: return "_1280x720"; + case _1024x768: return "_1024x768"; + case _1280x768: return "_1280x768"; + case _1360x768: return "_1360x768"; + case _1366x768: return "_1366x768"; + case _1280x800: return "_1280x800"; + case _1440x900: return "_1440x900"; + case _1600x900: return "_1600x900"; + case _1280x960: return "_1280x960"; + case _1440x960: return "_1440x960"; + case _1770x1000: return "_1770x1000"; + case _1280x1024: return "_1280x1024"; + case _1360x1024: return "_1360x1024"; + case _1600x1024: return "_1600x1024"; + case _1440x1050: return "_1440x1050"; + case _1680x1050: return "_1680x1050"; + case _1920x1080: return "_1920x1080"; + case _1600x1200: return "_1600x1200"; + case _1920x1200: return "_1920x1200"; + case _2560x1440: return "_2560x1440"; + case _2560x1600: return "_2560x1600"; + default: return ""; + } +} + +std::string FindBestFittingLoadscreenFilename(const std::string& baseName, SCREEN_RESOLUTION resolution) +{ + for (SCREEN_RESOLUTION res = resolution; res <= _2560x1600; res = (SCREEN_RESOLUTION)(res + 1)) + { + std::string fileName = baseName + GetResolutionSuffix(res); + if (FileExists((CHAR8*)((fileName + ".png").c_str()))) + { + return fileName + ".png"; + } + + if (FileExists((CHAR8*)((fileName + ".sti").c_str()))) + { + return fileName + ".sti"; + } + } + + if (FileExists((CHAR8*)((baseName + ".png").c_str()))) + { + return baseName + ".png"; + } + + return baseName + ".sti"; +} + //sets up the loadscreen with specified ID, and draws it to the FRAME_BUFFER, //and refreshing the screen with it. void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) @@ -420,27 +477,8 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) } } - std::string strImage; - - BuildLoadscreenFilename(strImage, imagePath.c_str(), 0, imageFormat.c_str()); - strImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile)-1); - - - if ( !FileExists(vs_desc.ImageFile) ) - { - std::string strImage; - BuildLoadscreenFilename(strImage, imagePath.c_str(), 0, "png"); - strImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile) - 1); - - if (!FileExists(vs_desc.ImageFile)) - { - std::string strImage("LOADSCREENS\\"); - - BuildLoadscreenFilename(strImage, LoadScreenNames[1], 0, imageFormat.c_str()); - - strImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile) - 1); - } - } + std::string strImage = FindBestFittingLoadscreenFilename(imagePath, (SCREEN_RESOLUTION)iResolution); + strImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile) - 1); } else { @@ -475,18 +513,41 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) //Blit the background image GetVideoSurface(&hVSurface, uiLoadScreen); - - // Stretch the background image - SrcRect.iLeft = 0; - SrcRect.iTop = 0; - SrcRect.iRight = hVSurface->usWidth; - SrcRect.iBottom = hVSurface->usHeight; - - DstRect.iLeft = 0; - DstRect.iTop = 0; - DstRect.iRight = SCREEN_WIDTH; - DstRect.iBottom = SCREEN_HEIGHT; - + + fLoadingScreenAspectRatio = (FLOAT)hVSurface->usWidth / (FLOAT)hVSurface->usHeight; + FLOAT fScreenAspectRatio = (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT; + + if (gGameExternalOptions.ubLoadscreenStretchMode == 1 || + (gGameExternalOptions.ubLoadscreenStretchMode == 2 && fLoadingScreenAspectRatio > fScreenAspectRatio)) + { + // match height, preserve aspect ratio + INT32 iCalculatedWidth = (INT32)(SCREEN_HEIGHT * fLoadingScreenAspectRatio + 0.5f); + + SrcRect.iLeft = 0; + SrcRect.iTop = 0; + SrcRect.iRight = hVSurface->usWidth; + SrcRect.iBottom = hVSurface->usHeight; + + DstRect.iLeft = (SCREEN_WIDTH - iCalculatedWidth) / 2; + DstRect.iTop = 0; + DstRect.iRight = SCREEN_WIDTH - ((SCREEN_WIDTH - iCalculatedWidth) / 2); + DstRect.iBottom = SCREEN_HEIGHT; + } + else + { + // vanilla (stretch to fit) + // Stretch the background image + SrcRect.iLeft = 0; + SrcRect.iTop = 0; + SrcRect.iRight = hVSurface->usWidth; + SrcRect.iBottom = hVSurface->usHeight; + + DstRect.iLeft = 0; + DstRect.iTop = 0; + DstRect.iRight = SCREEN_WIDTH; + DstRect.iBottom = SCREEN_HEIGHT; + } + BltStretchVideoSurface( FRAME_BUFFER, uiLoadScreen, 0, 0, 0, &SrcRect, &DstRect ); DeleteVideoSurfaceFromIndex( uiLoadScreen ); diff --git a/Loading Screen.h b/Loading Screen.h index fa5bc658b..831c9e2be 100644 --- a/Loading Screen.h +++ b/Loading Screen.h @@ -84,6 +84,8 @@ enum //For use by the game loader, before it can possibly know the situation. extern UINT8 gubLastLoadingScreenID; +extern FLOAT fLoadingScreenAspectRatio; + //returns the UINT8 ID for the specified sector. UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 37eca4c55..3d90f27e3 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -6813,15 +6813,6 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) //Reset the Ai Timer clock giRTAILastUpdateTime = 0; - //if we are in tactical - if( guiScreenToGotoAfterLoadingSavedGame == GAME_SCREEN ) - { - //Initialize the current panel - InitializeCurrentPanel( ); - - SelectSoldier( gusSelectedSoldier, FALSE, TRUE ); - } - uiRelEndPerc += 1; SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." ); RenderProgressBar( 0, 100 ); @@ -6950,6 +6941,15 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) RemoveLoadingScreenProgressBar(); + //if we are in tactical + if (guiScreenToGotoAfterLoadingSavedGame == GAME_SCREEN) + { + //Initialize the current panel + InitializeCurrentPanel(); + + SelectSoldier(gusSelectedSoldier, FALSE, TRUE); + } + // sevenfm: reset sound map ResetSoundMap(); diff --git a/Utils/Animated ProgressBar.cpp b/Utils/Animated ProgressBar.cpp index 652d5f05e..5cdfa0ab6 100644 --- a/Utils/Animated ProgressBar.cpp +++ b/Utils/Animated ProgressBar.cpp @@ -14,6 +14,7 @@ #include "WordWrap.h" #include "Message.h" #include "Text.h" + #include "Loading Screen.h" double rStart, rEnd; double rActual; @@ -63,10 +64,31 @@ void CreateLoadingScreenProgressBar(BOOLEAN resetLoadScreenHint) // CreateProgressBar(0, 259 + ((SCREEN_WIDTH - 1024) / 2), 683 + ((SCREEN_HEIGHT - 768) / 2), 767 + ((SCREEN_WIDTH - 1024) / 2), 708 + ((SCREEN_HEIGHT - 768) / 2)); // } //} - - CreateProgressBar(0, SCREEN_WIDTH*162/640, SCREEN_HEIGHT*427/480, SCREEN_WIDTH*480/640, SCREEN_HEIGHT*443/480); + FLOAT fScreenAspectRatio = (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT; + + if (gGameExternalOptions.ubLoadscreenStretchMode == 1 || + (gGameExternalOptions.ubLoadscreenStretchMode == 2 && fLoadingScreenAspectRatio > fScreenAspectRatio)) + { + // match height, preserve aspect ratioernalOptions.ubLoadscreenStretchMode == 2 && fLoadingScreenAspectRatio > fScreenAspectRatio)) + INT32 iCalculatedWidth = (INT32)(SCREEN_HEIGHT * fLoadingScreenAspectRatio + 0.5f); + + UINT16 usLeft = (UINT16)((SCREEN_WIDTH - iCalculatedWidth) / 2 + (iCalculatedWidth * 162.0f / 640.0f) + 0.5f); + UINT16 usTop = (UINT16)((SCREEN_HEIGHT * 427.0f / 480.0f) + 0.5f); + UINT16 usRight = (UINT16)((SCREEN_WIDTH - iCalculatedWidth) / 2 + (iCalculatedWidth * 478.0f / 640.0f) + 0.5f); + UINT16 usBottom = (UINT16)((SCREEN_HEIGHT * 443.0f / 480.0f) + 0.5f); + + CreateProgressBar(0, usLeft, usTop, usRight, usBottom); + } + else + { + UINT16 usLeft = (UINT16)((SCREEN_WIDTH * 162.0f / 640.0f) + 0.5f); + UINT16 usTop = (UINT16)((SCREEN_HEIGHT * 427.0f / 480.0f) + 0.5f); + UINT16 usRight = (UINT16)((SCREEN_WIDTH * 478.0f / 640.0f) + 0.5f); + UINT16 usBottom = (UINT16)((SCREEN_HEIGHT * 443.0f / 480.0f) + 0.5f); + CreateProgressBar(0, usLeft, usTop, usRight, usBottom); + } SetProgressBarUseBorder(0, FALSE ); } @@ -334,6 +356,8 @@ void SetRelativeStartAndEndPercentage( UINT8 ubID, UINT16 uiRelStartPerc, UINT16 pCurr->rStart = (double)uiRelStartPerc*0.01f; pCurr->rEnd = (double)uiRelEndPerc*0.01f; + UINT8 yTextOffset = (UINT8)(3.0f * SCREEN_HEIGHT / 480.0f + 0.5f); + //Render the entire panel now, as it doesn't need update during the normal rendering if( pCurr->fPanel ) { @@ -352,7 +376,7 @@ void SetRelativeStartAndEndPercentage( UINT8 ubID, UINT16 uiRelStartPerc, UINT16 usStartX = pCurr->usPanelLeft + // left position (pCurr->usPanelRight - pCurr->usPanelLeft)/2 - // + half width StringPixLength( pCurr->swzTitle, pCurr->usTitleFont ) / 2; // - half string width - usStartY = pCurr->usPanelTop + 3; + usStartY = pCurr->usPanelTop + yTextOffset; SetFont( pCurr->usTitleFont ); SetFontForeground( pCurr->ubTitleFontForeColor ); SetFontShadow( pCurr->ubTitleFontShadowColor ); @@ -370,21 +394,21 @@ void SetRelativeStartAndEndPercentage( UINT8 ubID, UINT16 uiRelStartPerc, UINT16 { UINT16 usFontHeight = GetFontHeight( pCurr->usMsgFont ); - RestoreExternBackgroundRect( pCurr->usBarLeft, pCurr->usBarBottom, (INT16)(pCurr->usBarRight-pCurr->usBarLeft), (INT16)(usFontHeight + 3) ); + RestoreExternBackgroundRect( pCurr->usBarLeft, pCurr->usBarBottom, (INT16)(pCurr->usBarRight-pCurr->usBarLeft), (INT16)(usFontHeight + yTextOffset) ); } SetFont( pCurr->usMsgFont ); SetFontForeground( pCurr->ubMsgFontForeColor ); SetFontShadow( pCurr->ubMsgFontShadowColor ); SetFontBackground( 0 ); - mprintf( pCurr->usBarLeft, pCurr->usBarBottom + 3, str ); + mprintf( pCurr->usBarLeft, pCurr->usBarBottom + yTextOffset, str ); } } // Flugente: loadscreen hints if (gGameExternalOptions.gfUseLoadScreenHints && usCurrentLoadScreenHint ) { - ShowLoadScreenHintInLoadScreen(pCurr->usBarBottom + 3 - 100); + ShowLoadScreenHintInLoadScreen(pCurr->usBarBottom + yTextOffset - 100); } } @@ -408,25 +432,24 @@ void RenderProgressBar( UINT8 ubID, UINT32 uiPercentage ) if( pCurr ) { - rActual = pCurr->rStart+(pCurr->rEnd-pCurr->rStart)*uiPercentage*0.01; + rActual = pCurr->rStart + (pCurr->rEnd - pCurr->rStart) * uiPercentage * 0.01; - if( fabs(rActual - pCurr->rLastActual) < 0.01 ) + pCurr->rLastActual = (DOUBLE)((INT32)(std::round(rActual * 100)) * 0.01); + + end = (INT32)(pCurr->usBarLeft + std::round(rActual * (pCurr->usBarRight - pCurr->usBarLeft))); + if (end < pCurr->usBarLeft) { - return; + end = pCurr->usBarLeft; } - - pCurr->rLastActual = ( DOUBLE )( ( INT32)( rActual * 100 ) * 0.01 ); - - end = (INT32)(pCurr->usBarLeft+2.0+rActual*(pCurr->usBarRight-pCurr->usBarLeft-4)); - if( end < pCurr->usBarLeft+2 || end > pCurr->usBarRight-2 ) + else if (end > pCurr->usBarRight) { - return; + end = pCurr->usBarRight; } if( !pCurr->fDrawBorder ) { ColorFillVideoSurfaceArea( pCurr->uiFrameBuffer, //FRAME_BUFFER, pCurr->usBarLeft, pCurr->usBarTop, end, pCurr->usBarBottom, - Get16BPPColor(FROMRGB( pCurr->ubColorFillRed, pCurr->ubColorFillGreen, pCurr->ubColorFillBlue )) ); + Get16BPPColor(FROMRGB(pCurr->ubColorFillRed, pCurr->ubColorFillGreen, pCurr->ubColorFillBlue))); //if( pCurr->usBarRight > gusLeftmostShaded ) //{ // ShadowVideoSurfaceRect( FRAME_BUFFER, gusLeftmostShaded+1, pCurr->usBarTop, end, pCurr->usBarBottom ); @@ -493,7 +516,7 @@ void SetProgressBarTextDisplayFlag( UINT8 ubID, BOOLEAN fDisplayText, BOOLEAN fU //if we are to use the save buffer, blit the portion of the screen to the save buffer if( fSaveScreenToFrameBuffer ) { - UINT16 usFontHeight = GetFontHeight( pCurr->usMsgFont )+3; + UINT16 usFontHeight = GetFontHeight(pCurr->usMsgFont) + (UINT8)(3.0f * SCREEN_HEIGHT / 480.f + 0.5f); //blit everything to the save buffer ( cause the save buffer can bleed through ) BlitBufferToBuffer(guiRENDERBUFFER, guiSAVEBUFFER, pCurr->usBarLeft, pCurr->usBarBottom, (UINT16)(pCurr->usBarRight-pCurr->usBarLeft), usFontHeight );