From 489743da419b0da842e82dc6d430f6f3d8752055 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 14 Aug 2020 17:34:04 +0300 Subject: [PATCH 1/6] Darkel fixes --- src/control/Darkel.cpp | 16 +++++++++++----- src/control/Darkel.h | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index cfd58340..02627f33 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -30,9 +30,9 @@ int8 CDarkel::InterruptedWeapon; * makes game handle sounds & messages instead of SCM (just like in GTA2) * but it's never been used in the game. Has unused sliding text when frenzy completed etc. */ -int8 CDarkel::bStandardSoundAndMessages; -int8 CDarkel::bNeedHeadShot; -int8 CDarkel::bProperKillFrenzy; +bool CDarkel::bStandardSoundAndMessages; +bool CDarkel::bNeedHeadShot; +bool CDarkel::bProperKillFrenzy; uint16 CDarkel::Status; uint16 CDarkel::RegisteredKills[NUM_DEFAULT_MODELS]; int32 CDarkel::ModelToKill; @@ -108,9 +108,15 @@ CDarkel::DrawMessages() sprintf(gString, "%d", (CDarkel::KillsNeeded >= 0 ? CDarkel::KillsNeeded : 0)); AsciiToUnicode(gString, gUString); CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString); +#ifdef FIX_BUGS +#define DARKEL_COUNTER_HEIGHT 143.0f +#else +#define DARKEL_COUNTER_HEIGHT 128.0f +#endif + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT + 1.0f), gUString); CFont::SetColor(CRGBA(255, 128, 128, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(143.0f), gUString); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT), gUString); +#undef DARKEL_COUNTER_HEIGHT break; } case KILLFRENZY_PASSED: diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 14529c63..0f5c2329 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -24,9 +24,9 @@ private: static int32 AmmoInterruptedWeapon; static int32 KillsNeeded; static int8 InterruptedWeapon; - static int8 bStandardSoundAndMessages; - static int8 bNeedHeadShot; - static int8 bProperKillFrenzy; + static bool bStandardSoundAndMessages; + static bool bNeedHeadShot; + static bool bProperKillFrenzy; static uint16 Status; static uint16 RegisteredKills[NUM_DEFAULT_MODELS]; static int32 ModelToKill; From e7945625b59750459ff4876f7e076b4b8d5c3aee Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 14 Aug 2020 18:57:23 +0300 Subject: [PATCH 2/6] Original screen grabber --- src/core/FileMgr.h | 1 + src/core/main.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/skel/glfw/glfw.cpp | 16 ++++++++++++++++ src/skel/platform.h | 1 + src/skel/skeleton.cpp | 9 +++++++++ src/skel/skeleton.h | 3 +++ src/skel/win/win.cpp | 17 +++++++++++++++++ 7 files changed, 85 insertions(+) diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h index 0ad9daa7..4734720e 100644 --- a/src/core/FileMgr.h +++ b/src/core/FileMgr.h @@ -19,4 +19,5 @@ public: static bool ReadLine(int fd, char *buf, int len); static int CloseFile(int fd); static int GetErrorReadWrite(int fd); + static char *GetRootDirName() { return ms_rootDirName; } }; diff --git a/src/core/main.cpp b/src/core/main.cpp index b63688ec..8458a248 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -2,6 +2,7 @@ #include "rpmatfx.h" #include "rphanim.h" #include "rpskin.h" +#include "rtbmp.h" #include "main.h" #include "CdStream.h" @@ -61,6 +62,7 @@ #include "MemoryCard.h" #include "SceneEdit.h" #include "debugmenu.h" +#include "Clock.h" GlobalScene Scene; @@ -288,6 +290,28 @@ DoFade(void) } } +bool +RwGrabScreen(RwCamera *camera, RwChar *filename) +{ + char temp[255]; + RwImage *pImage = RsGrabScreen(camera); + bool result = true; + + if (pImage == nil) + return false; + + strcpy(temp, CFileMgr::GetRootDirName()); + strcat(temp, filename); + + if (RtBMPImageWrite(pImage, &temp[0]) == nil) + result = false; + RwImageDestroy(pImage); + return result; +} + +#define TILE_WIDTH 576 +#define TILE_HEIGHT 432 + void DoRWStuffEndOfFrame(void) { @@ -296,6 +320,20 @@ DoRWStuffEndOfFrame(void) FlushObrsPrintfs(); RwCameraEndUpdate(Scene.camera); RsCameraShowRaster(Scene.camera); +#ifndef MASTER + char s[48]; + if (CPad::GetPad(1)->GetLeftShockJustDown()) { + // try using both controllers for this thing... crazy bastards + if (CPad::GetPad(0)->GetRightStickY() > 0) { + sprintf(s, "screen%d%d.ras", CClock::ms_nGameClockHours, CClock::ms_nGameClockMinutes); + // TODO + //RtTileRender(Scene.camera, TILE_WIDTH * 2, TILE_HEIGHT * 2, TILE_WIDTH, TILE_HEIGHT, &NewTileRendererCB, nil, s); + } else { + sprintf(s, "screen%d%d.bmp", CClock::ms_nGameClockHours, CClock::ms_nGameClockMinutes); + RwGrabScreen(Scene.camera, s); + } + } +#endif // !MASTER } static RwBool diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index ed442348..920bb8a9 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -181,6 +181,22 @@ psCameraShowRaster(RwCamera *camera) return; } +/* + ***************************************************************************** + */ +RwImage * +psGrabScreen(RwCamera *pCamera) +{ +#ifndef LIBRW + RwRaster *pRaster = RwCameraGetRaster(pCamera); + if (RwImage *pImage = RwImageCreate(pRaster->width, pRaster->height, 32)) { + RwImageAllocatePixels(pImage); + RwImageSetFromRaster(pImage, pRaster); + return pImage; + } +#endif + return nil; +} /* ***************************************************************************** diff --git a/src/skel/platform.h b/src/skel/platform.h index 0f314b9d..c9a8a11f 100644 --- a/src/skel/platform.h +++ b/src/skel/platform.h @@ -22,6 +22,7 @@ extern void psTerminate(void); extern void psCameraShowRaster(RwCamera *camera); extern RwBool psCameraBeginUpdate(RwCamera *camera); +extern RwImage *psGrabScreen(RwCamera *camera); extern void psMouseSetPos(RwV2d *pos); diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp index 8191107e..4780316a 100644 --- a/src/skel/skeleton.cpp +++ b/src/skel/skeleton.cpp @@ -50,6 +50,15 @@ RsCameraBeginUpdate(RwCamera * camera) return psCameraBeginUpdate(camera); } +/* + ***************************************************************************** + */ +RwImage* +RsGrabScreen(RwCamera *camera) +{ + return psGrabScreen(camera); +} + /* ***************************************************************************** */ diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h index b5ea5abf..1c468179 100644 --- a/src/skel/skeleton.h +++ b/src/skel/skeleton.h @@ -274,6 +274,9 @@ RsCameraBeginUpdate(RwCamera *camera); //extern void //RsMouseSetVisibility(RwBool visible); +extern RwImage* +RsGrabScreen(RwCamera *camera); + extern void RsMouseSetPos(RwV2d *pos); diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index cf4749b1..a064788c 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -238,6 +238,23 @@ psCameraShowRaster(RwCamera *camera) } +/* + ***************************************************************************** + */ +RwImage * +psGrabScreen(RwCamera *pCamera) +{ +#ifndef LIBRW + RwRaster *pRaster = RwCameraGetRaster(pCamera); + if (RwImage *pImage = RwImageCreate(pRaster->width, pRaster->height, 32)) { + RwImageAllocatePixels(pImage); + RwImageSetFromRaster(pImage, pRaster); + return pImage; + } +#endif + return nil; +} + /* ***************************************************************************** */ From 72088a000b6fc0d641f5b94f6aa6586e9e2d9e8b Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 14 Aug 2020 19:42:15 +0300 Subject: [PATCH 3/6] Don't react if player's targeting with melee --- src/peds/Ped.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index f52b373e..a15927ff 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -10232,7 +10232,11 @@ CPed::ProcessControl(void) CPed::Chat(); break; case PED_AIM_GUN: - if (m_pPointGunAt && m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, CAN_SEE_ENTITY_ANGLE_THRESHOLD * 2)) { + if (m_pPointGunAt && m_pPointGunAt->IsPed() +#ifdef FIX_BUGS + && !GetWeapon()->IsTypeMelee() +#endif + && ((CPed*)m_pPointGunAt)->CanSeeEntity(this, CAN_SEE_ENTITY_ANGLE_THRESHOLD * 2)) { ((CPed*)m_pPointGunAt)->ReactToPointGun(this); } PointGunAt(); From a728a542be7b3cf5dde16184dea071c50fdd38c0 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Sun, 16 Aug 2020 01:37:09 +0300 Subject: [PATCH 4/6] Graphics menu + MSAA --- gamefiles/TEXT/american.gxt | Bin 218862 -> 219054 bytes src/core/Frontend.cpp | 215 ++++++++++++++++++++++++++++++++++-- src/core/Frontend.h | 22 +++- src/core/MenuScreens.cpp | 85 ++++++++++++-- src/core/config.h | 9 +- src/core/re3.cpp | 28 ++--- src/skel/win/win.cpp | 4 +- utils/gxt/american.txt | 15 +++ utils/gxt/gxt.exe | Bin 70656 -> 125440 bytes 9 files changed, 341 insertions(+), 37 deletions(-) diff --git a/gamefiles/TEXT/american.gxt b/gamefiles/TEXT/american.gxt index 6d74c7aac80771fd31ea82bf5af5133058663e22..35973f660f153bb8b22e5df638f13a624686380e 100644 GIT binary patch delta 312 zcmaF2mUrEHUe*wA*T@qaS=04-xo$BrxVgH-J30n4culUysgN=;bGr;w delta 120 zcmZ3tp7-5aUe*wA*T|lYtm*o^Z*DR%xVgH-J30n4=uEEEkLTvN1rc%c^qKr#Uy||4 zWKM&AaXYAJNRSUh!a0bFaL?e)yA3unZmux0VBEaN_y*hN1y&|bj6uy;Yuc~YFmAtE N!*u=T^iyHXbpWC8E4csw diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 95d5f6e6..df65f94f 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -116,6 +116,12 @@ int32 CMenuManager::m_PrefsSfxVolume = 102; bool CMenuManager::m_PrefsCutsceneBorders = true; #endif + +#ifdef MULTISAMPLING +int8 CMenuManager::m_nPrefsMSAALevel = 0; +int8 CMenuManager::m_nDisplayMSAALevel = 0; +#endif + char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; int32 CMenuManager::m_KeyPressedCode = -1; @@ -399,8 +405,15 @@ CMenuManager::ThingsToDoBeforeGoingBack() DMAudio.StopFrontEndTrack(); OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); #endif +#ifdef GRAPHICS_MENU_OPTIONS } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#else + } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif m_nDisplayVideoMode = m_nPrefsVideoMode; +#ifdef MULTISAMPLING + m_nDisplayMSAALevel = m_nPrefsMSAALevel; +#endif } if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { @@ -848,7 +861,7 @@ CMenuManager::Draw() CFont::SetCentreOn(); break; case MENUPAGE_SOUND_SETTINGS: - case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_DISPLAY_SETTINGS: case MENUPAGE_MULTIPLAYER_CREATE: case MENUPAGE_SKIN_SELECT_OLD: case MENUPAGE_CONTROLLER_PC_OLD1: @@ -856,7 +869,10 @@ CMenuManager::Draw() case MENUPAGE_CONTROLLER_PC_OLD3: case MENUPAGE_CONTROLLER_PC_OLD4: case MENUPAGE_CONTROLLER_DEBUG: - case MENUPAGE_MOUSE_CONTROLS: + case MENUPAGE_MOUSE_CONTROLS: +#ifdef GRAPHICS_MENU_OPTIONS + case MENUPAGE_GRAPHICS_SETTINGS: +#endif columnWidth = 50; headerHeight = 0; lineHeight = 20; @@ -1155,6 +1171,25 @@ CMenuManager::Draw() AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp); rightText = unicodeTemp; break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENFORMAT: + rightText = TheText.Get(FrontEndMenuManager.m_nSelectedScreenMode ? "FED_WND" : "FED_FLS"); + break; +#endif +#ifdef MULTISAMPLING + case MENUACTION_MULTISAMPLING: + switch (m_nDisplayMSAALevel) { + case 0: + rightText = TheText.Get("FEM_OFF"); + break; + default: + sprintf(gString, "%iX", 1 << (m_nDisplayMSAALevel)); + AsciiToUnicode(gString, unicodeTemp); + rightText = unicodeTemp; + break; + } + break; +#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == -1) rightText = TheText.Get("FEA_NAH"); @@ -1205,6 +1240,11 @@ CMenuManager::Draw() case MENUACTION_MOUSESTEER: rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON"); break; +#ifdef CUTSCENE_BORDERS_SWITCH + case MENUACTION_CUTSCENEBORDERS: + rightText = TheText.Get(m_PrefsCutsceneBorders ? "FEM_ON" : "FEM_OFF"); + break; +#endif #ifdef CUSTOM_FRONTEND_OPTIONS case MENUACTION_TRIGGERFUNC: FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; @@ -1306,7 +1346,14 @@ CMenuManager::Draw() CFont::SetRightJustifyOn(); if(textLayer == 1) - if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") + if((!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") +#ifdef IMPROVED_VIDEOMODE + || !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEM_SCF") +#endif +#ifdef MULTISAMPLING + || !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_AAS") +#endif + ) && !m_bGameNotLoaded #ifdef CUSTOM_FRONTEND_OPTIONS || isOptionDisabled @@ -1331,6 +1378,18 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1) ResetHelperText(); } +#ifdef IMPROVED_VIDEOMODE + if (m_nSelectedScreenMode == m_nPrefsWindowed) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_SCF") && m_nHelperTextMsgId == 1) + ResetHelperText(); + } +#endif +#ifdef MULTISAMPLING + if (m_nDisplayMSAALevel == m_nPrefsMSAALevel) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_AAS") && m_nHelperTextMsgId == 1) + ResetHelperText(); + } +#endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH")) SetHelperText(1); @@ -1339,6 +1398,18 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES")) SetHelperText(1); } +#ifdef IMPROVED_VIDEOMODE + if (m_nSelectedScreenMode != m_nPrefsWindowed) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_SCF")) + SetHelperText(1); + } +#endif +#ifdef MULTISAMPLING + if (m_nDisplayMSAALevel != m_nPrefsMSAALevel) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_AAS")) + SetHelperText(1); + } +#endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != -1) { @@ -1349,11 +1420,41 @@ CMenuManager::Draw() } if (m_nDisplayVideoMode != m_nPrefsVideoMode) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 - && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#ifdef GRAPHICS_MENU_OPTIONS + && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#else + && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif m_nDisplayVideoMode = m_nPrefsVideoMode; SetHelperText(3); } } +#ifdef IMPROVED_VIDEOMODE + if (m_nSelectedScreenMode != m_nPrefsWindowed) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_SCF") != 0 +#ifdef GRAPHICS_MENU_OPTIONS + && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#else + && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif + m_nSelectedScreenMode = m_nPrefsWindowed; + SetHelperText(3); + } + } +#endif +#ifdef MULTISAMPLING + if (m_nSelectedScreenMode != m_nPrefsWindowed) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_AAS") != 0 +#ifdef GRAPHICS_MENU_OPTIONS + && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#else + && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif + m_nDisplayMSAALevel = m_nPrefsMSAALevel; + SetHelperText(3); + } + } +#endif #ifdef CUSTOM_FRONTEND_OPTIONS if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { @@ -1419,10 +1520,13 @@ CMenuManager::Draw() switch (m_nCurrScreen) { case MENUPAGE_CONTROLLER_SETTINGS: case MENUPAGE_SOUND_SETTINGS: - case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_DISPLAY_SETTINGS: case MENUPAGE_SKIN_SELECT: case MENUPAGE_CONTROLLER_PC: case MENUPAGE_MOUSE_CONTROLS: +#ifdef GRAPHICS_MENU_OPTIONS + case MENUPAGE_GRAPHICS_SETTINGS: +#endif DisplayHelperText(); break; } @@ -2079,7 +2183,7 @@ CMenuManager::DrawFrontEnd() bbNames[0] = { "FEB_SAV",MENUPAGE_NEW_GAME }; bbNames[1] = { "FEB_CON",MENUPAGE_CONTROLLER_PC }; bbNames[2] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS }; - bbNames[3] = { "FEB_DIS",MENUPAGE_GRAPHICS_SETTINGS }; + bbNames[3] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS }; bbNames[4] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS }; bbNames[5] = { "FESZ_QU",MENUPAGE_EXIT }; bbTabCount = 6; @@ -2091,7 +2195,7 @@ CMenuManager::DrawFrontEnd() bbNames[2] = { "FEB_BRI",MENUPAGE_BRIEFS }; bbNames[3] = { "FEB_CON",MENUPAGE_CONTROLLER_PC }; bbNames[4] = { "FEB_AUD",MENUPAGE_SOUND_SETTINGS }; - bbNames[5] = { "FEB_DIS",MENUPAGE_GRAPHICS_SETTINGS }; + bbNames[5] = { "FEB_DIS",MENUPAGE_DISPLAY_SETTINGS }; bbNames[6] = { "FEB_LAN",MENUPAGE_LANGUAGE_SETTINGS }; bbNames[7] = { "FESZ_QU",MENUPAGE_EXIT }; bbTabCount = 8; @@ -2212,7 +2316,7 @@ CMenuManager::DrawFrontEndNormal() case MENUPAGE_DELETE_SLOT_CONFIRM: currentSprite = FE_ICONSAVE; break; - case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_DISPLAY_SETTINGS: currentSprite = FE_ICONDISPLAY; break; case MENUPAGE_SOUND_SETTINGS: @@ -3224,6 +3328,10 @@ CMenuManager::LoadSettings() #endif #ifdef CUTSCENE_BORDERS_SWITCH CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); +#endif +#ifdef MULTISAMPLING + CFileMgr::Read(fileHandle, (char *)&m_nPrefsMSAALevel, 1); + m_nDisplayMSAALevel = m_nPrefsMSAALevel; #endif } } @@ -3320,6 +3428,9 @@ CMenuManager::SaveSettings() #endif #ifdef CUTSCENE_BORDERS_SWITCH CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); +#endif +#ifdef MULTISAMPLING + CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_nPrefsMSAALevel, 1); #endif } @@ -4638,7 +4749,27 @@ CMenuManager::ProcessButtonPresses(void) SetHelperText(0); SaveSettings(); } + break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENFORMAT: + if (m_nSelectedScreenMode != m_nPrefsWindowed) { + m_nPrefsWindowed = m_nSelectedScreenMode; + _psSelectScreenVM(m_nPrefsVideoMode); + SetHelperText(0); + SaveSettings(); + } break; +#endif +#ifdef MULTISAMPLING + case MENUACTION_MULTISAMPLING: + if (m_nDisplayMSAALevel != m_nPrefsMSAALevel) { + m_nPrefsMSAALevel = m_nDisplayMSAALevel; + _psSelectScreenVM(m_nPrefsVideoMode); + SetHelperText(0); + SaveSettings(); + } + break; +#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4685,7 +4816,8 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.SetRadioInCar(m_PrefsRadioStation); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); SaveSettings(); - } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { +#ifndef GRAPHICS_MENU_OPTIONS + } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { m_PrefsFrameLimiter = true; m_PrefsBrightness = 256; m_PrefsVsyncDisp = true; @@ -4706,8 +4838,40 @@ CMenuManager::ProcessButtonPresses(void) } #else CMBlur::BlurOn = true; +#endif +#ifdef CUTSCENE_BORDERS_SWITCH + m_PrefsCutsceneBorders = true; #endif SaveSettings(); +#else + } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { + m_PrefsBrightness = 256; + m_PrefsShowSubtitles = true; +#ifdef CUTSCENE_BORDERS_SWITCH + m_PrefsCutsceneBorders = true; +#endif + SaveSettings(); + } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { + m_PrefsFrameLimiter = true; + m_PrefsUseWideScreen = false; + m_PrefsVsyncDisp = true; + m_PrefsLOD = 1.2f; + m_PrefsVsync = true; + CRenderer::ms_lodDistScale = 1.2f; + m_nDisplayVideoMode = m_nPrefsVideoMode; +#ifdef GTA3_1_1_PATCH + if (_dwOperatingSystemVersion == OS_WIN98) { + CMBlur::BlurOn = false; + CMBlur::MotionBlurClose(); + } else { + CMBlur::BlurOn = true; + CMBlur::MotionBlurOpen(Scene.camera); + } +#else + CMBlur::BlurOn = true; +#endif // GTA3_1_1_PATCH + SaveSettings(); +#endif // GRAPHICS_MENU_OPTIONS } else if ((m_nCurrScreen != MENUPAGE_SKIN_SELECT_OLD) && (m_nCurrScreen == MENUPAGE_CONTROLLER_PC)) { ControlsManager.MakeControllerActionsBlank(); ControlsManager.InitDefaultControlConfiguration(); @@ -4966,6 +5130,32 @@ CMenuManager::ProcessButtonPresses(void) } } break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENFORMAT: + if (m_bGameNotLoaded) { + FrontEndMenuManager.m_nSelectedScreenMode = !FrontEndMenuManager.m_nSelectedScreenMode; + } + break; +#endif +#ifdef MULTISAMPLING + case MENUACTION_MULTISAMPLING: + if (m_bGameNotLoaded) { + m_nDisplayMSAALevel += changeValueBy; + + int i = 0; + int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels(); + while (maxAA != 1) { + i++; + maxAA >>= 1; + } + + if (m_nDisplayMSAALevel < 0) + m_nDisplayMSAALevel = i; + else if (m_nDisplayMSAALevel > i) + m_nDisplayMSAALevel = 0; + } + break; +#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != -1) { m_nPrefsAudio3DProviderIndex += changeValueBy; @@ -5131,6 +5321,13 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; +#ifdef CUTSCENE_BORDERS_SWITCH + case MENUACTION_CUTSCENEBORDERS: + m_PrefsCutsceneBorders = !m_PrefsCutsceneBorders; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + SaveSettings(); + break; +#endif } } diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 7b0e2f4b..c9af7c10 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -183,7 +183,7 @@ enum eMenuScreen MENUPAGE_BRIEFS = 3, MENUPAGE_CONTROLLER_SETTINGS = 4, MENUPAGE_SOUND_SETTINGS = 5, - MENUPAGE_GRAPHICS_SETTINGS = 6, + MENUPAGE_DISPLAY_SETTINGS = 6, MENUPAGE_LANGUAGE_SETTINGS = 7, MENUPAGE_CHOOSE_LOAD_SLOT = 8, MENUPAGE_CHOOSE_DELETE_SLOT = 9, @@ -238,6 +238,9 @@ enum eMenuScreen MENUPAGE_58 = 58, #ifdef MENU_MAP MENUPAGE_MAP = 59, +#endif +#ifdef GRAPHICS_MENU_OPTIONS + MENUPAGE_GRAPHICS_SETTINGS, #endif MENUPAGES }; @@ -359,6 +362,19 @@ enum eMenuAction MENUACTION_UNK112, MENUACTION_REJECT_RETRY, MENUACTION_UNK114, +#ifdef IMPROVED_VIDEOMODE + MENUACTION_SCREENFORMAT, +#endif +#ifdef ANISOTROPIC_FILTERING + MENUACTION_MIPMAPS, + MENUACTION_TEXTURE_FILTERING, +#endif +#ifdef MULTISAMPLING + MENUACTION_MULTISAMPLING, +#endif +#ifdef CUTSCENE_BORDERS_SWITCH + MENUACTION_CUTSCENEBORDERS, +#endif #ifdef CUSTOM_FRONTEND_OPTIONS MENUACTION_TRIGGERFUNC #endif @@ -532,6 +548,10 @@ public: int32 m_nPrefsSubsystem; int32 m_nSelectedScreenMode; #endif +#ifdef MULTISAMPLING + static int8 m_nPrefsMSAALevel; + static int8 m_nDisplayMSAALevel; +#endif enum LANGUAGE { diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 4685918e..c313944c 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -4,6 +4,32 @@ // If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp. +#ifdef CUTSCENE_BORDERS_SWITCH +#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, +#else +#define MENU_CUTSCENE_BORDERS_SWITCH(screen) +#endif + +#ifdef IMPROVED_VIDEOMODE +#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen, +#else +#define MENU_IMPROVED_VIDEOMODE(screen) +#endif + +#ifdef ANISOTROPIC_FILTERING +#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen, +#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen, +#else +#define MENU_MIPMAPS(screen) +#define MENU_TEXTURE_FILTERING(screen) +#endif + +#ifdef MULTISAMPLING +#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen, +#else +#define MENU_MULTISAMPLING(screen) +#endif + CMenuScreen aScreens[] = { // MENUPAGE_NONE = 0 { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, @@ -46,19 +72,35 @@ CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, - // MENUPAGE_GRAPHICS_SETTINGS = 6 + // MENUPAGE_DISPLAY_SETTINGS = 6 +#ifndef GRAPHICS_MENU_OPTIONS { "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2, - MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENU_CUTSCENE_BORDERS_SWITCH(MENUPAGE_DISPLAY_SETTINGS) + MENU_MIPMAPS(MENUPAGE_DISPLAY_SETTINGS) + MENU_TEXTURE_FILTERING(MENUPAGE_DISPLAY_SETTINGS) + MENU_MULTISAMPLING(MENUPAGE_DISPLAY_SETTINGS) + MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENU_IMPROVED_VIDEOMODE(MENUPAGE_DISPLAY_SETTINGS) + MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, +#else + { "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2, + MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENU_CUTSCENE_BORDERS_SWITCH(MENUPAGE_DISPLAY_SETTINGS) + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, + MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, + }, +#endif // GRAPHICS_MENU_OPTIONS + // MENUPAGE_LANGUAGE_SETTINGS = 7 { "FET_LAN", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3, @@ -322,7 +364,10 @@ CMenuScreen aScreens[] = { { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4, MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, +#ifdef GRAPHICS_MENU_OPTIONS + MENUACTION_CHANGEMENU, "FET_GRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, +#endif MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, MENUACTION_PLAYERSETUP, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, @@ -446,6 +491,24 @@ CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, #endif + +#ifdef GRAPHICS_MENU_OPTIONS + // MENUPAGE_GRAPHICS_SETTINGS = 60 + { "FET_GRA", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2, + MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENU_MIPMAPS(MENUPAGE_GRAPHICS_SETTINGS) + MENU_TEXTURE_FILTERING(MENUPAGE_GRAPHICS_SETTINGS) + MENU_MULTISAMPLING(MENUPAGE_GRAPHICS_SETTINGS) + MENU_IMPROVED_VIDEOMODE(MENUPAGE_GRAPHICS_SETTINGS) + MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, + MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, + }, +#endif }; #endif \ No newline at end of file diff --git a/src/core/config.h b/src/core/config.h index bb6adce6..081d9b39 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -209,6 +209,12 @@ enum Config { //#define USE_TEXTURE_POOL #define CUTSCENE_BORDERS_SWITCH //#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) +#define MULTISAMPLING // adds MSAA option + +#ifdef LIBRW +// these are not supported with librw yet +# undef MULTISAMPLING +#endif // Particle //#define PC_PARTICLE @@ -233,14 +239,15 @@ enum Config { #ifndef PC_MENU # define PS2_MENU //# define PS2_MENU_USEALLPAGEICONS -#else # define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box //# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc. +#else # define MENU_MAP // VC-like menu map. Make sure you have new menu.txd # define SCROLLABLE_STATS_PAGE // only draggable by mouse atm # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON # define CUSTOM_FRONTEND_OPTIONS +# define GRAPHICS_MENU_OPTIONS #endif // Script diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 9edd9497..dbc526dd 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -111,7 +111,7 @@ void LangJapSelect(int8 action) } #endif -#ifdef IMPROVED_VIDEOMODE +/*#ifdef IMPROVED_VIDEOMODE void ScreenModeChange(int8 displayedValue) { if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) { @@ -121,7 +121,7 @@ void ScreenModeChange(int8 displayedValue) FrontEndMenuManager.SaveSettings(); } } -#endif +#endif*/ #ifdef FREE_CAM void ToggleFreeCam(int8 action) @@ -133,13 +133,13 @@ void ToggleFreeCam(int8 action) } #endif -#ifdef CUTSCENE_BORDERS_SWITCH -void BorderModeChange(int8 displayedValue) -{ - CMenuManager::m_PrefsCutsceneBorders = !!displayedValue; - FrontEndMenuManager.SaveSettings(); -} -#endif +//#ifdef CUTSCENE_BORDERS_SWITCH +//void BorderModeChange(int8 displayedValue) +//{ +// CMenuManager::m_PrefsCutsceneBorders = !!displayedValue; +// FrontEndMenuManager.SaveSettings(); +//} +//#endif // Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind void @@ -154,11 +154,11 @@ CustomFrontendOptionsPopulate(void) FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, LangJapSelect, nil); #endif -#ifdef IMPROVED_VIDEOMODE +/*#ifdef IMPROVED_VIDEOMODE static const wchar *screenModes[] = { (wchar*)L"FULLSCREEN", (wchar*)L"WINDOWED" }; FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 8); FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil); -#endif +#endif*/ #ifdef MENU_MAP FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2); @@ -171,11 +171,11 @@ CustomFrontendOptionsPopulate(void) FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil); #endif -#ifdef CUTSCENE_BORDERS_SWITCH +/*#ifdef CUTSCENE_BORDERS_SWITCH static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") }; - FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 9); + FrontendOptionSetPosition(MENUPAGE_DISPLAY_SETTINGS, 3); FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil); -#endif +#endif*/ } #endif diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp index a064788c..e79a8150 100644 --- a/src/skel/win/win.cpp +++ b/src/skel/win/win.cpp @@ -1597,7 +1597,9 @@ psSelectDevice() PSGLOBAL(fullScreen) = FALSE; #endif } - +#ifdef MULTISAMPLING + RwD3D8EngineSetMultiSamplingLevels(1 << FrontEndMenuManager.m_nPrefsMSAALevel); +#endif return TRUE; } diff --git a/utils/gxt/american.txt b/utils/gxt/american.txt index 94074819..9d9ddaa6 100644 --- a/utils/gxt/american.txt +++ b/utils/gxt/american.txt @@ -7957,6 +7957,9 @@ POLISH RUSSIAN { new display menus } +[FET_GRA] +GRAPHICS SETUP + [FED_MIP] MIP MAPPING @@ -7972,6 +7975,18 @@ BILINEAR [FED_TRL] TRILINEAR +[FED_WND] +WINDOWED + +[FED_FLS] +FULLSCREEN + +[FEM_CSB] +CUTSCENE BORDERS + +[FEM_SCF] +SCREEN FORMAT + { end of file } [DUMMY] diff --git a/utils/gxt/gxt.exe b/utils/gxt/gxt.exe index 0a39c0b1feb8505be5643a4e2ec055e02f88672a..ff264dadc8c8e716964fbbf61cf4d1842881c12b 100644 GIT binary patch literal 125440 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 Date: Sun, 16 Aug 2020 17:26:44 +0300 Subject: [PATCH 5/6] Island loading and PS2 alpha test added to options --- gamefiles/TEXT/american.gxt | Bin 219054 -> 219210 bytes src/control/Record.cpp | 8 +- src/control/Script.cpp | 60 +++++++---- src/core/Collision.cpp | 112 +++++++++++-------- src/core/Collision.h | 3 + src/core/Frontend.cpp | 183 ++++++++++++++++++++++++++++++++ src/core/Frontend.h | 18 ++++ src/core/MenuScreens.cpp | 16 +++ src/core/Streaming.cpp | 40 ++++--- src/core/config.h | 2 +- src/modelinfo/ModelInfo.cpp | 26 +++-- src/render/Renderer.cpp | 16 +-- src/save/GenericGameStorage.cpp | 22 ++-- utils/gxt/american.txt | 15 +++ 14 files changed, 417 insertions(+), 104 deletions(-) diff --git a/gamefiles/TEXT/american.gxt b/gamefiles/TEXT/american.gxt index 35973f660f153bb8b22e5df638f13a624686380e..28bf0565adcbd61dfa19d3d482e8712ba4484950 100644 GIT binary patch delta 227 zcmXYoJr06U5QIl!Xb9Gpp5d8bVMPK0krxOLLumZD2Uf;-0BWz`Pbj>Di7hd32Wv~m zK(V_s-_BgF=JRIi>C(-I`@3!lW87+3xN;-nq@0W0eAIhC@UVV$KVPM&n@$HR#HZ(B zWma(mKXYU_H~;_u delta 70 zcmX@Lfp^_{UbYZ#*T@q!8`;c^CVLnqh{v5}VsLZyjrRx+VR#2+`}n&|er(jbxx{#m WC)2fC%|f;9LbZ(Bg=(2@+yVfOX&Qq7 diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 8dc0028a..8a23ffde 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -9,6 +9,7 @@ #include "Timer.h" #include "VehicleModelInfo.h" #include "World.h" +#include "Frontend.h" uint16 CRecordDataForGame::RecordingState; uint8* CRecordDataForGame::pDataBuffer; @@ -439,10 +440,11 @@ void CRecordDataForChase::StartChaseScene(float startTime) Status = STATE_PLAYBACK; AnimTime = startTime; AnimStartTime = CTimer::GetTimeInMilliseconds(); -#ifndef NO_ISLAND_LOADING - RemoveUnusedCollision(); - CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + RemoveUnusedCollision(); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); CGame::TidyUpMemory(true, true); CStreaming::ImGonnaUseStreamingMemory(); CFileMgr::SetDir("data\\paths"); diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 6eb802b4..fa0fb463 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -10017,15 +10017,21 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CollectParameters(&m_nIp, 1); CTimer::Stop(); CGame::currLevel = (eLevelName)ScriptParams[0]; -#ifndef NO_ISLAND_LOADING - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + } CCollision::SortOutCollisionAfterLoad(); -#ifndef NO_ISLAND_LOADING - CStreaming::RequestIslands(CGame::currLevel); - CStreaming::LoadAllRequestedModels(true); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_HIGH) #endif + { + CStreaming::RequestIslands(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + } CTimer::Update(); return 0; } @@ -10641,24 +10647,40 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CTimer::Stop(); CGame::currLevel = (eLevelName)ScriptParams[0]; if (CGame::currLevel != CCollision::ms_collisionInMemory) { -#ifndef NO_ISLAND_LOADING - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - CCollision::LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + } CPopulation::DealWithZoneChange(CCollision::ms_collisionInMemory, CGame::currLevel, false); -#ifndef NO_ISLAND_LOADING - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + } CCollision::SortOutCollisionAfterLoad(); -#ifndef NO_ISLAND_LOADING - CStreaming::RequestIslands(CGame::currLevel); - CStreaming::RequestBigBuildings(CGame::currLevel); - CStreaming::LoadAllRequestedModels(true); - DMAudio.SetEffectsFadeVol(127); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_HIGH) #endif + CStreaming::RequestIslands(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + CStreaming::RequestBigBuildings(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_HIGH) +#endif + CStreaming::LoadAllRequestedModels(true); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + DMAudio.SetEffectsFadeVol(127); } CTimer::Update(); return 0; diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 6522ff1c..bd0dfb92 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -21,6 +21,7 @@ #include "SurfaceTable.h" #include "Lines.h" #include "Collision.h" +#include "Frontend.h" // TODO: where do these go? @@ -519,74 +520,101 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange) } } - if(level == CGame::currLevel || forceChange){ + if (level == CGame::currLevel || forceChange) { CTimer::Stop(); -#ifndef NO_ISLAND_LOADING - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + } CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false); -#ifndef NO_ISLAND_LOADING - CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); - CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); - CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); - CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); - CStreaming::RemoveUnusedModelsInLoadedList(); - CGame::TidyUpMemory(true, true); - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_HIGH) #endif + { + CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); + } +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + { + CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); + CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); + CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); + } ms_collisionInMemory = CGame::currLevel; CReplay::EmptyReplayBuffer(); -#ifndef NO_ISLAND_LOADING - if(CGame::currLevel != LEVEL_GENERIC) - LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); - CStreaming::RequestBigBuildings(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + { + if (CGame::currLevel != LEVEL_GENERIC) + LoadSplash(GetLevelSplashScreen(CGame::currLevel)); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestBigBuildings(CGame::currLevel); + } +#ifdef NO_ISLAND_LOADING + else if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) + CStreaming::RequestIslands(CGame::currLevel); #endif CStreaming::LoadAllRequestedModels(true); -#ifndef NO_ISLAND_LOADING - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + { + CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); - CGame::TidyUpMemory(true, true); -#endif + CGame::TidyUpMemory(true, true); + } CTimer::Update(); -#ifndef NO_ISLAND_LOADING - DMAudio.SetEffectsFadeVol(127); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + DMAudio.SetEffectsFadeVol(127); } } +#ifdef NO_ISLAND_LOADING +bool CCollision::bAlreadyLoaded = false; +#endif void CCollision::SortOutCollisionAfterLoad(void) { if(ms_collisionInMemory == CGame::currLevel) return; -#ifndef NO_ISLAND_LOADING - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + if (CGame::currLevel != LEVEL_GENERIC) { #ifdef NO_ISLAND_LOADING - static bool bAlreadyLoaded = false; - if (bAlreadyLoaded) { - ms_collisionInMemory = CGame::currLevel; - return; - } - bAlreadyLoaded = true; - CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); - CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); - CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); -#else - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) { + if (bAlreadyLoaded) { + ms_collisionInMemory = CGame::currLevel; + return; + } + bAlreadyLoaded = true; + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + } else #endif + CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); if(!CGame::playingIntro) LoadSplash(GetLevelSplashScreen(CGame::currLevel)); } diff --git a/src/core/Collision.h b/src/core/Collision.h index d7498ac0..da94dd34 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -212,6 +212,9 @@ class CCollision public: static eLevelName ms_collisionInMemory; static CLinkList ms_colModelCache; +#ifdef NO_ISLAND_LOADING + static bool bAlreadyLoaded; +#endif static void Init(void); static void Shutdown(void); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index df65f94f..0c813cbb 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -122,6 +122,11 @@ int8 CMenuManager::m_nPrefsMSAALevel = 0; int8 CMenuManager::m_nDisplayMSAALevel = 0; #endif +#ifdef NO_ISLAND_LOADING +int8 CMenuManager::m_DisplayIslandLoading = ISLAND_LOADING_LOW; +int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; +#endif + char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; int32 CMenuManager::m_KeyPressedCode = -1; @@ -155,6 +160,10 @@ int32 MouseButtonJustClicked; int32 JoyButtonJustClicked; //int32 *pControlTemp = 0; +#ifdef PS2_ALPHA_TEST +extern bool gPS2alphaTest; +#endif + #ifndef MASTER bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; @@ -1189,6 +1198,21 @@ CMenuManager::Draw() break; } break; +#endif +#ifdef NO_ISLAND_LOADING + case MENUACTION_ISLANDLOADING: + switch (m_DisplayIslandLoading) { + case ISLAND_LOADING_LOW: + rightText = TheText.Get("FEM_LOW"); + break; + case ISLAND_LOADING_MEDIUM: + rightText = TheText.Get("FEM_MED"); + break; + case ISLAND_LOADING_HIGH: + rightText = TheText.Get("FEM_HIG"); + break; + } + break; #endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == -1) @@ -1245,6 +1269,11 @@ CMenuManager::Draw() rightText = TheText.Get(m_PrefsCutsceneBorders ? "FEM_ON" : "FEM_OFF"); break; #endif +#ifdef PS2_ALPHA_TEST + case MENUACTION_PS2_ALPHA_TEST: + rightText = TheText.Get(gPS2alphaTest ? "FEM_ON" : "FEM_OFF"); + break; +#endif #ifdef CUSTOM_FRONTEND_OPTIONS case MENUACTION_TRIGGERFUNC: FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; @@ -1389,6 +1418,12 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_AAS") && m_nHelperTextMsgId == 1) ResetHelperText(); } +#endif +#ifdef NO_ISLAND_LOADING + if (m_DisplayIslandLoading == m_PrefsIslandLoading) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_ISL") && m_nHelperTextMsgId == 1) + ResetHelperText(); + } #endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH")) @@ -1409,6 +1444,12 @@ CMenuManager::Draw() if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_AAS")) SetHelperText(1); } +#endif +#ifdef NO_ISLAND_LOADING + if (m_DisplayIslandLoading != m_PrefsIslandLoading) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEM_ISL")) + SetHelperText(1); + } #endif if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 @@ -3333,6 +3374,13 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, (char *)&m_nPrefsMSAALevel, 1); m_nDisplayMSAALevel = m_nPrefsMSAALevel; #endif +#ifdef NO_ISLAND_LOADING + CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); + CMenuManager::m_DisplayIslandLoading = CMenuManager::m_PrefsIslandLoading; +#endif +#ifdef PS2_ALPHA_TEST + CFileMgr::Read(fileHandle, (char *)&gPS2alphaTest, 1); +#endif // PS2_ALPHA_TEST } } @@ -3432,6 +3480,12 @@ CMenuManager::SaveSettings() #ifdef MULTISAMPLING CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_nPrefsMSAALevel, 1); #endif +#ifdef NO_ISLAND_LOADING + CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsIslandLoading, 1); +#endif +#ifdef PS2_ALPHA_TEST + CFileMgr::Write(fileHandle, (char *)&gPS2alphaTest, 1); +#endif // PS2_ALPHA_TEST } CFileMgr::CloseFile(fileHandle); @@ -4769,6 +4823,45 @@ CMenuManager::ProcessButtonPresses(void) SaveSettings(); } break; +#endif +#ifdef NO_ISLAND_LOADING + case MENUACTION_ISLANDLOADING: + if (m_DisplayIslandLoading != m_PrefsIslandLoading) { + if (!m_bGameNotLoaded) { + if (m_DisplayIslandLoading > ISLAND_LOADING_LOW) { + if (m_DisplayIslandLoading == ISLAND_LOADING_HIGH) + CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); + if (m_PrefsIslandLoading == ISLAND_LOADING_LOW) { + if (CGame::currLevel != LEVEL_INDUSTRIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + if (CGame::currLevel != LEVEL_COMMERCIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + if (CGame::currLevel != LEVEL_SUBURBAN) + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + CCollision::bAlreadyLoaded = true; + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestBigBuildings(CGame::currLevel); + } else if (m_PrefsIslandLoading == ISLAND_LOADING_HIGH) { + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestIslands(CGame::currLevel); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; + } else { // low + m_PrefsIslandLoading = m_DisplayIslandLoading; + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; + SetHelperText(0); + SaveSettings(); + } + break; #endif case MENUACTION_AUDIOHW: { @@ -4842,6 +4935,43 @@ CMenuManager::ProcessButtonPresses(void) #ifdef CUTSCENE_BORDERS_SWITCH m_PrefsCutsceneBorders = true; #endif +#ifdef NO_ISLAND_LOADING + m_DisplayIslandLoading = ISLAND_LOADING_LOW; + if (!m_bGameNotLoaded) { + if (m_DisplayIslandLoading > ISLAND_LOADING_LOW) { + if (m_DisplayIslandLoading == ISLAND_LOADING_HIGH) + CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); + if (m_PrefsIslandLoading == ISLAND_LOADING_LOW) { + if (CGame::currLevel != LEVEL_INDUSTRIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + if (CGame::currLevel != LEVEL_COMMERCIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + if (CGame::currLevel != LEVEL_SUBURBAN) + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + CCollision::bAlreadyLoaded = true; + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestBigBuildings(CGame::currLevel); + } else if (m_PrefsIslandLoading == ISLAND_LOADING_HIGH) { + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestIslands(CGame::currLevel); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; + } else { // low + m_PrefsIslandLoading = m_DisplayIslandLoading; + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; +#endif // NO_ISLAND_LOADING +#ifdef PS2_ALPHA_TEST + gPS2alphaTest = false; +#endif // PS2_ALPHA_TEST SaveSettings(); #else } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { @@ -4870,6 +5000,43 @@ CMenuManager::ProcessButtonPresses(void) #else CMBlur::BlurOn = true; #endif // GTA3_1_1_PATCH +#ifdef NO_ISLAND_LOADING + m_DisplayIslandLoading = ISLAND_LOADING_LOW; + if (!m_bGameNotLoaded) { + if (m_DisplayIslandLoading > ISLAND_LOADING_LOW) { + if (m_DisplayIslandLoading == ISLAND_LOADING_HIGH) + CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); + if (m_PrefsIslandLoading == ISLAND_LOADING_LOW) { + if (CGame::currLevel != LEVEL_INDUSTRIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + if (CGame::currLevel != LEVEL_COMMERCIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + if (CGame::currLevel != LEVEL_SUBURBAN) + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + CCollision::bAlreadyLoaded = true; + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestBigBuildings(CGame::currLevel); + } else if (m_PrefsIslandLoading == ISLAND_LOADING_HIGH) { + m_PrefsIslandLoading = m_DisplayIslandLoading; + CStreaming::RequestIslands(CGame::currLevel); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; + } else { // low + m_PrefsIslandLoading = m_DisplayIslandLoading; + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } else + m_PrefsIslandLoading = m_DisplayIslandLoading; +#endif // NO_ISLAND_LOADING +#ifdef PS2_ALPHA_TEST + gPS2alphaTest = false; +#endif // PS2_ALPHA_TEST SaveSettings(); #endif // GRAPHICS_MENU_OPTIONS } else if ((m_nCurrScreen != MENUPAGE_SKIN_SELECT_OLD) && (m_nCurrScreen == MENUPAGE_CONTROLLER_PC)) { @@ -5155,6 +5322,15 @@ CMenuManager::ProcessButtonPresses(void) m_nDisplayMSAALevel = 0; } break; +#endif +#ifdef NO_ISLAND_LOADING + case MENUACTION_ISLANDLOADING: + m_DisplayIslandLoading += changeValueBy; + if (m_DisplayIslandLoading > ISLAND_LOADING_HIGH) + m_DisplayIslandLoading = ISLAND_LOADING_LOW; + else if (m_DisplayIslandLoading < ISLAND_LOADING_LOW) + m_DisplayIslandLoading = ISLAND_LOADING_HIGH; + break; #endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != -1) { @@ -5327,6 +5503,13 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; +#endif +#ifdef PS2_ALPHA_TEST + case MENUACTION_PS2_ALPHA_TEST: + gPS2alphaTest = !gPS2alphaTest; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + SaveSettings(); + break; #endif } } diff --git a/src/core/Frontend.h b/src/core/Frontend.h index c9af7c10..dd82507e 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -372,6 +372,12 @@ enum eMenuAction #ifdef MULTISAMPLING MENUACTION_MULTISAMPLING, #endif +#ifdef NO_ISLAND_LOADING + MENUACTION_ISLANDLOADING, +#endif +#ifdef PS2_ALPHA_TEST + MENUACTION_PS2_ALPHA_TEST, +#endif #ifdef CUTSCENE_BORDERS_SWITCH MENUACTION_CUTSCENEBORDERS, #endif @@ -622,6 +628,18 @@ public: void PrintMap(); #endif +#ifdef NO_ISLAND_LOADING + enum + { + ISLAND_LOADING_LOW = 0, + ISLAND_LOADING_MEDIUM, + ISLAND_LOADING_HIGH + }; + + static int8 m_DisplayIslandLoading; + static int8 m_PrefsIslandLoading; +#endif + public: static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2); static void CentreMousePointer(); diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index c313944c..02c004b3 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -30,6 +30,18 @@ #define MENU_MULTISAMPLING(screen) #endif +#ifdef NO_ISLAND_LOADING +#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen, +#else +#define MENU_ISLAND_LOADING(screen) +#endif + +#ifdef PS2_ALPHA_TEST +#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen, +#else +#define MENU_PS2_ALPHA_TEST(screen) +#endif + CMenuScreen aScreens[] = { // MENUPAGE_NONE = 0 { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, @@ -84,6 +96,8 @@ CMenuScreen aScreens[] = { MENU_CUTSCENE_BORDERS_SWITCH(MENUPAGE_DISPLAY_SETTINGS) MENU_MIPMAPS(MENUPAGE_DISPLAY_SETTINGS) MENU_TEXTURE_FILTERING(MENUPAGE_DISPLAY_SETTINGS) + MENU_ISLAND_LOADING(MENUPAGE_DISPLAY_SETTINGS) + MENU_PS2_ALPHA_TEST(MENUPAGE_DISPLAY_SETTINGS) MENU_MULTISAMPLING(MENUPAGE_DISPLAY_SETTINGS) MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, MENU_IMPROVED_VIDEOMODE(MENUPAGE_DISPLAY_SETTINGS) @@ -502,6 +516,8 @@ CMenuScreen aScreens[] = { MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, MENU_MIPMAPS(MENUPAGE_GRAPHICS_SETTINGS) MENU_TEXTURE_FILTERING(MENUPAGE_GRAPHICS_SETTINGS) + MENU_ISLAND_LOADING(MENUPAGE_GRAPHICS_SETTINGS) + MENU_PS2_ALPHA_TEST(MENUPAGE_GRAPHICS_SETTINGS) MENU_MULTISAMPLING(MENUPAGE_GRAPHICS_SETTINGS) MENU_IMPROVED_VIDEOMODE(MENUPAGE_GRAPHICS_SETTINGS) MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 40189844..089e8b23 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -32,6 +32,7 @@ #include "Replay.h" #endif #include "main.h" +#include "Frontend.h" bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -727,7 +728,9 @@ CStreaming::RequestBigBuildings(eLevelName level) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding -#ifndef NO_ISLAND_LOADING +#ifdef NO_ISLAND_LOADING + && ((CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) || (b->m_level == level)) +#else && b->m_level == level #endif ) @@ -740,7 +743,9 @@ CStreaming::RequestBigBuildings(eLevelName level) void CStreaming::RequestIslands(eLevelName level) { -#ifndef NO_ISLAND_LOADING +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_HIGH) +#endif switch(level){ case LEVEL_INDUSTRIAL: RequestModel(islandLODcomInd, BIGBUILDINGFLAGS); @@ -756,7 +761,6 @@ CStreaming::RequestIslands(eLevelName level) break; default: break; } -#endif } void @@ -942,14 +946,17 @@ CStreaming::RemoveBuildings(eLevelName level) void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { -#ifndef NO_ISLAND_LOADING - if(level != LEVEL_INDUSTRIAL) - RemoveBigBuildings(LEVEL_INDUSTRIAL); - if(level != LEVEL_COMMERCIAL) - RemoveBigBuildings(LEVEL_COMMERCIAL); - if(level != LEVEL_SUBURBAN) - RemoveBigBuildings(LEVEL_SUBURBAN); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + if (level != LEVEL_INDUSTRIAL) + RemoveBigBuildings(LEVEL_INDUSTRIAL); + if (level != LEVEL_COMMERCIAL) + RemoveBigBuildings(LEVEL_COMMERCIAL); + if (level != LEVEL_SUBURBAN) + RemoveBigBuildings(LEVEL_SUBURBAN); + } RemoveIslandsNotUsed(level); } @@ -969,7 +976,15 @@ DeleteIsland(CEntity *island) void CStreaming::RemoveIslandsNotUsed(eLevelName level) { -#ifndef NO_ISLAND_LOADING +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + DeleteIsland(pIslandLODindustEntity); + DeleteIsland(pIslandLODcomIndEntity); + DeleteIsland(pIslandLODcomSubEntity); + DeleteIsland(pIslandLODsubIndEntity); + DeleteIsland(pIslandLODsubComEntity); + } else +#endif switch(level){ case LEVEL_INDUSTRIAL: DeleteIsland(pIslandLODindustEntity); @@ -987,16 +1002,13 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) DeleteIsland(pIslandLODcomIndEntity); break; default: -#endif // !NO_ISLAND_LOADING DeleteIsland(pIslandLODindustEntity); DeleteIsland(pIslandLODcomIndEntity); DeleteIsland(pIslandLODcomSubEntity); DeleteIsland(pIslandLODsubIndEntity); DeleteIsland(pIslandLODsubComEntity); -#ifndef NO_ISLAND_LOADING break; } -#endif // !NO_ISLAND_LOADING } void diff --git a/src/core/config.h b/src/core/config.h index 081d9b39..6aa41e6b 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -205,7 +205,7 @@ enum Config { #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time -//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU //#define USE_TEXTURE_POOL #define CUTSCENE_BORDERS_SWITCH //#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index d6fb0102..5d9c7700 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -4,6 +4,7 @@ #include "TempColModels.h" #include "ModelIndices.h" #include "ModelInfo.h" +#include "Frontend.h" CBaseModelInfo *CModelInfo::ms_modelInfoPtrs[MODELINFOSIZE]; @@ -217,20 +218,23 @@ CModelInfo::IsBikeModel(int32 id) void CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level) { -#ifndef NO_ISLAND_LOADING - int i; - CBaseModelInfo *mi; - CColModel *colmodel; +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) +#endif + { + int i; + CBaseModelInfo *mi; + CColModel *colmodel; - for(i = 0; i < MODELINFOSIZE; i++){ - mi = GetModelInfo(i); - if(mi){ - colmodel = mi->GetColModel(); - if(colmodel && colmodel->level != LEVEL_GENERIC && colmodel->level != level) - colmodel->RemoveCollisionVolumes(); + for (i = 0; i < MODELINFOSIZE; i++) { + mi = GetModelInfo(i); + if (mi) { + colmodel = mi->GetColModel(); + if (colmodel && colmodel->level != LEVEL_GENERIC && colmodel->level != level) + colmodel->RemoveCollisionVolumes(); + } } } -#endif } void diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 7ae29a2f..568f0afa 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -19,6 +19,7 @@ #include "Shadows.h" #include "PointLights.h" #include "Renderer.h" +#include "Frontend.h" bool gbShowPedRoadGroups; bool gbShowCarRoadGroups; @@ -710,15 +711,18 @@ CRenderer::ScanWorld(void) ScanSectorPoly(poly, 3, ScanSectorList); } #ifdef NO_ISLAND_LOADING - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN)); -#else + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL)); + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL)); + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN)); + } else +#endif + { #ifdef FIX_BUGS if (CCollision::ms_collisionInMemory != LEVEL_GENERIC) #endif - ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); -#endif + ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); + } ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); } } diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index 1e2d5da7..516c8d46 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -562,17 +562,23 @@ RestoreForStartLoad() ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().x); ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().y); ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().z); -#ifndef NO_ISLAND_LOADING - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + } CCollision::SortOutCollisionAfterLoad(); -#ifndef NO_ISLAND_LOADING - CStreaming::RequestBigBuildings(CGame::currLevel); - CStreaming::LoadAllRequestedModels(false); - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); - CGame::TidyUpMemory(true, false); +#ifdef NO_ISLAND_LOADING + if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_LOW) #endif + { + CStreaming::RequestBigBuildings(CGame::currLevel); + CStreaming::LoadAllRequestedModels(false); + CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); + CGame::TidyUpMemory(true, false); + } if (CloseFile(file)) { return true; } else { diff --git a/utils/gxt/american.txt b/utils/gxt/american.txt index 9d9ddaa6..ea7228aa 100644 --- a/utils/gxt/american.txt +++ b/utils/gxt/american.txt @@ -7987,6 +7987,21 @@ CUTSCENE BORDERS [FEM_SCF] SCREEN FORMAT +[FEM_ISL] +MAP MEMORY USAGE + +[FEM_LOW] +LOW + +[FEM_MED] +MEDIUM + +[FEM_HIG] +HIGH + +[FEM_2PR] +PS2 ALPHA TEST + { end of file } [DUMMY] From 0418ba597bc53d08d0244188f4623ebadfdd2876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sun, 16 Aug 2020 17:58:40 +0300 Subject: [PATCH 6/6] remove CFO --- src/core/Frontend.cpp | 150 +---------------------------- src/core/Frontend.h | 5 +- src/core/Game.cpp | 5 - src/core/MenuScreens.cpp | 21 ++++- src/core/config.h | 1 - src/core/re3.cpp | 112 ---------------------- src/extras/frontendoption.cpp | 173 ---------------------------------- src/extras/frontendoption.h | 87 ----------------- 8 files changed, 21 insertions(+), 533 deletions(-) delete mode 100644 src/extras/frontendoption.cpp delete mode 100644 src/extras/frontendoption.h diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 0c813cbb..d82c5df4 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -36,7 +36,6 @@ #include "Stats.h" #include "Messages.h" #include "FileLoader.h" -#include "frontendoption.h" #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 @@ -432,46 +431,12 @@ CMenuManager::ThingsToDoBeforeGoingBack() if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { m_nTotalListRow = 0; } - -#ifdef CUSTOM_FRONTEND_OPTIONS - for (int i = 0; i < numCustomFrontendOptions; i++) { - FrontendOption &option = customFrontendOptions[i]; - if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) { - if (option.returnPrevPageFunc) - option.returnPrevPageFunc(); - - if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC) - option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - - if (option.onlyApplyOnEnter) - option.displayedValue = *option.value; - } - } -#endif } int8 CMenuManager::GetPreviousPageOption() { -#ifndef CUSTOM_FRONTEND_OPTIONS return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; -#else - int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; - - if (prevPage == -1) // Game also does same - return 0; - - prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; - - for (int i = 0; i < NUM_MENUROWS; i++) { - if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { - return i; - } - } - - // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?) - return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; -#endif } // ------ Functions not in the game/inlined ends @@ -990,14 +955,7 @@ CMenuManager::Draw() } #endif -#ifdef CUSTOM_FRONTEND_OPTIONS - static int lastOption = m_nCurrOption; -#endif - for (int i = 0; i < NUM_MENUROWS; ++i) { -#ifdef CUSTOM_FRONTEND_OPTIONS - bool isOptionDisabled = false; -#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { wchar *rightText = nil; wchar *leftText; @@ -1274,29 +1232,6 @@ CMenuManager::Draw() rightText = TheText.Get(gPS2alphaTest ? "FEM_ON" : "FEM_OFF"); break; #endif -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; - if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) { - leftText = (wchar*)option.leftText; - if (option.type == FEOPTION_SELECT) { - if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) - option.displayedValue = 0; - - rightText = (wchar*)option.rightTexts[option.displayedValue]; - - } else if (option.type == FEOPTION_DYNAMIC) { - if (option.drawFunc) { - rightText = option.drawFunc(&isOptionDisabled); - } - } - } else { - debug("A- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, i, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu, option.screen, option.screenOptionOrder); - assert(0 && "Custom frontend options is borked"); - } - - break; -#endif } float nextItemY = headerHeight + nextYToUse; @@ -1383,11 +1318,7 @@ CMenuManager::Draw() || !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_AAS") #endif ) - && !m_bGameNotLoaded -#ifdef CUSTOM_FRONTEND_OPTIONS - || isOptionDisabled -#endif - ) + && !m_bGameNotLoaded) CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); @@ -1497,20 +1428,6 @@ CMenuManager::Draw() } #endif -#ifdef CUSTOM_FRONTEND_OPTIONS - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { - FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; - if (option.onlyApplyOnEnter && m_nCurrOption != i) - option.displayedValue = *option.value; - - if (m_nCurrOption != lastOption && lastOption == i) { - FrontendOption &oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu]; - if (oldOption.type == FEOPTION_DYNAMIC) - oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - } - } -#endif - // Sliders int lastActiveBarX; switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { @@ -1554,10 +1471,6 @@ CMenuManager::Draw() } } -#ifdef CUSTOM_FRONTEND_OPTIONS - lastOption = m_nCurrOption; -#endif - switch (m_nCurrScreen) { case MENUPAGE_CONTROLLER_SETTINGS: case MENUPAGE_SOUND_SETTINGS: @@ -3215,10 +3128,6 @@ CMenuManager::InitialiseChangedLanguageSettings() default: break; } - -#ifdef CUSTOM_FRONTEND_OPTIONS - CustomFrontendOptionsPopulate(); -#endif } } @@ -5096,33 +5005,6 @@ CMenuManager::ProcessButtonPresses(void) RequestFrontEndShutDown(); RetryMission(2, 0); return; -#endif -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; - if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { - if (option.type == FEOPTION_SELECT) { - if (!option.onlyApplyOnEnter) { - option.displayedValue++; - if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) - option.displayedValue = 0; - } - option.changeFunc(option.displayedValue); - *option.value = option.displayedValue; - - } else if (option.type == FEOPTION_DYNAMIC) { - option.buttonPressFunc(FEOPTION_ACTION_SELECT); - } else if (option.type == FEOPTION_REDIRECT) { - ChangeScreen(option.to, option.option, true, option.fadeIn); - } else if (option.type == FEOPTION_GOBACK) { - goBack = true; - } - } else { - debug("B- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder); - assert(0 && "Custom frontend options are borked"); - } - - break; #endif } } @@ -5354,36 +5236,6 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; - if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { - if (option.type == FEOPTION_SELECT) { - if (changeValueBy > 0) { - option.displayedValue++; - if (option.displayedValue >= option.numRightTexts) - option.displayedValue = 0; - } else { - option.displayedValue--; - if (option.displayedValue < 0) - option.displayedValue = option.numRightTexts - 1; - } - if (!option.onlyApplyOnEnter) { - option.changeFunc(option.displayedValue); - *option.value = option.displayedValue; - } - } else if (option.type == FEOPTION_DYNAMIC) { - option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); - } - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - } - else { - debug("C- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder); - assert(0 && "Custom frontend options are borked"); - } - - break; -#endif } ProcessOnOffMenuOptions(); if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { diff --git a/src/core/Frontend.h b/src/core/Frontend.h index dd82507e..d631a7d1 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -381,9 +381,6 @@ enum eMenuAction #ifdef CUTSCENE_BORDERS_SWITCH MENUACTION_CUTSCENEBORDERS, #endif -#ifdef CUSTOM_FRONTEND_OPTIONS - MENUACTION_TRIGGERFUNC -#endif }; enum eCheckHover @@ -478,7 +475,7 @@ struct CMenuScreen int32 m_Action; // eMenuAction char m_EntryName[8]; int32 m_SaveSlot; // eSaveSlot - int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option + int32 m_TargetMenu; // eMenuScreen } m_aEntries[NUM_MENUROWS]; }; diff --git a/src/core/Game.cpp b/src/core/Game.cpp index d5b376f6..06f2c1bd 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -86,7 +86,6 @@ #include "ZoneCull.h" #include "Zones.h" #include "debugmenu.h" -#include "frontendoption.h" #include "postfx.h" eLevelName CGame::currLevel; @@ -292,10 +291,6 @@ bool CGame::InitialiseOnceAfterRW(void) DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); - -#ifdef CUSTOM_FRONTEND_OPTIONS - CustomFrontendOptionsPopulate(); -#endif return true; } diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 02c004b3..5dfcc8fe 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -2,8 +2,6 @@ #include "Frontend.h" #ifdef PC_MENU -// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp. - #ifdef CUTSCENE_BORDERS_SWITCH #define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, #else @@ -47,7 +45,11 @@ CMenuScreen aScreens[] = { { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, // MENUPAGE_STATS = 1 +#ifdef MENU_MAP + { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 3, +#else { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2, +#endif MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -60,7 +62,11 @@ CMenuScreen aScreens[] = { }, // MENUPAGE_BRIEFS = 3 +#ifdef MENU_MAP + { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 4, +#else { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3, +#endif MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, }, @@ -375,7 +381,11 @@ CMenuScreen aScreens[] = { }, // MENUPAGE_OPTIONS = 41 +#ifdef MENU_MAP + { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 5, +#else { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4, +#endif MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, @@ -388,7 +398,11 @@ CMenuScreen aScreens[] = { }, // MENUPAGE_EXIT = 42 +#ifdef MENU_MAP + { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 6, +#else { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5, +#endif MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE, @@ -449,6 +463,9 @@ CMenuScreen aScreens[] = { { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, +#ifdef MENU_MAP + MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP, +#endif MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, diff --git a/src/core/config.h b/src/core/config.h index 6aa41e6b..00a8076f 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -246,7 +246,6 @@ enum Config { # define SCROLLABLE_STATS_PAGE // only draggable by mouse atm # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON -# define CUSTOM_FRONTEND_OPTIONS # define GRAPHICS_MENU_OPTIONS #endif diff --git a/src/core/re3.cpp b/src/core/re3.cpp index dbc526dd..eef30706 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -70,115 +70,6 @@ mysrand(unsigned int seed) myrand_seed = seed; } -#ifdef CUSTOM_FRONTEND_OPTIONS -#include "frontendoption.h" -#include "platform.h" - -void ReloadFrontendOptions(void) -{ - CustomFrontendOptionsPopulate(); -} - -#ifdef MORE_LANGUAGES -void LangPolSelect(int8 action) -{ - if (action == FEOPTION_ACTION_SELECT) { - FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH; - FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; - FrontEndMenuManager.InitialiseChangedLanguageSettings(); - FrontEndMenuManager.SaveSettings(); - } -} - -void LangRusSelect(int8 action) -{ - if (action == FEOPTION_ACTION_SELECT) { - FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN; - FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; - FrontEndMenuManager.InitialiseChangedLanguageSettings(); - FrontEndMenuManager.SaveSettings(); - } -} - -void LangJapSelect(int8 action) -{ - if (action == FEOPTION_ACTION_SELECT) { - FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE; - FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; - FrontEndMenuManager.InitialiseChangedLanguageSettings(); - FrontEndMenuManager.SaveSettings(); - } -} -#endif - -/*#ifdef IMPROVED_VIDEOMODE -void ScreenModeChange(int8 displayedValue) -{ - if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) { - FrontEndMenuManager.m_nPrefsWindowed = displayedValue; - _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution - FrontEndMenuManager.SetHelperText(0); - FrontEndMenuManager.SaveSettings(); - } -} -#endif*/ - -#ifdef FREE_CAM -void ToggleFreeCam(int8 action) -{ - if (action == FEOPTION_ACTION_SELECT) { - TheCamera.bFreeCam = !TheCamera.bFreeCam; - FrontEndMenuManager.SaveSettings(); - } -} -#endif - -//#ifdef CUTSCENE_BORDERS_SWITCH -//void BorderModeChange(int8 displayedValue) -//{ -// CMenuManager::m_PrefsCutsceneBorders = !!displayedValue; -// FrontEndMenuManager.SaveSettings(); -//} -//#endif - -// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind -void -CustomFrontendOptionsPopulate(void) -{ - RemoveCustomFrontendOptions(); // if exist - -#ifdef MORE_LANGUAGES - FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS); - FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil); - FrontendOptionAddDynamic(TheText.Get("FEL_RUS"), nil, LangRusSelect, nil); - FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, LangJapSelect, nil); -#endif - -/*#ifdef IMPROVED_VIDEOMODE - static const wchar *screenModes[] = { (wchar*)L"FULLSCREEN", (wchar*)L"WINDOWED" }; - FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 8); - FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil); -#endif*/ - -#ifdef MENU_MAP - FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2); - FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP); -#endif - -#ifdef FREE_CAM - static const wchar *text = (wchar*)L"TOGGLE FREE CAM"; - FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1); - FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil); -#endif - -/*#ifdef CUTSCENE_BORDERS_SWITCH - static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") }; - FrontendOptionSetPosition(MENUPAGE_DISPLAY_SETTINGS, 3); - FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil); -#endif*/ -} -#endif - #ifdef DEBUGMENU void WeaponCheat(); void HealthCheat(); @@ -502,9 +393,6 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway); DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil); -#ifdef CUSTOM_FRONTEND_OPTIONS - DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions); -#endif DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil); DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp deleted file mode 100644 index 51814f35..00000000 --- a/src/extras/frontendoption.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "common.h" - -#ifdef CUSTOM_FRONTEND_OPTIONS -#include "frontendoption.h" - -int numCustomFrontendOptions = 0; -FrontendOption *customFrontendOptions; - -int optionCursor = -1; -eMenuScreen currentMenu; - -void ChangeScreen(eMenuScreen screen, int option, bool fadeIn) -{ - FrontEndMenuManager.m_nPrevScreen = FrontEndMenuManager.m_nCurrScreen; - FrontEndMenuManager.m_nCurrScreen = screen; - FrontEndMenuManager.m_nCurrOption = option; - if (fadeIn) - FrontEndMenuManager.m_nMenuFadeAlpha = 0; -} - -void GoBack(bool fadeIn) -{ - int screen = !FrontEndMenuManager.m_bGameNotLoaded ? - aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[0]; - int option = !FrontEndMenuManager.m_bGameNotLoaded ? - aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[0]; - - FrontEndMenuManager.ThingsToDoBeforeGoingBack(); - - ChangeScreen((eMenuScreen)screen, option, fadeIn); -} - -uint8 -GetNumberOfMenuOptions(int screen) -{ - uint8 Rows = 0; - for (int i = 0; i < NUM_MENUROWS; i++) { - if (aScreens[screen].m_aEntries[i].m_Action == MENUACTION_NOTHING) - break; - - ++Rows; - } - return Rows; -} - -// Used before populating options, but effective in InitialiseChangedLanguageSettings and debugmenu -void -RemoveCustomFrontendOptions() -{ - if (numCustomFrontendOptions == 0) - return; - - for (int i = 0; i < MENUPAGES; i++) { - for (int j = 0; j < NUM_MENUROWS; j++) { - if (aScreens[i].m_aEntries[j].m_Action == MENUACTION_TRIGGERFUNC) { - int k; - for (k = j; k < NUM_MENUROWS-1; k++) { - memcpy(&aScreens[i].m_aEntries[k], &aScreens[i].m_aEntries[k+1], sizeof(CMenuScreen::CMenuEntry)); - } - aScreens[i].m_aEntries[k].m_Action = MENUACTION_NOTHING; - aScreens[i].m_aEntries[k].m_EntryName[0] = '\0'; - j--; - } - } - } - free(customFrontendOptions); - numCustomFrontendOptions = 0; -} - -int8 RegisterNewOption(int screen) -{ - numCustomFrontendOptions++; - if (numCustomFrontendOptions == 1) - customFrontendOptions = (FrontendOption*)malloc(5 * sizeof(FrontendOption)); - else if (numCustomFrontendOptions % 5 == 1) - customFrontendOptions = (FrontendOption*)realloc(customFrontendOptions, (numCustomFrontendOptions + 4) * sizeof(FrontendOption)); - - assert(customFrontendOptions != nil && "Custom frontend options can't be allocated"); - - uint8 nth = GetNumberOfMenuOptions(screen); - if (optionCursor < 0) { - if (optionCursor == -1) { - if (!strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FEDS_TB") || !strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FESZ_CA")) { - // Move back button one below - memcpy(&aScreens[screen].m_aEntries[nth], &aScreens[screen].m_aEntries[nth - 1], sizeof(CMenuScreen::CMenuEntry)); - nth--; - } - } - } else { - if (aScreens[screen].m_aEntries[optionCursor].m_Action != MENUACTION_NOTHING) { - for (int i = nth - 1; i >= optionCursor; i--) { - memcpy(&aScreens[screen].m_aEntries[i + 1], &aScreens[screen].m_aEntries[i], sizeof(CMenuScreen::CMenuEntry)); - } - } - nth = optionCursor; - optionCursor++; - } - - aScreens[screen].m_aEntries[nth].m_Action = MENUACTION_TRIGGERFUNC; - aScreens[screen].m_aEntries[nth].m_TargetMenu = numCustomFrontendOptions - 1; - aScreens[screen].m_aEntries[nth].m_EntryName[0] = 1; // just something to fool it - return nth; -} - -void FrontendOptionSetPosition(eMenuScreen screen, int8 option) -{ - currentMenu = screen; - optionCursor = option; -} - -void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc) -{ - int8 screenOptionOrder = RegisterNewOption(currentMenu); - - FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; - option.screen = currentMenu; - option.type = FEOPTION_SELECT; - option.leftText = leftText; - option.rightTexts = rightTexts; - option.numRightTexts = numRightTexts; - option.value = var; - option.displayedValue = *var; - option.onlyApplyOnEnter = onlyApplyOnEnter; - option.changeFunc = changeFunc; - option.screenOptionOrder = screenOptionOrder; - option.returnPrevPageFunc = returnPrevPageFunc; -} - -void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc) -{ - int8 screenOptionOrder = RegisterNewOption(currentMenu); - - FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; - option.screen = currentMenu; - option.type = FEOPTION_DYNAMIC; - option.drawFunc = drawFunc; - option.buttonPressFunc = buttonPressFunc; - option.leftText = leftText; - option.onlyApplyOnEnter = false; - option.screenOptionOrder = screenOptionOrder; - option.returnPrevPageFunc = returnPrevPageFunc; -} - -void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption, bool fadeIn) -{ - int8 screenOptionOrder = RegisterNewOption(currentMenu); - - FrontendOption &option = customFrontendOptions[numCustomFrontendOptions - 1]; - option.screen = currentMenu; - option.type = FEOPTION_REDIRECT; - option.to = to; - option.option = selectedOption; - option.fadeIn = fadeIn; - option.leftText = text; - option.onlyApplyOnEnter = false; - option.screenOptionOrder = screenOptionOrder; - option.returnPrevPageFunc = nil; -} - -void FrontendOptionAddBackButton(const wchar* text, bool fadeIn) -{ - int8 screenOptionOrder = RegisterNewOption(currentMenu); - - FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1]; - option.screen = currentMenu; - option.type = FEOPTION_GOBACK; - option.fadeIn = fadeIn; - option.leftText = text; - option.onlyApplyOnEnter = false; - option.screenOptionOrder = screenOptionOrder; - option.returnPrevPageFunc = nil; -} -#endif \ No newline at end of file diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h deleted file mode 100644 index 7cfc09a7..00000000 --- a/src/extras/frontendoption.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once -#include "common.h" - -#ifdef CUSTOM_FRONTEND_OPTIONS -#include "Frontend.h" - -// Warning: All of the code relies on that you won't use more then NUM_MENUROWS(18) options on one page. Also congrats if you can make 18 options visible at once. - - -// Static/select: User allocates variable, passes it to function and it's set automatically from input among the strings given to function, -// then you can handle ChangeFunc and ReturnPrevPageFunc if needed. -// -// Dynamic: Function doesn't accept value pointer, user should do operations with handling ButtonPressFunc. -// Right-side text can be set via DrawFunc, which is called on every draw. ReturnPrevPageFunc is also here if needed. - -#define FEOPTION_SELECT 0 -#define FEOPTION_DYNAMIC 1 -#define FEOPTION_REDIRECT 2 -#define FEOPTION_GOBACK 3 - -#define FEOPTION_ACTION_LEFT 0 -#define FEOPTION_ACTION_RIGHT 1 -#define FEOPTION_ACTION_SELECT 2 -#define FEOPTION_ACTION_FOCUSLOSS 3 - -void RemoveCustomFrontendOptions(); -void CustomFrontendOptionsPopulate(); - -// for static and dynamic options -typedef void (*ReturnPrevPageFunc)(); - -// for static options -typedef void (*ChangeFunc)(int8 displayedValue); // called before updating the value - -// for dynamic options -typedef wchar* (*DrawFunc)(bool* disabled); // should return pointer to right text. *disabled = true will make it dark yellow -typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above - -struct FrontendOption -{ - int8 type; - int8 screenOptionOrder; - eMenuScreen screen; - const wchar* leftText; - ReturnPrevPageFunc returnPrevPageFunc; - - union { - // Only for dynamic - struct { - DrawFunc drawFunc; - ButtonPressFunc buttonPressFunc; - }; - - // Only for static/select - struct { - const wchar** rightTexts; - int8 numRightTexts; - int8 *value; - int8 displayedValue; // if onlyApplyOnEnter enabled - bool onlyApplyOnEnter; - ChangeFunc changeFunc; - }; - - // Only for redirect - struct { - eMenuScreen to; - int8 option; - bool fadeIn; - }; - }; -}; - -extern int numCustomFrontendOptions; -extern FrontendOption* customFrontendOptions; - -// To be used in ButtonPressFunc / ChangeFunc(but that would be weird): -void ChangeScreen(eMenuScreen screen, int option = 0, bool fadeIn = true); -void GoBack(bool fadeIn = true); - -// If option is positive number, all calls will increase it before using it (you can think it as cursor). -1 means before the back button, -2 is end of page -void FrontendOptionSetPosition(eMenuScreen screen, int8 option = -1); - -void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc); -void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc rightTextDrawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc); -void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption = 0, bool fadeIn = true); -void FrontendOptionAddBackButton(const wchar* text, bool fadeIn = true); -#endif \ No newline at end of file