diff --git a/README.md b/README.md index 5cb254f3..e56ea9ae 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Open Fodder supports six demos from the Amiga platform, and three retail release -w, --window Start in window mode --window-scale arg Set the window scale (default: 0) --integer-scaling Set integer scaling (default: true) + --bilinear Apply bilinear filtering --cheats Enable cheat keys --max-sprite 45 Set the maximum sprites (default: 45) @@ -119,6 +120,7 @@ Open Fodder supports six demos from the Amiga platform, and three retail release ``` * F1: Switch to Amiga version (if available) * F2: Switch to PC version (if available) +* F8: Toggle bilinear filter * F9: Make current squad invincible (with --cheats enabled) * F10: Complete current map (with --cheats enabled) * F11: Toggle full screen diff --git a/Source/Fodder.cpp b/Source/Fodder.cpp index 6699ffb6..b69e3f08 100644 --- a/Source/Fodder.cpp +++ b/Source/Fodder.cpp @@ -2362,6 +2362,16 @@ void cFodder::keyProcess(uint8 pKeyCode, bool pPressed) mWindow->WindowDecrease(); } + // Toggle Bilinear Filtering by pressing F8 + if (pKeyCode == SDL_SCANCODE_F8 && pPressed) + { + if (g_Fodder->mParams) + if(!g_Fodder->mParams->mBilinearFilter) + g_Fodder->mParams->mBilinearFilter = true; + else + g_Fodder->mParams->mBilinearFilter = false; + } + if (pKeyCode == SDL_SCANCODE_F11 && pPressed) { mWindow->ToggleFullscreen(); diff --git a/Source/OptionsMenu.cpp b/Source/OptionsMenu.cpp index f3d195dc..eab41c50 100644 --- a/Source/OptionsMenu.cpp +++ b/Source/OptionsMenu.cpp @@ -159,6 +159,7 @@ void cOptionsMenu::BuildItems() { mItems.push_back({ eOptType::Toggle, eOptSection::Video, "Display mode", OPT_WINDOW_MODE }); mItems.push_back({ eOptType::IntRange, eOptSection::Video, "Window scale", OPT_WINDOW_SCALE, 0, 6, 1 }); mItems.push_back({ eOptType::Toggle, eOptSection::Video, "Integer scaling", OPT_INTEGER_SCALING }); + mItems.push_back({ eOptType::Toggle, eOptSection::Video, "Bilinear filtering", OPT_BILINEAR_FILTERING }); // These were in INI but missing from menu //mItems.push_back({ eOptType::IntRange, "Window columns", OPT_WINDOW_COLUMNS, 0, 80, 1 }); // 0=AUTO @@ -274,6 +275,7 @@ int cOptionsMenu::GetInt(int optId) const { return g_Fodder->mWindow->GetScaler(); return (int)g_Fodder->mStartParams->mWindowScale; case OPT_INTEGER_SCALING: return g_Fodder->mStartParams->mIntegerScaling ? 1 : 0; + case OPT_BILINEAR_FILTERING: return g_Fodder->mStartParams->mBilinearFilter ? 1 : 0; case OPT_WINDOW_COLUMNS: return (int)g_Fodder->mStartParams->mWindowColumns; case OPT_WINDOW_ROWS: return (int)g_Fodder->mStartParams->mWindowRows; @@ -334,7 +336,7 @@ void cOptionsMenu::SetInt(int optId, int v) { } break; } - + case OPT_WINDOW_SCALE: { const int clamped = clamp_int(v, 0, 6); g_Fodder->mStartParams->mWindowScale = (uint32)clamped; @@ -342,6 +344,13 @@ void cOptionsMenu::SetInt(int optId, int v) { break; } + case OPT_BILINEAR_FILTERING: { + g_Fodder->mStartParams->mBilinearFilter = (v != 0); + if (g_Fodder->mParams) + g_Fodder->mParams->mBilinearFilter = g_Fodder->mStartParams->mBilinearFilter; + break; + } + case OPT_WINDOW_COLUMNS: { const int clamped = clamp_int(v, 0, 80); g_Fodder->mStartParams->mWindowColumns = (uint32)clamped; @@ -696,6 +705,10 @@ void cOptionsMenu::ResetDefaults() { g_Fodder->mStartParams->clear(); mApplied = true; g_Fodder->mStartParams->SaveIni(); + + // Reset bilinear filtering to false (default value) for current parameters same as toggling the menu option but forcing false since bilinear filtering is OFF by default + if (g_Fodder->mParams) + g_Fodder->mParams->mBilinearFilter = false; } void cOptionsMenu::OnRowClick(int16 action, int16 arg) { diff --git a/Source/OptionsMenu.hpp b/Source/OptionsMenu.hpp index bfdf9a12..87b73bc1 100644 --- a/Source/OptionsMenu.hpp +++ b/Source/OptionsMenu.hpp @@ -81,7 +81,8 @@ class cOptionsMenu { OPT_WINDOW_MODE = 1, OPT_WINDOW_SCALE, OPT_INTEGER_SCALING, - + OPT_BILINEAR_FILTERING, + OPT_ALTERNATE_MOUSE, OPT_MOUSE_LOCKED, OPT_MOUSE_SPEED, diff --git a/Source/Parameters.cpp b/Source/Parameters.cpp index 168679fb..0f82318a 100644 --- a/Source/Parameters.cpp +++ b/Source/Parameters.cpp @@ -166,6 +166,8 @@ std::string sFodderParameters::ToJson() { Save["mWindowMode"] = mWindowMode; Save["mIntegerScaling"] = mIntegerScaling; + Save["mBilinearFilter"] = mBilinearFilter; + Save["mRandom"] = mRandom; Save["mRandomMapOptionsEnabled"] = mRandomMapOptionsEnabled; Save["mRandomMapSeed"] = mRandomMapSeed; @@ -210,6 +212,7 @@ bool sFodderParameters::FromJson(const std::string& pJson) { mMissionNumber = LoadedData["mMissionNumber"]; mPhaseNumber = LoadedData["mPhaseNumber"]; mWindowMode = LoadedData["mWindowMode"]; + mBilinearFilter = LoadedData["mBilinearFilter"]; mRandom = LoadedData["mRandom"]; if (LoadedData.count("mRandomMapOptionsEnabled") > 0) mRandomMapOptionsEnabled = LoadedData["mRandomMapOptionsEnabled"]; @@ -292,6 +295,7 @@ void sFodderParameters::PrepareOptions() { ("w,window", "Start in window mode", cxxopts::value()->default_value("false")) ("window-scale", "Set the window scale", cxxopts::value()->default_value("0")) ("integer-scaling", "Use integer scaling", cxxopts::value()->default_value("true")) + ("bilinear", "Apply bilinear filtering", cxxopts::value()->default_value("false")) ("cheats", "Enable cheat keys", cxxopts::value()->default_value("false")) ("max-sprite", "Set the maximum sprites", cxxopts::value()->default_value("45"), "45") @@ -486,6 +490,10 @@ bool sFodderParameters::ProcessCLI(int argc, char *argv[]) { if (result.count("integer-scaling")) mIntegerScaling = result["integer-scaling"].as(); + + if (result.count("bilinear")) + mBilinearFilter = result["bilinear"].as(); + mRandom = result["random"].as(); if (result["random-save"].count()) { @@ -753,6 +761,7 @@ bool sFodderParameters::SaveIni() { ini.set("scale", (mWindowScale == 0) ? "auto" : std::to_string(mWindowScale)); ini.set("integer", mIntegerScaling ? "true" : "false"); + ini.set("bilinear", mBilinearFilter ? "true" : "false"); ini.set("columns", (mWindowColumns == 0) ? "0" : std::to_string(mWindowColumns)); ini.set("rows", (mWindowRows == 0) ? "0" : std::to_string(mWindowRows)); @@ -845,6 +854,11 @@ bool sFodderParameters::ProcessINI() { else mWindowMode = false; + if (ini.get("bilinear", "false") == "true") + mBilinearFilter = true; + else + mBilinearFilter = false; + if (ini.get("cheats", "false") == "true") mCheatsEnabled = true; else diff --git a/Source/Parameters.hpp b/Source/Parameters.hpp index 6f5fd556..cc814c64 100644 --- a/Source/Parameters.hpp +++ b/Source/Parameters.hpp @@ -76,6 +76,8 @@ class sFodderParameters { size_t mWindowRows; size_t mWindowColumns; + bool mBilinearFilter; // Use bilinear filtering + bool mRandom; // Start a random map bool mRandomSave; // Create a random map bool mRandomMenuOnStart; // Open the create-random-map options menu on startup @@ -206,6 +208,7 @@ class sFodderParameters { mWindowMode = false; mIntegerScaling = true; mWindowScale = 0; + mBilinearFilter = false; mWindowRows = 0; mWindowColumns = 0; diff --git a/Source/Window.cpp b/Source/Window.cpp index eb531e0f..1132b3d8 100644 --- a/Source/Window.cpp +++ b/Source/Window.cpp @@ -41,6 +41,8 @@ cWindow::cWindow() { mHasFocus = true; mResized = false; + + mBilinearFilter = false; } cWindow::~cWindow() { @@ -430,6 +432,13 @@ void cWindow::RenderAt( cSurface* pImage ) { } } + if (g_Fodder->mParams->mBilinearFilter) { + SDL_SetTextureScaleMode(pImage->GetTexture(), SDL_SCALEMODE_LINEAR); + } + else { + SDL_SetTextureScaleMode(pImage->GetTexture(), SDL_SCALEMODE_NEAREST); + } + SDL_RenderTexture( mRenderer, pImage->GetTexture(), &Src, &Dest ); } @@ -459,6 +468,13 @@ void cWindow::RenderShrunk( cSurface* pImage ) { } } + if (g_Fodder->mParams->mBilinearFilter) { + SDL_SetTextureScaleMode(pImage->GetTexture(), SDL_SCALEMODE_LINEAR); + } + else { + SDL_SetTextureScaleMode(pImage->GetTexture(), SDL_SCALEMODE_NEAREST); + } + SDL_RenderTexture( mRenderer, pImage->GetTexture(), &Src, &Dest); } diff --git a/Source/Window.hpp b/Source/Window.hpp index b75cf62d..4b27689f 100644 --- a/Source/Window.hpp +++ b/Source/Window.hpp @@ -37,6 +37,7 @@ class cWindow { bool mWindowMode; bool mHasFocus; bool mResized; + bool mBilinearFilter; protected: @@ -106,7 +107,7 @@ class cWindow { void ToggleVSync(bool pEnabled); float GetRefreshRate(); - + }; class cWindowNull : public cWindow {