Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Override zoom parameters on-the-fly #520

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Main/include/GameConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ DefineEnum(GameConfigKeys,
ExitPlayMethod,
ExitPlayHoldDuration,
DisableNonButtonInputsDuringPlay, // TODO: after enabling key customization for non-button commands, remove this.
EnableVisualParamOverridesForNormalGameplay,

LastSelected,
LastSelectedChal,
Expand Down
187 changes: 170 additions & 17 deletions Main/src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ class Game_Impl : public Game
uint32 m_pressTimes[static_cast<size_t>(Input::Button::Length)] = { 0 };
uint8 m_hispeedAdjustMode = 0; // for skins, 0 = not adjusting, 1 = coarse adjustment, 2 = fine adjustment

// Override track position
bool m_hasAdjustedVisualParam = false; // TODO: consider creating a dedicated flag for tainting unsaveableness
int8 m_currVisualParam = -1; // -1: disabled, 0-4: editing
std::array<std::optional<float>, 5> m_visualParamOverrides;
std::array<String, 5> m_visualParamNames = {
"zoom_bottom", "zoom_top", "zoom_side", "tilt", "center_split"
};
std::array<float, 5> m_visualParamDefaultIncrement = {
0.01f, 0.01f, 0.01f, 0.1f/36.0f, 0.01f
};

public:
Game_Impl(const String& mapPath, PlayOptions&& options) : m_playOptions(std::move(options))
{
Expand Down Expand Up @@ -643,6 +654,8 @@ class Game_Impl : public Game
}
}

ClearVisualParamOverrides();

if (m_practiceSetupDialog)
{
m_InitPracticeSetupDialog();
Expand Down Expand Up @@ -725,11 +738,8 @@ class Game_Impl : public Game
m_transitioning = false;
m_scoring.Reset(m_playOptions.range);
m_scoring.SetInput(&g_input);
m_camera.pLaneZoom = m_playback.GetZoom(0);
m_camera.pLanePitch = m_playback.GetZoom(1);
m_camera.pLaneOffset = m_playback.GetZoom(2);
m_camera.pLaneTilt = m_playback.GetZoom(3);
m_track->centerSplit = m_playback.GetZoom(4);

SetVisualParams();

for(uint32 i = 0; i < 2; i++)
{
Expand Down Expand Up @@ -922,14 +932,8 @@ class Game_Impl : public Game
m_camera.SetSlowTilt(slowTilt);

// Set track zoom
SetVisualParams();

m_camera.pLaneZoom = m_playback.GetZoom(0);
m_camera.pLanePitch = m_playback.GetZoom(1);
m_camera.pLaneOffset = m_playback.GetZoom(2);
m_camera.pLaneTilt = m_playback.GetZoom(3);
m_track->centerSplit = m_playback.GetZoom(4);
m_camera.SetManualTilt(m_manualTiltEnabled);
m_camera.SetManualTiltInstant(m_playback.CheckIfManualTiltInstant());
m_camera.track = m_track;
m_camera.Tick(deltaTime,m_playback);
m_track->Tick(m_playback, deltaTime);
Expand Down Expand Up @@ -1088,6 +1092,8 @@ class Game_Impl : public Game
}
}

RenderVisualParamHUD();

if (m_renderDebugHUD)// Render debug hud if enabled
{
m_introCompleted = true;
Expand Down Expand Up @@ -1401,11 +1407,7 @@ class Game_Impl : public Game
m_playback.OnLaserAlertEntered.Add(this, &Game_Impl::OnLaserAlertEntered);
m_playback.Reset();

// Set camera start position
m_camera.pLaneZoom = m_playback.GetZoom(0);
m_camera.pLanePitch = m_playback.GetZoom(1);
m_camera.pLaneOffset = m_playback.GetZoom(2);
m_camera.pLaneTilt = m_playback.GetZoom(3);
SetVisualParams();

// Enable laser slams and roll ignore behaviour
m_camera.SetFancyHighwayTilt(g_gameConfig.GetBool(GameConfigKeys::EnableFancyHighwayRoll));
Expand Down Expand Up @@ -1813,6 +1815,69 @@ class Game_Impl : public Game
g_application->RemoveTickable(this);
}

void ClearVisualParamOverrides()
{
if (m_isPracticeSetup || !m_introCompleted)
{
m_hasAdjustedVisualParam = false;
}

for (auto& visualParamOverride : m_visualParamOverrides)
{
visualParamOverride.reset();
}
}

void ClearVisualParamOverride(uint8 index)
{
m_visualParamOverrides[index].reset();
}

void AdjustVisualParamOverride(uint8 index, int delta)
{
float value = m_visualParamOverrides[index].value_or(m_playback.GetZoom(index));
value += m_visualParamDefaultIncrement[index] * delta;

if (index == 3)
{
// 0.1 degrees
const float quant = m_visualParamDefaultIncrement[3] / 10;
value = Math::RoundToInt(value / quant) * quant;
}
else
{
value = Math::RoundToInt(value*100) / 100.0f;
}

m_visualParamOverrides[index] = value;

m_hasAdjustedVisualParam = true;
}

void SetVisualParams()
{
m_camera.pLaneZoom = m_visualParamOverrides[0].value_or(m_playback.GetZoom(0));
m_camera.pLanePitch = m_visualParamOverrides[1].value_or(m_playback.GetZoom(1));
m_camera.pLaneOffset = m_visualParamOverrides[2].value_or(m_playback.GetZoom(2));
m_camera.pLaneTilt = m_visualParamOverrides[3].value_or(m_playback.GetZoom(3));

if (m_track)
{
m_track->centerSplit = m_visualParamOverrides[4].value_or(m_playback.GetZoom(4));
}

if (m_visualParamOverrides[3].has_value())
{
m_camera.SetManualTilt(true);
m_camera.SetManualTiltInstant(true);
}
else
{
m_camera.SetManualTilt(m_manualTiltEnabled);
m_camera.SetManualTiltInstant(m_playback.CheckIfManualTiltInstant());
}
}

void RenderParticles(const RenderState& rs, float deltaTime)
{
// Render particle effects
Expand Down Expand Up @@ -2015,6 +2080,50 @@ class Game_Impl : public Game
//g_guiRenderer->End();
}

void RenderVisualParamHUD()
{
if (!m_renderDebugHUD && m_currVisualParam == -1)
{
return;
}

const int textSize = g_resolution.y >= 600 ? 24 : 18;

auto RenderText = [&](const String& text, const Vector2& pos, const Color& color = {1.0f, 1.0f, 0.5f, 1.0f})
{
g_application->FastText(text, pos.x + 1, pos.y + 1, textSize, NVGalign::NVG_ALIGN_CENTER, Color::Black);
g_application->FastText(text, pos.x, pos.y, textSize, NVGalign::NVG_ALIGN_CENTER, color);
};

Vector2 center = Vector2(g_resolution / 2);

for (int8 i = 0; i < static_cast<int8>(m_visualParamOverrides.size()); ++i)
{
String s = "";

if (m_visualParamOverrides[i].has_value())
{
if (i == 3)
{
s = Utility::Sprintf("%s = %.3f", m_visualParamNames[i], -36 * m_visualParamOverrides[i].value_or(0));
}
else
{
s = Utility::Sprintf("%s = %d", m_visualParamNames[i], Math::RoundToInt(100 * m_visualParamOverrides[i].value_or(0)));
}
}
else
{
s = Utility::Sprintf("%s = not set", m_visualParamNames[i]);
}

const Vector2 pos = center + Vector2(0.0f, static_cast<float>((i - static_cast<int8>(m_visualParamOverrides.size() / 2)) * textSize));
const Color& color = m_currVisualParam == i ? Color::Green : Color::White;

RenderText(s, pos, color);
}
}

void OnLaserSlam(LaserObjectState* object)
{
// Note: this merely simulates the slam roll effect. The way SDVX does laser slams is probably just putting
Expand Down Expand Up @@ -2324,6 +2433,49 @@ class Game_Impl : public Game
if (!m_isPracticeSetup && g_gameConfig.GetBool(GameConfigKeys::DisableNonButtonInputsDuringPlay))
return;

// Ctrl + S + arrow keys: adjusting visual params
if (g_gameWindow->IsKeyPressed(SDL_SCANCODE_LCTRL) && g_gameWindow->IsKeyPressed(SDL_SCANCODE_S))
{
const bool enableVisualParamOverrides = m_renderDebugHUD || m_isPracticeSetup || m_scoring.autoplayInfo.IsAutoplayButtons() || m_paused;
if (!IsMultiplayerGame() && !IsChallenge() && (enableVisualParamOverrides || g_gameConfig.GetBool(GameConfigKeys::EnableVisualParamOverridesForNormalGameplay)))
{
int increment = (g_gameWindow->IsKeyPressed(SDL_SCANCODE_LSHIFT) ? 5 : 1) * (g_gameWindow->IsKeyPressed(SDL_SCANCODE_LALT) ? 1 : 10);

switch (code)
{
case SDL_SCANCODE_UP:
--m_currVisualParam;
break;
case SDL_SCANCODE_DOWN:
++m_currVisualParam;
break;
case SDL_SCANCODE_LEFT:
if(m_currVisualParam >= 0) AdjustVisualParamOverride(m_currVisualParam, -increment);
break;
case SDL_SCANCODE_RIGHT:
if (m_currVisualParam >= 0) AdjustVisualParamOverride(m_currVisualParam, increment);
break;
case SDL_SCANCODE_BACKSPACE:
case SDL_SCANCODE_DELETE:
if (m_currVisualParam >= 0) ClearVisualParamOverride(static_cast<uint8>(m_currVisualParam));
break;
default:
break;
}

if (m_currVisualParam < -1)
{
m_currVisualParam = static_cast<int8>(m_visualParamOverrides.size()-1);
}
else if (m_currVisualParam >= static_cast<int8>(m_visualParamOverrides.size()))
{
m_currVisualParam = -1;
}

return;
}
}

if (m_practiceSetupDialog && m_practiceSetupDialog->IsActive())
{
if (code != SDL_SCANCODE_F8) return;
Expand Down Expand Up @@ -2971,6 +3123,7 @@ class Game_Impl : public Game
if (IsPartialPlay()) return false;

if (!(m_scoring.hitWindow <= HitWindow::NORMAL)) return false;
if (m_hasAdjustedVisualParam) return false;

return true;
}
Expand Down
1 change: 1 addition & 0 deletions Main/src/GameConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ void GameConfig::InitDefaults()
Set(GameConfigKeys::ExitPlayHoldDuration, 2000);

Set(GameConfigKeys::DisableNonButtonInputsDuringPlay, false);
Set(GameConfigKeys::EnableVisualParamOverridesForNormalGameplay, false);

Set(GameConfigKeys::LastSelected, 0);
Set(GameConfigKeys::LastSelectedChal, 0);
Expand Down
1 change: 1 addition & 0 deletions Main/src/SettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class SettingsPage_Input : public SettingsPage

ToggleSetting(GameConfigKeys::DisableNonButtonInputsDuringPlay, "Disable non-buttons during gameplay");
ToggleSetting(GameConfigKeys::PracticeSetupNavEnabled, "Enable navigation inputs for the practice setup");
ToggleSetting(GameConfigKeys::EnableVisualParamOverridesForNormalGameplay, "Enable overriding visual(camera) parameters during normal gameplay");
}

private:
Expand Down
3 changes: 2 additions & 1 deletion Main/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@

#include <functional>
#include <memory>
#include <optional>
#include <queue>
#include <stack>
#include <string>
#include <queue>
#include <unordered_set>

#include <Shared/Shared.hpp>
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,26 @@ If something breaks in the song database, delete "maps.db". **Please note this w
- \[Start\] when selecting filters to toggle between level and folder filters
- \[FX-L\] + \[FX-R\] to open up game settings (Hard gauge, Random, Mirror, etc.)
- \[TAB\] to open the Search bar on the top to search for songs
- \[BT-B + BT-C\] Add song to collection (such as favourites)
- \[BT-B + BT-C\] to add the song to a collection (such as favourites)
- \[~\] to enter the practice mode

### During Gameplay:
- These keys can be disabled with a setting (`DisableNonButtonInputsDuringPlay`).
- \[F5\] to restart the game
- \[F8\] to show/hide the debug HUD
- \[F9\] to reload the skin
- \[Enter\] to skip intro/outro
- \[Pause\] to pause/unpause
- \[PageUp\] to advance 5 seconds
- \[Ctrl\]+\[S\]+\[Arrow Key\] to override visual track parameters (`zoom_top`, `zoom_bottom`, ...)
- Unless the setting `EnableVisualParamOverridesForNormalGameplay` is set, this is only available during one of these situations:
- The debug HUD is being shown
- During practice setup
- During autoplay
- The game is paused
- Using this will prevent the score of the play from being saved.
- Use \[Shift\] or \[Alt\] for coarse/fine adjustments.
- Clear overrides with \[Ctrl\]+\[S\]+\[Backspace\].

## How to run:
Just run 'usc-game' or 'usc-game_Debug' from within the 'bin' folder.
Expand Down
2 changes: 1 addition & 1 deletion Shared/include/Shared/Math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace Math
template<typename T>
int RoundToInt(T t)
{
return static_cast<int>(t + 0.5);
return t >= 0 ? static_cast<int>(t + 0.5) : static_cast<int>(t - 0.5);
}
template<typename T>
T BeatInMS(T bpm)
Expand Down