Open norbjd opened 4 years ago
From what I’ve heard, STROOP builds fine on wine. I don’t think Pannen has any plans to make it build natively.
@onlymx13 Thanks for your answer.
It will run probably fine on Wine, but this was just a question I had looking at the project. Using Mono, a developer using a GNU/Linux distribution would have directly all the tools to develop/debug the application in an IDE (example : VS Code with Mono debug plugin) without using Wine every time to build the software and not be able to debug effectively.
In fact, this is also more a question of curiosity, to understand what is the effort to refactor STROOP to not use the WPF APIs (I mean, if there is for example only ten files to change, then it won't probably be too difficult to migrate - I can help on this :smiley: - but I may be wrong). Using Mono also opens the door for using technologies like Docker to create reproducible builds and images. And it may attract also GNU Linux/MacOS developers for contributing.
I made further researches, and it looks like hopefully Mono supports WinForms. The 4 missing assemblies used by WPF and missing are the following, as the last warning message suggests in my first message :
I figured out that each one is bound to a particular namespace :
System.Windows
System.Windows.Media
System.Windows.Automation
System.Windows.Forms.Integration
The 2 last namespaces are not used in the entire STROOP project.
Imports of System.Windows
and System.Windows.Media
are used in only 4 files (7 matches) :
$ echo; grep -Ern 'using System.Windows;|using System.Windows.Media' . | sort
./STROOP/Controls/DecompilerView.xaml.cs:10:using System.Windows;
./STROOP/Controls/DecompilerView.xaml.cs:14:using System.Windows.Media;
./STROOP/Controls/VisualLinkLineText.cs:10:using System.Windows.Media.TextFormatting;
./STROOP/Controls/VisualLinkLineText.cs:7:using System.Windows;
./STROOP/Controls/VisualLinkLineText.cs:9:using System.Windows.Media;
./STROOP/Utilities/MoreMath.cs:9:using System.Windows;
./STROOP/Utilities/SubtitleUtilities.cs:11:using System.Windows;
Concerned C# files are :
Controls/DecompilerView.xaml.cs
Controls/VisualLinkLineText.cs
Utilities/MoreMath.cs
Utilities/SubtitleUtilities.cs
I believe (although not sure) that without these imports, STROOP could be build natively on Linux with Mono.
I'll try to see what I can do.
I removed Controls\DecompilerView.xaml.cs
and Controls\VisualLinkLineText.cs
, and their dependencies (Controls\DecompilerView.xaml
and Controls\VisualRegexLinkGenerator.cs
) from the .csproj
build file. These files are not used widely in STROOP, so this is fine.
But I got new build errors now (more) :
"/app/STROOP.sln" (default target) (1) ->
"/app/STROOP/STROOP.csproj" (default target) (2) ->
(CoreCompile target) ->
Controls/WatchVariableControl.cs(335,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(336,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(337,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(338,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(339,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(340,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(341,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(342,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(343,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(344,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(345,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(346,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(347,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(348,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(349,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(351,35): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(352,28): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(353,32): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(354,31): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(746,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(747,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/WatchVariableControl.cs(748,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(18,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(19,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(20,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(21,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(22,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(23,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(24,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(25,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(26,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(27,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(38,20): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(38,56): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(43,20): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(43,57): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(48,20): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(48,55): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(53,20): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(54,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/KeyboardUtilities.cs(55,17): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/ObjectSlot.cs(568,84): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/ObjectSlot.cs(570,88): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/ObjectSlot.cs(573,90): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/ObjectSlot.cs(576,82): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Controls/ObjectSlot.cs(587,71): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Utilities/SubtitleUtilities.cs(19,36): error CS0103: The name 'Clipboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Managers/MemoryManager.cs(389,21): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Managers/MemoryManager.cs(390,21): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Managers/MemoryManager.cs(391,21): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
Managers/MemoryManager.cs(392,21): error CS0103: The name 'Keyboard' does not exist in the current context [/app/STROOP/STROOP.csproj]
There are 2 distinct error messages :
The name 'Keyboard' does not exist in the current context
(50 errors)The name 'Clipboard' does not exist in the current context
(1 error)Keyboard
class is indeed present in PresentationCore.dll , like Clipboard
class.
So, my last message was wrong, my mistake (not a C# expert) : DLL hides many namespaces. PresentationFramework.dll hides other namespaces, for example System.Windows.Documents
. Same for PresentationCore.dll :
There are probably other namespaces hidden behind these DLLs, but having no Windows system, I can't find what's behind all these 4 missing DLLs (maybe a kind Windows user could "decompile" them to help me find all namespaces behind :pray:).
Unfortunately, System.Windows.Input
(across Keyboard
class mainly) is widely used across STROOP :
$ echo; grep -Ern 'using System.Windows.Input' . | sort
./STROOP/Controls/DecompilerView.xaml.cs:13:using System.Windows.Input;
./STROOP/Controls/ObjectSlot.cs:17:using System.Windows.Input;
./STROOP/Controls/VisualLinkLineText.cs:8:using System.Windows.Input;
./STROOP/Controls/WatchVariableControl.cs:11:using System.Windows.Input;
./STROOP/Managers/CellsManager.cs:13:using System.Windows.Input;
./STROOP/Managers/CoinManager.cs:13:using System.Windows.Input;
./STROOP/Managers/MemoryManager.cs:13:using System.Windows.Input;
./STROOP/Managers/ObjectSlotsManager.cs:15:using System.Windows.Input;
./STROOP/Managers/SearchManager.cs:14:using System.Windows.Input;
./STROOP/Utilities/DictionaryUtilities.cs:10:using System.Windows.Input;
./STROOP/Utilities/KeyboardUtilities.cs:10:using System.Windows.Input;
There are many dependencies to these files (except Controls/DecompilerView.xaml.cs
and Controls/VisualLinkLineText.cs
, already removed from the build), so, sadly :disappointed:, I don't think I'll be able to fix these errors.
I was able to make some progress to make STROOP Mono-compatible (thus, natively GNU/Linux compatible).
As for the Keyboard
references, I've moved them to Utilities/KeyboardUtilities.cs
to centralize all keyboard interactions within a single class. I've changed all the references to Keyboard.[...]
to KeyboardUtilities.[...]
(no big changes). But, as for now, the methods are not implemented, I just wanted to know if the application could be launched with Mono first.
There was also an error with Clipboard
in Utilities/SubtitleUtilities
, so I removed the reference. I am aware that this needs to be fixed, but I repeat here, my goal was just to see if STROOP could be built with Mono.
At this step, after fixing the errors, I was finally able to build STROOP with Mono in a Docker container by running :
docker build . -t 'stroop'
I then tried to run STROOP :
# enable app to be displayed on the host
xhost +local:stroop
# run the image
docker run \
--name stroop \
--hostname stroop \
--rm -i -t \
-e DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-w /app/STROOP/bin/Debug/ \
stroop \
mono STROOP.exe
# remove X display permission on the host
xhost -local:stroop
Basically here, STROOP is running in a container but the GUI is run on the host by sharing the X11 socket (/tmp/.X11-unix
) and exporting DISPLAY
. This is the simplest way to run GUI apps with Docker AFAIK.
But there was an issue with some resources. Indeed, the separator used for directories in Config/*.xml
files was \
(for Windows). But, for GNU/Linux, this separator is /
. When running STROOP, consequences were that resources under directories could not be found. Rather than replacing in *.xml
files, I've simply replaced programmatically in Utilities/XmlConfigParser.cs
, only when needed, the \
character to Path.DirectorySeparatorChar
(on GNU/Linux, this is /
, and on Windows, there is no change), like this :
--- a/STROOP/Utilities/XmlConfigParser.cs
+++ b/STROOP/Utilities/XmlConfigParser.cs
@@ -255,16 +255,16 @@ namespace STROOP.Utilities
switch(subElement.Name.ToString())
{
case "ImageDirectory":
- imageDir = subElement.Value;
+ imageDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
case "DefaultImage":
defaultImagePath = subElement.Value;
break;
case "MapImageDirectory":
- mapImageDir = subElement.Value;
+ mapImageDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
case "OverlayImageDirectory":
- overlayImageDir = subElement.Value;
+ overlayImageDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
case "EmptyImage":
emptyImagePath = subElement.Value;
@@ -697,15 +697,15 @@ namespace STROOP.Utilities
{
case "ClassicInputImageDirectory":
guiList.Add(CreateInputImageAssoc(
- path, subElement.Value, InputDisplayTypeEnum.Classic));
+ path, subElement.Value.Replace('\\', Path.DirectorySeparatorChar), InputDisplayTypeEnum.Classic));
break;
case "SleekInputImageDirectory":
guiList.Add(CreateInputImageAssoc(
- path, subElement.Value, InputDisplayTypeEnum.Sleek));
+ path, subElement.Value.Replace('\\', Path.DirectorySeparatorChar), InputDisplayTypeEnum.Sleek));
break;
case "VerticalInputImageDirectory":
guiList.Add(CreateInputImageAssoc(
- path, subElement.Value, InputDisplayTypeEnum.Vertical));
+ path, subElement.Value.Replace('\\', Path.DirectorySeparatorChar), InputDisplayTypeEnum.Vertical));
break;
}
}
@@ -934,7 +934,7 @@ namespace STROOP.Utilities
switch (subElement.Name.ToString())
{
case "FileImageDirectory":
- fileImageDir = subElement.Value;
+ fileImageDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
}
}
@@ -1177,7 +1177,7 @@ namespace STROOP.Utilities
assoc.MapImageFolderPath = subElement.Value;
break;
case "BackgroundImageDirectory":
- assoc.BackgroundImageFolderPath = subElement.Value;
+ assoc.BackgroundImageFolderPath = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
case "DefaultImage":
var defaultMap = new MapLayout() { ImagePath = subElement.Value };
@@ -1290,7 +1290,7 @@ namespace STROOP.Utilities
switch (subElement.Name.ToString())
{
case "ScriptDirectory":
- scriptDir = subElement.Value;
+ scriptDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
case "FreeMemoryArea":
parser.FreeMemoryArea = ParsingUtilities.ParseHex(subElement.Value);
@@ -1336,7 +1336,7 @@ namespace STROOP.Utilities
switch (subElement.Name.ToString())
{
case "HackDirectory":
- hackDir = subElement.Value;
+ hackDir = subElement.Value.Replace('\\', Path.DirectorySeparatorChar);
break;
}
}
After this fix, I faced another issue here, the loading screen was launched correctly (until the end) :
But then an exception was thrown. After debugging (mono --trace:N=STROOP STROOP.exe
), I found out that error :
[0x7faf18d08bc0: 21.46603 2] LEAVE: STROOP.StroopMainForm:buttonRefresh_Click (object,System.EventArgs)
[0x7faf18d08bc0: 21.46749 1] LEAVE: STROOP.StroopMainForm:StroopMainForm_Load (object,System.EventArgs)
[0x7faf18d08bc0: 21.46837 1] ENTER: STROOP.ObjectSlot:get_Text ()(this:0x7faeeb8026e0[STROOP.ObjectSlot STROOP.exe])
[0x7faf18d08bc0: 21.46837 1] LEAVE: STROOP.ObjectSlot:get_Text ()[OBJECT:(nil)]
[0x7faf18d08bc0:] EXCEPTION handling: System.ArgumentNullException: Value cannot be null.
Parameter name: s
There is a similar issue an other Github project, fixed by this commit. Apparently, Mono does not like uninitialized string. I don't know more about this. So I just replaced (stupidly) in Controls/ObjectSlot.cs
the following :
--- a/STROOP/Controls/ObjectSlot.cs
+++ b/STROOP/Controls/ObjectSlot.cs
@@ -36,7 +36,7 @@ namespace STROOP
Image _bufferedObjectImage;
Point _textLocation = new Point();
Point _objectImageLocation = new Point();
- string _text;
+ string _text = "";
int _fontHeight;
#endregion
And this hopefully solved the error. After the loading screen, I was able to see the connection screen :
By bypassing this step, I was able to have STROOP running under GNU/Linux (in a Docker container) with Mono :
You can compare all the modifications on my fork :
Just a little update, I've made some modifications : https://github.com/SM64-TAS-ABC/STROOP/compare/Development...norbjd:21c38cf798e402bafac085f32f8268bd17e54f53.
STROOP builds fine with Mono. As of now, I cannot connect to an emulator since there is no other process in the container, only STROOP. I'm working on this.
When bypassing the connect step, the UI works fine but no values are shown in the different tabs. I think it's the normal behavior because STROOP is not connected. But, sometimes, STROOP also hangs when clicking on tab or buttons with no particular errors.
I've tried to install mupen64plus
(mupen64plus-ui-console on Debian) on the container along with STROOP. This runs fine, I've made a save state from here (.st2
file, renamed with extension .st
). STROOP loads the save state and "works", but no values are shown anywhere. In that save state, I've collected 1 star (Big Bob-omb on the Summit), get into BoB another time, grab some coins, and did the save state. But the results in STROOP does not show anything :
Also, you can see that objects are not shown in the part below.
@scob @onlymx13 : does loading save states is actually working on Windows with the latest version (Development branch)?
mupen64plus
Also, I'm not able to connect directly to mupen64plus
process because it is not declared in Config/Config.xml
(Emulators
tag). I made another issue to see if you could support mupen64plus
(#73). As of now, I've tried to add the following line :
<Emulator name="Mupen64Plus" processName="mupen64plus" ramStart="0x008EBA80" endianness="little"/>
(I copied ramStart
value from another Emulator
(mupen64-rerecording
), but I'm pretty sure this won't work like this).
After rebuilding, STROOP is now able to detect the mupen64plus
emulator on the connect page :
But when clicking Connect
, I got the following error :
Unhandled Exception:
System.EntryPointNotFoundException: CloseHandle assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) STROOP.Utilities.Kernal32NativeMethods.CloseHandle(intptr)
at STROOP.Utilities.Kernal32NativeMethods.CloseProcess (System.IntPtr processHandle) [0x00001] in <38a03fe220d245f3b3d5e7486135e053>:0
at STROOP.Utilities.WindowsProcessRamIO.Dispose (System.Boolean disposing) [0x0003f] in <38a03fe220d245f3b3d5e7486135e053>:0
at STROOP.Utilities.WindowsProcessRamIO.Finalize () [0x00002] in <38a03fe220d245f3b3d5e7486135e053>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.EntryPointNotFoundException: CloseHandle assembly:<unknown assembly> type:<unknown type> member:(null)
at (wrapper managed-to-native) STROOP.Utilities.Kernal32NativeMethods.CloseHandle(intptr)
at STROOP.Utilities.Kernal32NativeMethods.CloseProcess (System.IntPtr processHandle) [0x00001] in <38a03fe220d245f3b3d5e7486135e053>:0
at STROOP.Utilities.WindowsProcessRamIO.Dispose (System.Boolean disposing) [0x0003f] in <38a03fe220d245f3b3d5e7486135e053>:0
at STROOP.Utilities.WindowsProcessRamIO.Finalize () [0x00002] in <38a03fe220d245f3b3d5e7486135e053>:0
The error refers to native methods (extern
methods). Indeed, some of the C# files use DllImport
directive :
Controls/CarretlessTextBox.cs
Controls/RichTextBoxEx.cs
Utilities/Stream/ProcessStream.cs
Utilities/Kernal32NativeMethods.cs
Notably with the following DLLs :
user32.dll
(6 calls) : Controls/CarretlessTextBox.cs
(2 calls), Controls/RichTextBoxEx.cs
(1 call), Utilities/Stream/ProcessStream.cs
(3 calls)kernel32.dll
(8 calls) : Utilities/Kernal32NativeMethods.cs
psapi
(1 call) : Utilities/Kernal32NativeMethods.cs
Obviously, those DLLs could not be found on GNU/Linux environments. https://www.pinvoke.net/ can be used to find replacement to unmanaged API code to managed API code, but unfortunately, for methods I have searched for, there are no replacements that could be found.
I think that the most important files to be replaced are Utilities/Stream/ProcessStream.cs
and Utilities/Kernal32NativeMethods.cs
, so it may be necessary to create some for GNU/Linux equivalents.
But in a first time, if I could load a save state from STROOP, that will be a great progress. @scob @onlymx13 : do you have an idea of what can be wrong here?
Thank you very much.
I don’t know too much about mupen64plus or STROOP. However, what I will ask is whether the mupen64plus .st2 files are the same format as regular mupen64 .st files. If not, they won’t work with STROOP. I think you can get the correct RAM start value using Cheat Engine somehow. Try to find the value of Mario’s coin count or something, and you could convert that into a RAM start. I’m not sure if the issues you’re experiencing with Bypass are normal or not. What kind of buttons and tabs were causing errors? I ask since for Bypass, really M64 is the only useful tab, unless you just want the address of a variable. Not showing variables is normal. I’m pretty sure regular mupen64-rr can be built for Linux; have you looked into that?
@onlymx13 Thanks for your answer.
When using Bypass mode, or with .st2
file, the M64 tab is empty :
Indeed, it can be a problem with .st2
format.
Some errors occurs sometimes when resizing the window, or clicking too fast on some different tabs.
I guess building mupen64-rr
for GNU/Linux is possible, but the repo seems unmaintained : https://github.com/TASVideos/mupen64-rr (last commit it 2013). Is that this emulator? If yes, I'll take a look.
@onlymx13 Before that, could you please share with me a .st
file if you have one, just to see if it works with STROOP on Linux? Thank you very much.
The M64 tab is supposed to be like that until you press “Open” to open a mupen64-rr TAS file, or .m64 file. Last commit in 2013? Sadly, I’m gonna say that’s the wrong version because that’s too new. I guess it depends on which version of mupen you want. Are you in the SM64 TASing and ABC Discord server? I would advise joining that. Link is on the sidebar of https://ukikipedia.net. I don’t have an st file right now, but you could use Discord’s search to find one in that server. Some of your questions would be better put there. I’m MMMMMMMMMMMMM#2694 and scob is pannenkoek2012.
@onlymx13 Thanks for the links. I joined quickly the SM64 TASing and ABC Discord (I'll create an account later :smile:) just to get a valid .st
file that I could load in GNU/Linux STROOP :
So mupen64plus
format (.st2
) is probably not supported (yet :smile:).
Objects are loaded in the below part, but I don't see values for Life Count
, Life Display
, etc. Is it normal?
The Memory tab seems to work correctly, when clicking on an object :
I'll join the Discord as soon as possible and try to get the conversation continued here :smile:. Thanks again for your help :+1:, that was very appreciated.
Also, I found last version of mupen64-rr
on Github : https://github.com/SM64-TAS-ABC/mupen64-rr. Last commit had been made on Apr 14, 2018, so this is indeed a more recent version :smile:. At first glance, I think it can build on GNU/Linux and Windows, that's great news!
No no no, you misunderstand. 2013 is too new. You want one from 2005 or 2006. The 2018 one might still work though. I'm not exactly sure.
Ok, my bad, I misread that. In fact, the code was hosted here before http://code.google.com/p/mupen64-rr, and initial commit is from 2009 (not 2005 or 2006 though :thinking:). The migration to Github was done in 2013, hence this date on Github. I'll try to build an old version and see if it works, but I'm very sceptical because dependencies packages have been updated since.
I've tried to build the version hosted on SM64-TAS-ABC Github for Linux (from the initial commit https://github.com/SM64-TAS-ABC/mupen64-rr/tree/d6cffe315be7b4d48abac2285b151cb62df12452), but without success.
I've also found the source from v0.5 (2005/08/27) and have not been able to compile it fully. Build may have succeed someday on someone's own machine, but I think there are some missing things (I've tried to tweak the build too).
I've finally found the mupen64 v0.5 Linux binary from this site : http://mupen64.emulation64.com/down.htm and was able to run it correctly along with STROOP (after installing some 32 bits dependencies). Unfortunately, the binary mupen
is not recognized as one of the emulators, so I cannot connect to it with STROOP. Loading save states works "fine" though (I only see objects, not values) but like the .st
file found on Discord.
I'm not sure this version of mupen
is the mupen64-rerecording
expected by STROOP, but that's the only I have found :man_shrugging:.
As far as the processes go. The way it works is that STROOP assumes there is a process (executable) section of PC (Windows/Linux) memory that holds the N64 RAM memory. It can either be stored in little or big endian form. So in order to get "RAW N64 memory", the process name, the offset where the N64 memory starts in the process, and the endianess type needs to be known. The offset is assumed changed whenever the emulator is re-compiled. This is is because the compiler can place the n64 memory location to wherever it wants.
So because you are recompiling, or using the linux version of mupen, the offset is going to be different regardless. You'll need to find the offset which can be calculated by finding a known address, like Mario's health, y coordinate, etc. using cheat engine. Then subtracting the N64 address of that value from the process address you just found.
@danebou Thanks for your answer. I've made an issue (#73) related to add mupen64plus emulator, which is easier to install on GNU/Linux platforms, and also more recent than the mupen64 v0.5 I talked in my last comment (2005). I've also made a PR to support it (#74), feel free to check it.
As I said in the PR, I'm not sure it works on Windows because I don't have a Windows machine and as of now, connecting to a running process on GNU/Linux requires to rewrite some parts of the code as we have discussed on Discord. I have made a branch on my fork : https://github.com/norbjd/STROOP/tree/linux-build to rewrite functions requiring Windows only DLL to native functions (STROOP/Utilities/Kernal32NativeMethods.cs
for example). You could take a look here :smile: !
Just to keep this issue up-to-date, values are now shown in STROOP on GNU/Linux :
The hidden values was caused by the ShowCaret
and HideCaret
methods of CarretlessTextBox
, requiring user32.dll
(not present in Mono). I have added guards around these methods calls in GNU/Linux case to avoid this unfound DLL to cause issues. See this commit : https://github.com/norbjd/STROOP/commit/094398e97813105e1d138ab75515b4a7f8aa50ad.
The next step is now to rewrite all methods defined as extern
and requiring user32.dll
or kernel32.dll
(not included in Mono). This should fix other issues and maybe will allow to connect STROOP to a process running on GNU/Linux. Memory is also probably handled differently in GNU/Linux, so we must pay attention to that.
I believe that on (?:GNU[+/])?Linux
, reading another process's memory is done through /proc/<pid>/mem
and /proc/<pid>/maps
.
In addition, Mupen64Plus uses a heap allocation for its memory, so that's somewhat annoying.
Hi! I've been working on BizHawk's Linux port for a few years now and I'd like to offer my help. I'm in the Discord (same username) if you'd prefer to discuss there.
Some things that were helpful for BizHawk:
dotnet
CLI. IIRC this requires....csproj
format, the one that starts with <Project Sdk="Microsoft.NET.Sdk">
.
<LangVersion/>
in the repo so I'm not sure what it currently is, but you're going to want at least C# 8 which gets you most of the new concise syntaxes and nullable reference types. I recently compiled a list of supported features, though YMMV as I only looked at .NET Framework 4.8, not 4.6.1.Some specific concerns from this thread:
extern
methods, we may have abstractions for them that you can copy. Check usages of these classes.I know its been a while. As far as this goes, if you still want to do the development work, then we can add linux support. For that just make many gradual PRs and we can go back and forth.
Is that directed at me or OP? I can rebase my PR if you like.
Either lol. That's sounds good. I guess what I'm saying is I'll actually monitor PRs that improve STROOP, but and I don't want a massive PR to review (not your PR, just a giant linux one).
Hello :wave:
I've completely given up this to be honest, sorry :sweat_smile:
I only remembered it was too difficult (at least for me) to port to Linux because there were some references to Windows specific stuff, e.g. kernel32.dll. I even asked on StackOverflow to get some help:
But it seemed impossible at the time, and I really lacked C# and Windows expertise :confused:
Nevertheless, the last version I've made (https://github.com/SM64-TAS-ABC/STROOP/compare/dev...norbjd:STROOP:linux-build) was correctly loading .st
files with some limitations: https://github.com/SM64-TAS-ABC/STROOP/issues/72#issuecomment-619386875.
If @YoshiRulz wants to work on this, I'll closely follow his work, but I won't have neither the time nor the expertise required to help him. But glad to see this issue revived!
You're good. Hey I'm responding to this after four years lol. Compatibility would be nice, but yeah sounded like to much of a pain to get working.
I'll close this out unless Yoshi says otherwise
I'll do what I can. I rebased my PR already.
edit: merged 2024-04-30
I drafted a similar migration for the test project, but the main project doesn't compile on Linux so I can't test it. Not that there'd be much point to it since there are only 4 test methods.
I'll work on case-sensitivity next, though I don't think I'll be able to build on Linux while there's still a WPF component in the project. Maybe I could conditionally remove it and all references to it? There are no references to it. It's unused. FFS.
Yeah WPF is just related to the Accord package used for FFMPEG to convert images to video (I think) (Nope the old decompiler view, I see, nice) .
I haven't seen any issues so far.
Figured I should give an update on this:
The blocker here is being able to attach to a running process, which relies on the WindowsProcessRamIO
class, which is tied to Win32 APIs as the name suggests. I recall from early EmuHawk porting efforts that we used some .dll.so
s from WINE as drop-in replacements for kernel32.dll
and co. That's probably still a good avenue to take, even if their OpenProcess
implementation turns out to be unsuitable.
And that's where I'll have to leave this for now, since I'm not experienced in process and memory management on Linux. (Alternatively, you could redesign the IPC around memory-mapped files or sockets or something, which would require buy-in from emulators but would make a Linux port relatively easy.) But before I go I'll tie up the loose ends with the project files, and if you're interested @danebou, start on modernising the codebase.
To future humans: I reckon you'll need to test with standalone Mupen64Plus or maybe Dolphin—Mupen64Plus in EmuHawk and Project64 are Windows-only, as is Mupen-rr I believe, and Ares64 in EmuHawk probably won't work on either OS as it uses our Waterbox memory management system.
Nice, sounds good. Yeah modernizing is an understatement. I know pannen might be doing work here and there, but my current plan for stroop is just to let it coast (aside from community updates).
Maybe AI will eventually make pull requests lol
Hello :hand:,
I'd like to help on this project but I am not working on a Windows platform. I'm not an expert in C# too. I'm just a regular developer impressed by the work made on this project to find new strategies for the different challenges (ABC and others).
So, I'm trying to build the application under Linux environment using Mono, an open-source implementation of Microsoft's .NET Framework. I'm using a Docker image to create reproducible builds, using an official base Mono image based on Debian 9 (Stretch).
You can see the different updates I've made here on my fork of STROOP and the branch (
linux-build
) I've created : https://github.com/SM64-TAS-ABC/STROOP/compare/Development...norbjd:6f219e3c6efa509a045504f4163db9c8c43ceb70.To summarize quickly, here are the steps I have made :
STROOP/STROOP.csproj
toSTROOP/STROOP_linux.csproj
to avoid side effects with current builds. I'll use and modify thisSTROOP/STROOP_linux.csproj
for the Linux build.STROOP/TTC
folder (apparently, Windows does not matter about case but Linux does), precisely replacingTtc
toTTC
PreBuildEvent
andPostBuildEvent
to match Linux commands (cp
instead ofxcopy
andrm
instead ofdel
). Not sure that thePostBuildEvent
makes sense, but I did it just for the sake of consistencyThe difference between
STROOP/STROOP.csproj
andSTROOP/STROOP_linux.csproj
can be seen usingdiff
tool :When building, I've got some errors :
I have fixed some of them by removing some unused (maybe?)
using
imports, more precisely inSTROOP/Controls/DecompilerView.xaml.cs
(see this commit : https://github.com/norbjd/STROOP/commit/c217ea5134e939f22f5cffa01eb7350e25b04b45). This may be wrong (it may add some side effects?), but it removed some errors :I have also noticed that some warnings appeared before the errors (which may explain the errors) :
The build could not locate the assemblies
PresentationCore
,PresentationFramework
,UIAutomationProvider
andWindowsFormsIntegration
. Indeed, WPF (Windows Presentation Foundation) APIs are not implemented byMono
. That explains whyPresentationCore
is not available for example.By not using WPF APIs, it will be possible to build STROOP for Linux (and probably MacOS). It may (or not) attract some developers like me to contribute to this project. The problem is : I don't know how many efforts one have to make to not use WPF APIs. @scob will probably be able to answer this question. Do you think it's worth it? Maybe I'm chasing ghosts here.
If you have any questions, feel free to ask.
Thank you very much and great job on this tool once again. :+1: