Skip to content

Instructions for Minecraft Story Mode on Proton/Linux #28

@49016

Description

@49016

Since this is the only real result for looking up how to play MCSM in 21:9, and I spent a bit of time on this, here are some instructions.

MCSM not being available anymore makes getting your hands on the same executable a bit hard. I went with the FitGirl repack, so your .exe should have the SHA256 8844367.... I am also running the game through Proton Experimental via Steam.

The exact pattern from FlawlessWidescreen for The Wolf Among Us does not seem to work anymore:

(gdb) find /b 0x00400000,0x00fb4000,0x55,0x8b,0xec,0x80,0x3d,0x00,0x00,0x8b
Pattern not found.

However, a more lenient pattern finds it:

(gdb) find /b 0x00400000,0x00fb4000,0x55,0x8b,0xec,0x80,0x3d
0x489720
0x4ff540
0x511bc0
0x511c50
0x5a6660
0x5a66b0
0x7fed30
0x961170
0xb4e148
9 patterns found.
(gdb) x/20bx 0x489720
0x489720:       0x55    0x8b    0xec    0x80    0x3d    0x8c    0x3d    0xdd
0x489728:       0x00    0x00    0x8b    0x45    0x08    0x8b    0x4d    0x0c
0x489730:       0xf3    0x0f    0x10    0x1d
(gdb) x/wx 0x00dd3d8c
0xdd3d8c:       0x00000001
(gdb) set {int}0x00dd3d8c = 0
(gdb) x/wx 0x00dd3d8c
0xdd3d8c:       0x00000000
(gdb) c
Continuing.

Doing this manually ended up making the game widescreen for me!

I threw the thing into a LLM and this .lua ended up working for me (for some reason the actual scans fail, so it hardcodes some stuff):

require(GlobalDependencys:GetDependency("StandardBase"):GetPackageName())

--ControlVars
bFixEnabled = true
bCellShaderFix = false
bVerboseLogging = true

--PROCESS VARS
Process_FriendlyName = Module:GetFriendlyName()
Process_WindowName = "TellTale Games"
Process_ClassName = "*"
Process_EXEName = "*"

--INJECTION BEHAVIOUR
InjectDelay = 1000
WriteInterval = 200
SearchInterval = 500
SuspendThread = false

--Variables
fDefaultAspectRatio = 1.7777777
bLetterBoxScanPending = true
bLetterBoxFallbackAddress = 0x00DD3D8C

function Log(message)
	if bVerboseLogging then
		print(string.format("[MCSM-FLWS] %s", tostring(message)))
	end
end

--Name                         Manual/Auto/Hybrid  		Steam/Origin/Any                IncludeFile:Configure;Enable;Periodic;Disable;
SupportedVersions = { 		
{"Automatically Detect",       "Hybrid",  			"Any",	                         "Configure_SignatureScan;Enable_Inject;Periodic;Disable_Inject;"},
}

function TrySigScan(pattern, tAddress, offset)
	Log(string.format("TrySigScan pattern='%s' offset=0x%X exe='%s'", pattern, offset, Process_EXEName))
	if HackTool:SignatureScan(pattern, tAddress, PAGE_EXECUTE_READ, offset, Process_EXEName) ~= 0 then
		Log("TrySigScan matched with PAGE_EXECUTE_READ")
		return true
	end

	if HackTool:SignatureScan(pattern, tAddress, 0, offset, Process_EXEName) ~= 0 then
		Log("TrySigScan matched with PAGE=0 fallback")
		return true
	end

	Log("TrySigScan no match")
	return false
end

function TrySetAddress(tAddress, address)
	Log(string.format("TrySetAddress 0x%X", address))
	local ok = false

	ok = pcall(function() tAddress:SetAddress(address) end)
	if ok then
		Log("TrySetAddress succeeded via SetAddress")
		return true
	end

	ok = pcall(function() tAddress:SetLocation(address) end)
	if ok then
		Log("TrySetAddress succeeded via SetLocation")
		return true
	end

	Log("TrySetAddress failed")
	return false
end


function Configure_SignatureScan() 
	Log("Configure_SignatureScan begin")

	local tAddress = HackTool:AddAddress("LetterBoxing")
	local bFound = false
	if TrySigScan("55 8B EC 80 3D",tAddress,0) then
		bFound = true
	elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ?? 00 8B ?? ?? 8B",tAddress,0) then
		bFound = true
	elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ?? ?? 8B ?? ?? 8B",tAddress,0) then
		bFound = true
	elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ??",tAddress,0) then
		bFound = true
	end

	if not bFound then
		Log("Configure_SignatureScan scan did not find LetterBoxing")
		if TrySetAddress(tAddress, bLetterBoxFallbackAddress) then
			bLetterBoxScanPending = false
			Log("Configure_SignatureScan using fallback address")
			print(string.format("LetterBoxing fallback address applied: 0x%X", bLetterBoxFallbackAddress))
		else
			bLetterBoxScanPending = true
			Log("Configure_SignatureScan deferred for Periodic retry")
			print(string.format("LetterBoxing scan deferred, will retry in Periodic(). (%s)", tAddress:GetName()))
		end
	else
		tAddress:AcquireAddress(0x5)
		bLetterBoxScanPending = false
		Log("Configure_SignatureScan acquired LetterBoxing address via signature")
		print( tAddress:GetInfo(TYPE_INT) )
	end	

	if bCellShaderFix then
		Log("Configure_SignatureScan CellShader fix enabled, scanning CellShader")
		local tAddress = HackTool:AddAddress("CellShader")
		if HackTool:SignatureScan("F30F11??F30F59??F30F11??????????C20800CC",tAddress,PAGE_EXECUTE_READ,0x8,Process_EXEName) == 0 then
			Log("Configure_SignatureScan CellShader scan failed")
			return ErrorOccurred(string.format(SigScanError,tAddress:GetName()))
		else
			Log("Configure_SignatureScan CellShader scan succeeded")
			print( tAddress:GetInfo(TYPE_ADDRESS) )
		end
	else
		Log("Configure_SignatureScan CellShader fix disabled")
	end	
	
	Log("Configure_SignatureScan success")
	return true

end


function Enable_Inject() 
	Log("Enable_Inject begin")
	if not bCellShaderFix then
		Log("Enable_Inject early return (CellShader disabled)")
		return true
	end

	local Variables = HackTool:AllocateMemory("Variables",0)
	Variables:PushFloat("AspectDevider")
	Variables:Allocate()

	local asm = [[
		(codecave:jmp)CellShader,CellShader_cc:
			%originalcode%
			fld dword ptr [(allocation)Variables->AspectDevider]
			fld dword ptr [$$1]		$context=1
			fmulp
			fstp dword ptr [$$1]    $context=1
			jmp %returnaddress%
			
			%end%
	]]			
	
	if HackTool:CompileAssembly(asm,"CellShaderFix") == nil then
		Log("Enable_Inject assembly compile failed")
		print("Assembly compilation failed...")
		return ErrorOccurred("Assembly compilation failed...")
	else	
		Log("Enable_Inject assembly compile succeeded; enabling codecave")
		Toggle_CodeCave("CellShader_cc",true)
	end		

	Log("Enable_Inject success")
end

function Periodic()
	Log(string.format("Periodic tick (scanPending=%s)", tostring(bLetterBoxScanPending)))

	if bLetterBoxScanPending then
		Log("Periodic attempting deferred LetterBoxing scan")
		local tAddress = HackTool:AddAddress("LetterBoxing")
		local bFound = false
		if TrySigScan("55 8B EC 80 3D",tAddress,0) then
			bFound = true
		elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ?? 00 8B ?? ?? 8B",tAddress,0) then
			bFound = true
		elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ?? ?? 8B ?? ?? 8B",tAddress,0) then
			bFound = true
		elseif TrySigScan("55 8B EC 80 3D ?? ?? ?? ??",tAddress,0) then
			bFound = true
		end

		if bFound then
			tAddress:AcquireAddress(0x5)
			bLetterBoxScanPending = false
			Log("Periodic acquired LetterBoxing via deferred scan")
		elseif TrySetAddress(tAddress, bLetterBoxFallbackAddress) then
			bLetterBoxScanPending = false
			Log("Periodic applied fallback LetterBoxing address")
		else
			Log("Periodic could not resolve LetterBoxing address this tick")
		end
	end

	local LetterBoxing = HackTool:GetAddress("LetterBoxing")
	if LetterBoxing then							
		LetterBoxing:WriteInt(0)	
		Log("Periodic wrote LetterBoxing=0")
	else
		Log("Periodic LetterBoxing address missing")
	end	
	
	local Variables = HackTool:GetAllocation("Variables")
	if Variables and Variables["AspectDevider"] and DisplayInfo then	
		Variables["AspectDevider"]:WriteFloat(fDefaultAspectRatio / DisplayInfo:GetAspectRatio())
		Log("Periodic wrote AspectDevider")
	end	
	
end

function Disable_Inject()
	Log("Disable_Inject begin")

	local LetterBoxing = HackTool:GetAddress("LetterBoxing")
	if LetterBoxing then							
		LetterBoxing:WriteInt(1)	
		Log("Disable_Inject wrote LetterBoxing=1")
	else
		Log("Disable_Inject LetterBoxing address missing")
	end	
	
	CleanUp()
	Log("Disable_Inject cleanup done")
	
end


function Init()	
	Log("Init begin")
	Init_BaseControls()
	Init_Controls()
	Log("Init complete")
end

function DeInit()
	Log("DeInit begin")
	DisableFix()
	Log("DeInit complete")
end

For running it:

  • Locate your installation directory in Steam
  • Extract the FlawlessWidescreen Portable x64 into a folder (for example fw) in the game installation directory
  • Add a launch.bat file to your installation directory:
    start "" "fw/FlawlessWidescreen.exe"
    start "" ".\MinecraftStoryMode.exe"
  • Start it through Steam
  • Now every time you open MCSM, FW also launches in the same Wine prefix
  • Install the Wolf Among Us patch
  • Close FW & MCSM again
  • Paste the Lua file above into /blob/games/mcsm/fw/PluginCache/FWS_Plugins/Modules/TheWolfAmongUs/Dependencies/Scripts/TheWolfAmongUs.lua
  • Start it again through Steam
  • Enjoy!

Feel free to also link this issue in the README, maybe one day someone else with an ultrawide will appreciate this :3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions