From 58803cad1d10b8db213bfc5b434a86ca3236114c Mon Sep 17 00:00:00 2001 From: David Vogel Date: Fri, 29 Jul 2022 00:26:57 +0200 Subject: [PATCH] Add memory manipulation to set specific options #14 --- files/modification.lua | 64 +++++++++++++++++++++++++++++++++++++++--- init.lua | 9 ++++-- settings.lua | 4 +-- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/files/modification.lua b/files/modification.lua index b54560c..2d6d045 100644 --- a/files/modification.lua +++ b/files/modification.lua @@ -4,7 +4,7 @@ -- https://opensource.org/licenses/MIT -- Noita settings/configuration modifications. --- We try to keep non volatile modifications to a minimum, but some things have to be changed in order for the mod to work correctly. +-- We try to keep persistent modifications to a minimum, but some things have to be changed in order for the mod to work correctly. -------------------------- -- Load library modules -- @@ -12,6 +12,7 @@ local CameraAPI = require("noita-api.camera") local Coords = require("coordinates") +local ffi = require("ffi") local NXML = require("luanxml.nxml") local Utils = require("noita-api.utils") local Vec2 = require("noita-api.vec2") @@ -64,11 +65,60 @@ function Modification.SetMagicNumbers(magic) ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/generated.xml") end +---Changes some options directly by manipulating process memory. +--- +---Related issue: https://github.com/Dadido3/noita-mapcap/issues/14. +---@param memory table +function Modification.SetMemoryOptions(memory) + -- Lookup table with the following hierarchy: + -- DevBuild -> OS -> BuildDate -> Option -> Address. + local lookup = { + [true] = { + Windows = { + [0x00F77B0C] = { _BuildString = "Build Apr 23 2021 18:36:55", -- GOG build. + mPostFxDisabled = 0x010E3B6C, + mGuiDisabled = 0x010E3B6D, + mFreezeAI = 0x010E3B73, + }, + [0x00F80384] = { _BuildString = "Build Apr 23 2021 18:40:40", -- Steam build. + mPostFxDisabled = 0x010EDEBC, + mGuiDisabled = 0x010EDEBD, + mFreezeAI = 0x010EDEC3, + }, + }, + }, + } + + -- Look up the tree and set options accordingly. + + local level1 = lookup[DebugGetIsDevBuild()] + if level1 == nil then return end + + local level2 = level1[ffi.os] + if level2 == nil then return end + + local level3 + for k, v in pairs(level2) do + if ffi.string(ffi.cast("char*", k)) == v._BuildString then + level3 = v + break + end + end + + for k, v in pairs(memory) do + local address = level3[k] + if address ~= nil then + ffi.cast("char*", address)[0] = v + end + end +end + ---Returns tables with user requested game configuration changes. ---@return table config -- List of `config.xml` attributes that should be changed. ---@return table magic -- List of `magic_number.xml` attributes that should be changed. +---@return table memory -- List of options in RAM of this process that should be changed. function Modification.RequiredChanges() - local config, magic = {}, {} + local config, magic, memory = {}, {}, {} -- Does the user request a custom resolution? local customResolution = (ModSettingGet("noita-mapcap.custom-resolution-live") and ModSettingGet("noita-mapcap.capture-mode") == "live") @@ -104,7 +154,13 @@ function Modification.RequiredChanges() magic["DEBUG_PAUSE_BOX2D"] = ModSettingGet("noita-mapcap.disable-physics") and "1" or "0" magic["DEBUG_DISABLE_POSTFX_DITHERING"] = ModSettingGet("noita-mapcap.disable-postfx") and "1" or "0" - return config, magic + if ModSettingGet("noita-mapcap.disable-shaders-gui-ai") then + memory["mPostFxDisabled"] = 1 + memory["mGuiDisabled"] = 1 + memory["mFreezeAI"] = 1 + end + + return config, magic, memory end ---Sets the camera free if required by the mod settings. @@ -132,7 +188,7 @@ function Modification.AutoSet() Modification.SetConfig(config) end ----Will reset all settings that may have been changed by this mod. +---Will reset all persistent settings that may have been changed by this mod. --- ---This will force close Noita! function Modification.Reset() diff --git a/init.lua b/init.lua index c1af568..98d3fca 100644 --- a/init.lua +++ b/init.lua @@ -55,9 +55,10 @@ dofile("mods/noita-mapcap/files/ui.lua") ---Called in order upon loading a new(?) game. function OnModPreInit() - -- Set magic numbers based on mod settings. - local config, magic = Modification.RequiredChanges() + -- Set magic numbers and other stuff based on mod settings. + local config, magic, memory = Modification.RequiredChanges() Modification.SetMagicNumbers(magic) + Modification.SetMemoryOptions(memory) -- Override virtual resolution and some other stuff. --ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic-numbers/1024.xml") @@ -141,6 +142,10 @@ end ---@param isPaused boolean ---@param isInventoryPause boolean function OnPausedChanged(isPaused, isInventoryPause) + -- Set some stuff based on mod settings. + -- Normally this would be in `OnModSettingsChanged`, but that doesn't seem to be called. + local config, magic, memory = Modification.RequiredChanges() + Modification.SetMemoryOptions(memory) end ---Will be called when the game is unpaused, if player changed any mod settings while the game was paused. diff --git a/settings.lua b/settings.lua index 3504162..9ecb08d 100644 --- a/settings.lua +++ b/settings.lua @@ -273,9 +273,9 @@ modSettings = { id = "disable-physics", ui_name = " Disable pixel and entity physics", ui_description = "Will freeze all pixel simulations and rigid body dynamics.", + hidden = not DebugAPI.IsDevBuild(), value_default = DebugAPI.IsDevBuild(), -- Defaults to true in dev build, false in regular Noita. scope = MOD_SETTING_SCOPE_RUNTIME_RESTART, - show_fn = function() return DebugAPI.IsDevBuild() end, }, { id = "disable-postfx", @@ -297,7 +297,7 @@ modSettings = { ui_description = "It has the same effect as pressing F5, F8 and F12 in the Noita dev build.\nDoesn't work outside the dev build.", hidden = not DebugAPI:IsDevBuild(), -- Hide in anything else than the dev build. value_default = false, - scope = MOD_SETTING_SCOPE_RUNTIME_RESTART, + scope = MOD_SETTING_SCOPE_RUNTIME, }, } },