diff --git a/game/assets/lang/en_US.lang b/game/assets/lang/en_US.lang index d85d3c0b3..c86cb0cfe 100644 --- a/game/assets/lang/en_US.lang +++ b/game/assets/lang/en_US.lang @@ -103,7 +103,7 @@ options.guiScale.auto=Auto options.guiScale.small=Small options.guiScale.normal=Normal options.guiScale.large=Large -options.advancedOpengl=Advanced OpenGL +options.gamma=Gamma performance.max=Max FPS performance.balanced=Balanced diff --git a/platforms/input/xinput/GameControllerHandler_xinput.cpp b/platforms/input/xinput/GameControllerHandler_xinput.cpp index 02701c6f2..25b28e33f 100644 --- a/platforms/input/xinput/GameControllerHandler_xinput.cpp +++ b/platforms/input/xinput/GameControllerHandler_xinput.cpp @@ -109,10 +109,10 @@ void GameControllerHandler_xinput::refresh() float GameControllerHandler_xinput::normalizeAxis(float raw, float deadzone) const { - return Mth::Max(-1.0f, raw / 32767.0f); // -32768 to 32767 + return Mth::Max(-1.0f, raw / INT16_MAX); // Deadzone is currently handled in GameControllerManager - /*float v3 = Mth::Max(-1.0f, raw / 32767.0f); + /*float v3 = Mth::Max(-1.0f, raw / INT16_MAX); float v4 = fabs(v3); float v5; if (v4 >= deadzone) @@ -124,8 +124,8 @@ float GameControllerHandler_xinput::normalizeAxis(float raw, float deadzone) con void GameControllerHandler_xinput::normalizeAxes(Vec2& io, float deadzone) const { - io.x = Mth::Max(-1.0f, io.x / 32767.0f); - io.y = Mth::Max(-1.0f, io.y / 32767.0f); + io.x = Mth::Max(-1.0f, io.x / INT16_MAX); + io.y = Mth::Max(-1.0f, io.y / INT16_MAX); // Deadzone is currently handled in GameControllerManager /*float length = io.length(); diff --git a/platforms/sdl/base/AppPlatform_sdl.cpp b/platforms/sdl/base/AppPlatform_sdl.cpp index 28488b959..83f4887eb 100644 --- a/platforms/sdl/base/AppPlatform_sdl.cpp +++ b/platforms/sdl/base/AppPlatform_sdl.cpp @@ -317,7 +317,7 @@ void AppPlatform_sdl::handleControllerButtonEvent(SDL_JoystickID controllerIndex void AppPlatform_sdl::handleControllerAxisEvent(SDL_JoystickID controllerIndex, uint8_t axis, int16_t value) { - float val = value / 32767.0f; // -32768 to 32767 + float val = value / (float)INT16_MAX; // -32768 to 32767 switch (axis) { diff --git a/source/client/app/Minecraft.cpp b/source/client/app/Minecraft.cpp index 545333d5c..e6551e450 100644 --- a/source/client/app/Minecraft.cpp +++ b/source/client/app/Minecraft.cpp @@ -206,7 +206,7 @@ void Minecraft::_reloadInput() m_pLocalPlayer->m_pMoveInput = m_pInputHolder->getMoveInput(); } - getOptions()->field_19 = !isTouchscreen(); + getOptions()->m_bUseMouseForDigging = !isTouchscreen(); } int Minecraft::getLicenseId() @@ -608,7 +608,7 @@ void Minecraft::tickInput() #endif } - if (getOptions()->field_19) + if (getOptions()->m_bUseMouseForDigging) continue; // @TODO: Replace with KeyboardBuildInput diff --git a/source/client/options/Options.cpp b/source/client/options/Options.cpp index 2efecbf95..5d8beafc1 100644 --- a/source/client/options/Options.cpp +++ b/source/client/options/Options.cpp @@ -30,18 +30,18 @@ #include "client/gui/components/TickBox.hpp" #include "client/renderer/LogoRenderer.hpp" +#include "renderer/RenderContextImmediate.hpp" + void Options::_initDefaultValues() { - field_244 = 1.0f; + m_flySpeed = 1.0f; field_248 = 1.0f; - field_23E = 0; - field_241 = false; - field_24C = 0; - field_16 = 0; - field_240 = 1; - field_1C = "Default"; - field_19 = 1; + m_bFixedCamera = false; + m_bLimitFramerate = false; + field_240 = true; + m_skin = "Default"; + m_bUseMouseForDigging = true; #ifdef ORIGINAL_CODE m_viewDistance.set(2); m_thirdPerson.set(0); @@ -78,6 +78,8 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : , m_hideGui("gfx_hidegui", "options.hideGui", false) , m_thirdPerson("gfx_thirdperson", "options.thirdPerson", false) , m_flightHax("misc_flycheat", "options.flightHax", false) + , m_guiScale("gfx_guiscale", "options.guiScale", 0, ValuesBuilder().add("options.guiScale.auto").add("options.guiScale.small").add("options.guiScale.normal").add(("options.guiScale.large"))) + , m_gamma("gfx_gamma", "options.gamma", 0.50f) , m_playerName("mp_username", "options.username", "Steve") , m_serverVisibleDefault("mp_server_visible_default", "options.serverVisibleDefault", true) , m_autoJump("ctrl_autojump", "options.autoJump", mc->platform()->isTouchscreen()) @@ -89,7 +91,6 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : , m_bUseController("ctrl_usecontroller", "options.useController", false) , m_dynamicHand("gfx_dynamichand", "options.dynamicHand", false) , m_menuPanorama("misc_menupano", "options.menuPanorama", true) - , m_guiScale("gfx_guiscale", "options.guiScale", 0, ValuesBuilder().add("options.guiScale.auto").add("options.guiScale.small").add("options.guiScale.normal").add(("options.guiScale.large"))) , m_lang("gfx_lang", "options.lang", "en_us") , m_uiTheme("gfx_uitheme", "options.uiTheme", GetDefaultUiTheme(m_pMinecraft), ValuesBuilder().add("options.uiTheme.pocket").add("options.uiTheme.java").add("options.uiTheme.console")) , m_logoType("gfx_logotype", "options.logoType", LOGO_AUTO, ValuesBuilder().add("options.logoType.auto").add("options.logoType.pocket").add("options.logoType.java").add("options.logoType.console").add("options.logoType.xbox360").add("options.logoType.logo3d")) @@ -114,6 +115,7 @@ Options::Options(Minecraft* mc, const std::string& folderPath) : add(m_biomeColors); add(m_ambientOcclusion); add(m_guiScale); + add(m_gamma); //add(m_limitFramerate); add(m_autoJump); //add(m_bMipmaps); @@ -275,16 +277,12 @@ std::string Options::saveBool(bool b) std::string Options::saveInt(int i) { - std::stringstream ss; - ss << i; - return ss.str(); + return Util::toString(i); } std::string Options::saveFloat(float f) { - std::stringstream ss; - ss << f; - return ss.str(); + return Util::toString(f); } std::string Options::saveArray(const std::vector& arr) @@ -698,18 +696,6 @@ void OptionEntry::addGuiElement(std::vector& elements, UITheme uiTh elements.push_back(new SmallButton(0, 0, this, getMessage())); } -void AOOption::apply() -{ - Minecraft::useAmbientOcclusion = get(); - if (m_pMinecraft->m_pLevelRenderer) - m_pMinecraft->m_pLevelRenderer->allChanged(); -} - -void GuiScaleOption::apply() -{ - m_pMinecraft->sizeUpdate(Minecraft::width, Minecraft::height); -} - void FloatOption::load(const std::string& value) { set(Options::readFloat(value)); @@ -717,7 +703,7 @@ void FloatOption::load(const std::string& value) std::string FloatOption::getDisplayValue() const { - return get() == 0.0f ? Language::get("options.off") : Options::saveInt(get() * 100) + "%"; + return get() == 0.0f ? Language::get("options.off") : Util::toString(get() * 100) + "%"; } void FloatOption::addGuiElement(std::vector& elements, UITheme uiTheme) @@ -725,6 +711,11 @@ void FloatOption::addGuiElement(std::vector& elements, UITheme uiTh elements.push_back(new SliderButton(0, 0, 200, uiTheme == UI_CONSOLE ? 32 : 20, this, getMessage(), toFloat())); } +void IntOption::load(const std::string& value) +{ + set(Options::readInt(value)); +} + void BoolOption::load(const std::string& value) { set(Options::readBool(value)); @@ -761,25 +752,45 @@ void MinMaxOption::addGuiElement(std::vector& elements, UITheme uiT elements.push_back(new SwitchValuesButton(0, 0, this, getDisplayName())); } -void GraphicsOption::apply() +std::string SensitivityOption::getDisplayValue() const +{ + return get() == 0.0f ? Language::get("options.sensitivity.min") : get() == 1.0f ? Language::get("options.sensitivity.max") : Util::toString(int(get() * 200)) + "%"; +} + +void AOOption::apply() { + Minecraft::useAmbientOcclusion = get(); if (m_pMinecraft->m_pLevelRenderer) m_pMinecraft->m_pLevelRenderer->allChanged(); } -std::string FancyGraphicsOption::getMessage() const +void GuiScaleOption::apply() { - return Util::format(Language::get("options.value").c_str(), Language::get("options.graphics").c_str(), Language::get(get() ? "options.graphics.fancy" : "options.graphics.fast").c_str()); + m_pMinecraft->sizeUpdate(Minecraft::width, Minecraft::height); } -std::string SensitivityOption::getDisplayValue() const +void GammaOption::apply() { - return get() == 0.0f ? Language::get("options.sensitivity.min") : get() == 1.0f ? Language::get("options.sensitivity.max") : Options::saveInt(get() * 200) + "%"; + // Budget rounding since the 360 just doesn't have a round function + // @TODO: Then again, we don't need this level or precision to begin with + // I just don't wanna have to rework the SliderButton to support integers + m_pMinecraft->m_pGameRenderer->setGamma((float)Mth::floor(get() * 100) / 100); } -void IntOption::load(const std::string& value) +std::string GammaOption::getDisplayValue() const { - set(Options::readInt(value)); + return Util::toString(int(get() * 100)) + "%"; +} + +void GraphicsOption::apply() +{ + if (m_pMinecraft->m_pLevelRenderer) + m_pMinecraft->m_pLevelRenderer->allChanged(); +} + +std::string FancyGraphicsOption::getMessage() const +{ + return Util::format(Language::get("options.value").c_str(), Language::get("options.graphics").c_str(), Language::get(get() ? "options.graphics.fancy" : "options.graphics.fast").c_str()); } void LogoTypeOption::apply() @@ -793,7 +804,7 @@ void LogoTypeOption::apply() std::string HUDSizeOption::getDisplayValue() const { - return Options::saveInt(get() - 1); + return Util::toString(get() - 1); } void UIThemeOption::apply() diff --git a/source/client/options/Options.hpp b/source/client/options/Options.hpp index 0e1e3faeb..abeaa3590 100644 --- a/source/client/options/Options.hpp +++ b/source/client/options/Options.hpp @@ -193,38 +193,6 @@ class FloatOption : public OptionInstance float m_unit; }; -class SensitivityOption : public FloatOption -{ -public: - SensitivityOption(const std::string& key, const std::string& name, float initial = 0.0f) : FloatOption(key, name, initial, 0.005f) {} - - std::string getDisplayValue() const override; -}; - -class AOOption : public BoolOption -{ -public: - AOOption(const std::string& key, const std::string& name, bool initial = true) : BoolOption(key, name, initial) {} - - void apply() override; -}; - -class GraphicsOption : public BoolOption -{ -public: - GraphicsOption(const std::string& key, const std::string& name, bool initial = true) : BoolOption(key, name, initial) {} - - void apply() override; -}; - -class FancyGraphicsOption : public GraphicsOption -{ -public: - FancyGraphicsOption(const std::string& key, const std::string& name, bool initial = true) : GraphicsOption(key, name, initial) {} - - std::string getMessage() const override; -}; - class IntOption : public OptionInstance { public: @@ -259,7 +227,9 @@ class ValuesBuilder class MinMaxOption : public IntOption { public: - MinMaxOption(const std::string& key, const std::string& name, int initial, int min, int max) : IntOption(key, name, initial), m_min(min), m_max(max) + MinMaxOption(const std::string& key, const std::string& name, int initial, int min, int max) : IntOption(key, name, initial) + , m_min(min) + , m_max(max) { } @@ -273,11 +243,11 @@ class MinMaxOption : public IntOption int m_min, m_max; }; - class ValuesOption : public MinMaxOption { public: - ValuesOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : MinMaxOption(key, name, initial, 0, values.m_values.size()), m_values(values.m_values) + ValuesOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : MinMaxOption(key, name, initial, 0, values.m_values.size()) + , m_values(values.m_values) { } @@ -288,22 +258,59 @@ class ValuesOption : public MinMaxOption std::vector m_values; }; +class SensitivityOption : public FloatOption +{ +public: + SensitivityOption(const std::string& key, const std::string& name, float initial = 0.0f) : FloatOption(key, name, initial, 0.005f) {} + + std::string getDisplayValue() const override; +}; + +class AOOption : public BoolOption +{ +public: + AOOption(const std::string& key, const std::string& name, bool initial = true) : BoolOption(key, name, initial) {} + + void apply() override; +}; + +class GraphicsOption : public BoolOption +{ +public: + GraphicsOption(const std::string& key, const std::string& name, bool initial = true) : BoolOption(key, name, initial) {} + + void apply() override; +}; + +class FancyGraphicsOption : public GraphicsOption +{ +public: + FancyGraphicsOption(const std::string& key, const std::string& name, bool initial = true) : GraphicsOption(key, name, initial) {} + + std::string getMessage() const override; +}; + class GuiScaleOption : public ValuesOption { public: - GuiScaleOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) - { - } + GuiScaleOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) {} + + void apply() override; +}; + +class GammaOption : public FloatOption +{ +public: + GammaOption(const std::string& key, const std::string& name, float initial) : FloatOption(key, name, initial, 0.01f) {} void apply() override; + std::string getDisplayValue() const override; }; class LogoTypeOption : public ValuesOption { public: - LogoTypeOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) - { - } + LogoTypeOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) {} void apply() override; }; @@ -311,9 +318,7 @@ class LogoTypeOption : public ValuesOption class UIThemeOption : public ValuesOption { public: - UIThemeOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) - { - } + UIThemeOption(const std::string& key, const std::string& name, int initial, const ValuesBuilder& values) : ValuesOption(key, name, initial, values) {} void apply() override; }; @@ -321,9 +326,7 @@ class UIThemeOption : public ValuesOption class HUDSizeOption : public MinMaxOption { public: - HUDSizeOption(const std::string& key, const std::string& name, int initial) : MinMaxOption(key, name, initial, HUD_SIZE_1, HUD_SIZE_3 + 1) - { - } + HUDSizeOption(const std::string& key, const std::string& name, int initial) : MinMaxOption(key, name, initial, HUD_SIZE_1, HUD_SIZE_3 + 1) {} std::string getDisplayValue() const override; }; @@ -399,21 +402,21 @@ class Options ValuesOption m_viewDistance; BoolOption m_viewBobbing; BoolOption m_anaglyphs; - uint8_t field_16; + bool m_bLimitFramerate; FancyGraphicsOption m_fancyGraphics; AOOption m_ambientOcclusion; - uint8_t field_19; // use Mouse as input for breaking - std::string field_1C; + bool m_bUseMouseForDigging; + std::string m_skin; ValuesOption m_difficulty; BoolOption m_hideGui; BoolOption m_thirdPerson; - uint8_t field_23E; BoolOption m_flightHax; - uint8_t field_240; - bool field_241; - float field_244; + bool field_240; // seems like it's doing some sort of mouse smoothing + bool m_bFixedCamera; + float m_flySpeed; float field_248; - int field_24C; + GuiScaleOption m_guiScale; + GammaOption m_gamma; StringOption m_playerName; BoolOption m_serverVisibleDefault; BoolOption m_autoJump; @@ -425,7 +428,6 @@ class Options BoolOption m_bUseController; BoolOption m_dynamicHand; BoolOption m_menuPanorama; - GuiScaleOption m_guiScale; StringOption m_lang; UIThemeOption m_uiTheme; LogoTypeOption m_logoType; @@ -471,6 +473,7 @@ class Options /*OPTION(m_antiAliasing);*/ \ /*OPTION(m_guiScale);*/ \ /*OPTION(m_fov);*/ \ + OPTION(m_gamma); \ OPTION(m_ambientOcclusion); \ OPTION(m_fancyGraphics); \ OPTION(m_viewBobbing); \ diff --git a/source/client/player/LocalPlayer.cpp b/source/client/player/LocalPlayer.cpp index ec62ed15b..a328dbe5c 100644 --- a/source/client/player/LocalPlayer.cpp +++ b/source/client/player/LocalPlayer.cpp @@ -195,7 +195,7 @@ void LocalPlayer::hurtTo(int newHealth) void LocalPlayer::calculateFlight(const Vec3& pos) { - float f1 = m_pMinecraft->getOptions()->field_244; + float f1 = m_pMinecraft->getOptions()->m_flySpeed; float x1 = f1 * pos.x; float z1 = f1 * pos.z; diff --git a/source/client/renderer/GameRenderer.cpp b/source/client/renderer/GameRenderer.cpp index 97b2a69e3..466ff57fd 100644 --- a/source/client/renderer/GameRenderer.cpp +++ b/source/client/renderer/GameRenderer.cpp @@ -77,6 +77,8 @@ GameRenderer::GameRenderer(Minecraft* pMinecraft) : #ifdef FEATURE_GFX_SHADERS mce::GlobalConstantBuffers::getInstance().init(); #endif + + m_pMinecraft->getOptions()->m_gamma.apply(); } GameRenderer::~GameRenderer() @@ -312,7 +314,7 @@ void GameRenderer::moveCameraToPlayer(Matrix& matrix, float f) if (m_pMinecraft->getOptions()->m_thirdPerson.get()) { float v11 = field_30 + (field_2C - field_30) * f; - if (m_pMinecraft->getOptions()->field_241) + if (m_pMinecraft->getOptions()->m_bFixedCamera) { matrix.translate(Vec3::NEG_UNIT_Z * v11); matrix.rotate(field_38 + (field_34 - field_38) * f, Vec3::UNIT_X); @@ -363,7 +365,7 @@ void GameRenderer::moveCameraToPlayer(Matrix& matrix, float f) matrix.translate(Vec3(0.0f, 0.0f, -0.1f)); } - if (!m_pMinecraft->getOptions()->field_241) + if (!m_pMinecraft->getOptions()->m_bFixedCamera) { matrix.rotate(pMob->m_oRot.y + f * (pMob->m_rot.y - pMob->m_oRot.y), Vec3::UNIT_X); matrix.rotate(pMob->m_oRot.x + f * (pMob->m_rot.x - pMob->m_oRot.x) + 180.0f, Vec3::UNIT_Y); @@ -613,7 +615,7 @@ void GameRenderer::render(const Timer& timer) float v20 = mult1 * 0.25f * (v17 - v18); float v21 = v19 + (v20 - v19) * 0.5f; field_1C = v21; - if ((v20 <= 0.0 || v20 <= v21) && (v20 >= 0.0 || v20 >= v21)) + if ((v20 <= 0.0f || v20 <= v21) && (v20 >= 0.0f || v20 >= v21)) v21 = mult1 * 0.25f * (v17 - v18); float v22 = d.y + field_20; field_18 = v18 + v21; @@ -622,7 +624,7 @@ void GameRenderer::render(const Timer& timer) float v24 = mult1 * 0.15f * (v22 - v23); float v25 = field_28 + (v24 - field_28) * 0.5f; field_28 = v25; - if ((v24 <= 0.0 || v24 <= v25) && (v24 >= 0.0 || v24 >= v25)) + if ((v24 <= 0.0f || v24 <= v25) && (v24 >= 0.0f || v24 >= v25)) v25 = v24; field_24 = v23 + v25; } @@ -873,9 +875,16 @@ void GameRenderer::setLevel(Level* pLevel, Dimension* pDimension) //_tickLightTexture(pDimension, 1.0f); } -void GameRenderer::onGraphicsReset() +void GameRenderer::setGamma(float gamma) { + mce::RenderContext& renderContext = mce::RenderContextImmediate::get(); + renderContext.setGamma(gamma * (INT16_MAX+1)); +} +void GameRenderer::onGraphicsReset() +{ + // We might not need this long-term, but putting it here just in case + m_pMinecraft->getOptions()->m_gamma.apply(); } void GameRenderer::pick(float f) diff --git a/source/client/renderer/GameRenderer.hpp b/source/client/renderer/GameRenderer.hpp index 932acdf0d..5b890699b 100644 --- a/source/client/renderer/GameRenderer.hpp +++ b/source/client/renderer/GameRenderer.hpp @@ -53,6 +53,8 @@ class GameRenderer void renderWeather(float f); void renderPointer(const MenuPointer& pointer); void setLevel(Level* pLevel, Dimension* pDimension); + // Range: 0.0 - 1.0 + void setGamma(float gamma); void tick(); void setupGuiScreen(); void onGraphicsReset(); diff --git a/source/client/renderer/renderer/Tesselator.cpp b/source/client/renderer/renderer/Tesselator.cpp index 5b81110d9..59793a0ee 100644 --- a/source/client/renderer/renderer/Tesselator.cpp +++ b/source/client/renderer/renderer/Tesselator.cpp @@ -465,13 +465,13 @@ void Tesselator::vertex(float x, float y, float z) #ifdef ENH_GFX_COMPACT_UVS if (renderContext.supports16BitUnsignedUVs()) { - ((uint16_t*)m_currentVertex.uvs[i])[0] = (uint16_t)ceilf(m_nextVtxUVs[i].x * 65535.f); - ((uint16_t*)m_currentVertex.uvs[i])[1] = (uint16_t)ceilf(m_nextVtxUVs[i].y * 65535.f); + ((uint16_t*)m_currentVertex.uvs[i])[0] = (uint16_t)ceilf(m_nextVtxUVs[i].x * UINT16_MAX); + ((uint16_t*)m_currentVertex.uvs[i])[1] = (uint16_t)ceilf(m_nextVtxUVs[i].y * UINT16_MAX); } else { - ((int16_t*)m_currentVertex.uvs[i])[0] = (int16_t)ceilf(m_nextVtxUVs[i].x * 32767.f); - ((int16_t*)m_currentVertex.uvs[i])[1] = (int16_t)ceilf(m_nextVtxUVs[i].y * 32767.f); + ((int16_t*)m_currentVertex.uvs[i])[0] = (int16_t)ceilf(m_nextVtxUVs[i].x * INT16_MAX); + ((int16_t*)m_currentVertex.uvs[i])[1] = (int16_t)ceilf(m_nextVtxUVs[i].y * INT16_MAX); } #else ((float*)m_currentVertex.uvs[i])[0] = m_nextVtxUVs[i].x; diff --git a/source/common/DataIO.cpp b/source/common/DataIO.cpp index 89c5902d4..4f97bd8e5 100644 --- a/source/common/DataIO.cpp +++ b/source/common/DataIO.cpp @@ -3,7 +3,7 @@ #include "DataIO.hpp" -#define STR16_MAX_LEN 32767 +#define STR16_MAX_LEN INT16_MAX #define STR32_MAX_LEN 2147483647 std::string IDataInput::_readString() diff --git a/source/common/Util.cpp b/source/common/Util.cpp index 8d20d3c24..8dd7dc94d 100644 --- a/source/common/Util.cpp +++ b/source/common/Util.cpp @@ -6,6 +6,7 @@ SPDX-License-Identifier: BSD-1-Clause ********************************************************************/ +#include #include #include #include "Util.hpp" @@ -139,6 +140,13 @@ std::string Util::toString(int value) return str; } +std::string Util::toString(float value) +{ + std::stringstream ss; + ss << value; + return ss.str(); +} + std::string Util::toString(const wchar_t* str) { std::string result(wcslen(str), 0); diff --git a/source/common/Util.hpp b/source/common/Util.hpp index 207326f99..d640743e9 100644 --- a/source/common/Util.hpp +++ b/source/common/Util.hpp @@ -33,6 +33,7 @@ class Util static std::string getExtension(const std::string& path); static std::string toString(int value); + static std::string toString(float value); static std::string toString(const wchar_t* str); static std::string toString(const std::wstring& str); static std::wstring toWideString(const std::string& str); @@ -64,7 +65,6 @@ class Util return removed; } - // @TODO: reverse the actual thing? This is something different, but I'm lazy. It uses std::string::replace static void stringReplace(std::string& in, const std::string& what, const std::string& with) { //snippet from Zahlman's post on gamedev: http://www.gamedev.net/community/forums/topic.asp?topic_id=372125 diff --git a/source/renderer/hal/base/RenderContextBase.cpp b/source/renderer/hal/base/RenderContextBase.cpp index 7bcdfcf1a..849c39c69 100644 --- a/source/renderer/hal/base/RenderContextBase.cpp +++ b/source/renderer/hal/base/RenderContextBase.cpp @@ -5,7 +5,6 @@ using namespace mce; RenderContextBase::RenderContextBase() { m_pRenderDevice = nullptr; - m_currentShadeMode = SHADE_MODE_SMOOTH; } void RenderContextBase::loadMatrix(MatrixType matrixType, const Matrix& matrix) @@ -31,20 +30,30 @@ void RenderContextBase::disableFixedLighting(bool teardown) bool RenderContextBase::setShadeMode(ShadeMode mode) { - if (mode == m_currentShadeMode) + if (m_currentState.m_bBoundShadeMode && m_currentState.m_shadeMode == mode) return false; - m_currentShadeMode = mode; + m_currentState.m_shadeMode = mode; return true; } bool RenderContextBase::setCurrentColor(const Color& color) { - if (color == m_currentColor) + if (m_currentState.m_bBoundColor && m_currentState.m_color == color) return false; - m_currentColor = color; + m_currentState.m_color = color; + + return true; +} + +bool RenderContextBase::setGamma(Gamma gamma) +{ + if (m_currentState.m_bBoundGamma && m_currentState.m_gamma == gamma) + return false; + + m_currentState.m_gamma = gamma; return true; } diff --git a/source/renderer/hal/base/RenderContextBase.hpp b/source/renderer/hal/base/RenderContextBase.hpp index 5b869f843..a3c8f1cc4 100644 --- a/source/renderer/hal/base/RenderContextBase.hpp +++ b/source/renderer/hal/base/RenderContextBase.hpp @@ -1,12 +1,9 @@ #pragma once #include "RenderContextStateBase.hpp" -#include "common/math/Color.hpp" #include "renderer/VertexFormat.hpp" #include "renderer/MatrixStack.hpp" #include "renderer/hal/enums/PrimitiveMode.hpp" -#include "renderer/hal/enums/ShadeMode.hpp" -#include "renderer/hal/enums/ShaderType.hpp" #include "renderer/hal/interface/ShaderProgram.hpp" #include "renderer/hal/interface/ImmediateBuffer.hpp" #include "renderer/hal/interface/RenderDevice.hpp" @@ -21,8 +18,6 @@ namespace mce VertexFormat m_lastVertexFormat; unsigned int m_lastAttributeListIndex; ShaderProgram* m_lastShaderPrograms[SHADER_TYPES_COUNT]; - Color m_currentColor; - ShadeMode m_currentShadeMode; ImmediateBuffer m_immediateBuffer; StencilRefObject m_stencilReference; RenderDevice *m_pRenderDevice; @@ -38,6 +33,7 @@ namespace mce void disableFixedLighting(bool teardown); bool setShadeMode(ShadeMode mode); bool setCurrentColor(const Color& color); + bool setGamma(Gamma gamma); void draw(PrimitiveMode primitiveMode, unsigned int startOffset, unsigned int count); void drawIndexed(PrimitiveMode primitiveMode, unsigned int count, uint8_t indexSize); void drawIndexed(PrimitiveMode primitiveMode, unsigned int count, unsigned int startOffset, uint8_t indexSize); diff --git a/source/renderer/hal/base/RenderContextStateBase.cpp b/source/renderer/hal/base/RenderContextStateBase.cpp index d5b0498de..323c556c5 100644 --- a/source/renderer/hal/base/RenderContextStateBase.cpp +++ b/source/renderer/hal/base/RenderContextStateBase.cpp @@ -4,6 +4,7 @@ using namespace mce; RenderContextStateBase::RenderContextStateBase() { + m_shadeMode = SHADE_MODE_SMOOTH; clear(); } @@ -14,4 +15,7 @@ void RenderContextStateBase::clear() m_bBoundRasterizerState = false; m_bBoundFixedPipelineState = false; m_bBoundFogState = false; + m_bBoundColor = false; + m_bBoundShadeMode = false; + m_bBoundGamma = false; } diff --git a/source/renderer/hal/base/RenderContextStateBase.hpp b/source/renderer/hal/base/RenderContextStateBase.hpp index d5dee8f17..e3e9092db 100644 --- a/source/renderer/hal/base/RenderContextStateBase.hpp +++ b/source/renderer/hal/base/RenderContextStateBase.hpp @@ -5,9 +5,14 @@ #include "renderer/hal/RasterizerStateDescription.hpp" #include "renderer/hal/FixedPipelineStateDescription.hpp" #include "renderer/hal/FogStateDescription.hpp" +#include "common/math/Color.hpp" +#include "renderer/hal/enums/ShadeMode.hpp" namespace mce { + // Ranges from 0 - 32768 + typedef uint16_t Gamma; + class RenderContextStateBase { public: @@ -16,11 +21,17 @@ namespace mce RasterizerStateDescription m_rasterizerStateDescription; FixedPipelineStateDescription m_fixedPipelineStateDescription; FogStateDescription m_fogStateDescription; + Color m_color; + ShadeMode m_shadeMode; + Gamma m_gamma; bool m_bBoundBlendState; bool m_bBoundDepthStencilState; bool m_bBoundRasterizerState; bool m_bBoundFixedPipelineState; bool m_bBoundFogState; + bool m_bBoundColor; + bool m_bBoundShadeMode; + bool m_bBoundGamma; public: RenderContextStateBase(); diff --git a/source/renderer/hal/d3d9/RenderContextD3D9.cpp b/source/renderer/hal/d3d9/RenderContextD3D9.cpp index 329005ee7..ed5172334 100644 --- a/source/renderer/hal/d3d9/RenderContextD3D9.cpp +++ b/source/renderer/hal/d3d9/RenderContextD3D9.cpp @@ -2,6 +2,7 @@ #include "RenderContextD3D9.hpp" #include "compat/PlatformDefinitions.h" #include "common/Logger.hpp" +#include "common/Mth.hpp" #include "renderer/hal/d3d9/helpers/ErrorHandlerD3D9.hpp" using namespace mce; @@ -54,6 +55,48 @@ RenderContextD3D9::RenderContextD3D9() createDeviceResources(); } +// Scaling factor for the input +#define C_GAMMA_RANGE_SCALE 1.5f // Assumed 1.0 (range of gamma shift) +// Base gamma value +#define C_GAMMA_BASE_OFFSET 0.5f // Assumed 0.5 (min gamma) + +bool RenderContextD3D9::setGamma(Gamma gamma) +{ + if (!RenderContextBase::setGamma(gamma)) + return false; + + // Calculate the target Gamma value based on linear equation + // Formula: Gamma = ((Input / 32768) * Scale) + Base + float normalized = (float)gamma / INT16_MAX; + float scaled = normalized * C_GAMMA_RANGE_SCALE; + float calculatedGamma = scaled + C_GAMMA_BASE_OFFSET; + + // Calculate the exponent for the ramp generation (1.0 / Gamma) + float exponent = 1.0f / calculatedGamma; + + D3DGAMMARAMP ramp; + for (int i = 0; i < 256; i++) + { + // Normalize index to 0.0 - 1.0 range + float linear = (float)i / 255.0f; + + // Apply gamma curve + float corrected = powf(linear, exponent); + + // Scale to 16-bit color range (0 - 65535) + float scaled = corrected * UINT16_MAX; + + int val = Mth::clamp((int)scaled, 0, UINT16_MAX); + ramp.red[i] = (uint16_t)val; + ramp.green[i] = (uint16_t)val; + ramp.blue[i] = (uint16_t)val; + } + + m_d3dDevice->SetGammaRamp(0, 0x0, &ramp); + + return true; +} + void RenderContextD3D9::draw(PrimitiveMode primitiveMode, unsigned int startOffset, unsigned int count) { ErrorHandlerD3D9::checkForErrors( diff --git a/source/renderer/hal/d3d9/RenderContextD3D9.hpp b/source/renderer/hal/d3d9/RenderContextD3D9.hpp index d5c303fdc..f18fb5b0c 100644 --- a/source/renderer/hal/d3d9/RenderContextD3D9.hpp +++ b/source/renderer/hal/d3d9/RenderContextD3D9.hpp @@ -55,6 +55,7 @@ namespace mce RenderContextD3D9(); public: + bool setGamma(Gamma gamma); void draw(PrimitiveMode primitiveMode, unsigned int startOffset, unsigned int count); void drawIndexed(PrimitiveMode primitiveMode, unsigned int count, uint8_t indexSize); void drawIndexed(PrimitiveMode primitiveMode, unsigned int count, unsigned int startOffset, uint8_t indexSize);