fenphoenix / angelloader Goto Github PK
View Code? Open in Web Editor NEWA standalone fan mission loader / manager for the original Thief trilogy, System Shock 2, and The Dark Mod.
License: MIT License
A standalone fan mission loader / manager for the original Thief trilogy, System Shock 2, and The Dark Mod.
License: MIT License
A couple people have asked for this. Relatively easy but needs the custom listbox messagebox finished
FMSel does some stuff with detecting an FM's supported languages that we don't do. We should match its behavior, otherwise we're technically not to spec, as it were.
If we redesign it to be more vertical with a list of sections on the left and then an autosizing single-column design on the right for the actual settings (all within a resizable window), it would make it easier and more natural to support variable-width localized strings without the awkward kludges we have to do to accommodate them currently. For instance I notice that even with my allowance for two lines of text, the German translation for "Ignore the following leading articles when sorting by title:" still takes up the entirety of both lines. We want to change the design to fix this before we run past an actual limit.
RMGUIs of course have a ton of objects storing a bunch of redundant state, and layout performance is an issue as well (and it's done by the framework, of course). Still, we can do some things to speed it up. One thing we can do is to defer loading of UI elements that aren't visible immediately. I've already started on doing this with a couple of context menus. We can also try to do as much language setting as possible before the form shows, to try and avoid duplicate layouting. If we wanted to be hardcore we could even have two InitializeComponents() paths, one for debug which is the designer-generated version, and another that we generate ourselves that removes all pre-set settings that we're going to change anyway, giving us fine control.
So we can remove all Framework dependencies
We should make sure the user has a supported version of Sneaky Upgrade installed and that we tell them helpfully if they don't
As I was translating English.ini
, I noticed that two of the strings say Current culture short
and Current culture long
, appearing in the Options. Wouldn’t it be better to display System settings, short
? (Maybe it’s just me, but I think it sounds clearer this way.)
Also, there’s a string for an error that says, The date and time is outside the range of dates supported by the calendar used by the current culture
. When does this normally appear? Does this appear when an FM contains a release date like “the 33rd of December”? (First, I thought it has to do with the custom format you can set in the Options, but using the drop-downs, no matter what I set, it all appears fine without any errors.)
It means I have to research a game I really have no interest in and would rather not have to get down and dirty with... but can we really call ourselves a "DarkLoader successor" if we don't?
If we add SS2, then the space our game tabs take up will be starting to get a little bit hoggy. We could do either or both of the following:
I've stumbled across a small bug:
bug:yes
Add from list
Doing so will cause the text AngelLoader.Common.GlobalCatOrTag
to fill this position in the tags list instead of being removed.
AngelLoader already works fine with the steam version of Thief 2 (the only one I tried, I expect T1 and DS to work fine too), the only issue is it bypasses Steam itself when running the .exe
Would be great to add support for launching the game through Steam so one gets the Steam overlay, screenshots and playtime functionality while in FMs.
I could attempt to add this myself and file a PR if you think it's something you'd like added now and see a way it could be integrated in the GUI (a Use Steam checkbox?)
I'm guessing the best bet would be to use steam.exe -applaunch <appID> [launch parameters]
in the backend.
Maybe you don't care about Statistics for example, you should be able to hide it to reduce clutter.
Is is possible for angelload to write back the fm.ini files with the contents of angeloader's DB?
We want to switch AngelLoader_Stub to C++ for the following rationale:
We currently use 3F/DLLExport to allow the current .NET 4.7.2 stub to be called into by Thief. However, DLLExport doesn't support the newer SDK-style project format, which .NET Core 3 requires. If we wanted to keep the project in C#, we have two options:
However, with Core 3 now including the option for ReadyToRun where native code gets added into the compiled exe/dll - and therefore the ildasm/ilasm method is not supported at all - I'm starting to think this whole hack is a little shaky and who knows what'll happen in the future. Porting the stub to C++ allows it to work seamlessly with the NewDark call-in as it was meant to, and avoids any possible future problems. Since the stub is completely standalone, connected to the main app only through a small text-based temp file, and since it's extremely small and simple, even a C++ newb like myself can port it.
Possible stub comm file not being deleted in the following scenario:
You launch a game through Steam, but the game doesn't actually launch (because you don't have it in your Steam library or any other situation in which it gets cancelled). Because the game never runs, it never deletes the stub comm file. The next time the game runs, it finds the stub file and loads up whatever FM was specified. This won't happen if you launch an FM or original game from AngelLoader, as we delete or overwrite the stub file ourselves before playing anything, but if you were to run the game manually, it would load whatever FM was specified in the stub once, and then delete the stub file, so if you ran it again it would properly start the original game and everything would be fine again.
I could solve it if there was a way to detect if we were being launched through Steam (in C++). I don't know if there is, but then I could just specify a Steam=True line in the stub file, and then if we're being launched through steam we read and act on it as usual, but if we're not, then we just delete it and ignore.
I'll have to buy the games on Steam to test this. Or just buy one so I can have one game that works and one that doesn't, so I can test both paths.
We have a manual, but probably a lot of people aren't going to want to slog through that. We should at the very least have context-sensitive help that links out the relevant section in the manual, or ideally break it up into wiki-like sections or something.
Like it used to be. I changed that a while back to make it easier to run the game type scanner on startup if need be, but it'd be better to have the whole window ready (except possibly the readme of course, but maybe even that?) by the time you see it.
Add per-FM and per-game "option overrides" (pass config vars to the game).
--- OLD TEXT: ---
When I used to do videos, I would often find it necessary to change certain options temporarily in various config files ("inv_status_height 0" in user.cfg for hiding the HUD for screenshots, "force_windowed 1" in cam_ext.cfg when I was streaming, etc.). This was always a pain. We should have an option to run the game with a set of custom options and provide some checkboxes and an additional text field for writing in custom commands. Some options can be passed on the command-line; others will need to have their appropriate files temporarily changed. That will require us to track the running of games, rather than just fire-and-forget like we do now.
Yeah. WinForms high DPI, figure it out...
I would hope it's mostly pretty easy to get the hang of, but it's never a bad thing to explain everything explicitly (and there are a few corners)
7z files are usually solid archives, so it's very slow to do anything with them (it's prohibitively slow to grab individual files; extracting the whole archive to disk is also slow but much faster on average).
Two things need doing:
Dark Mode TODOs:
FMsDGV:
Images:
Controls
ToolStrip:
Colors:
Misc:
This is a separate exe and its saves are placed in "netsaves" folder, both of which we need to add a little bit of code to account for.
In testing with my enormous list of FMs, newly downloaded ones are just thrown in the mix and I have to remember their name and filter for them... some way to highlight newly added missions or something would be good
This was suggested in the TTLG thread a while ago. By pulling apart the UI and converting it to passive-view (with an actually good reason other than coding dogma, yay!) and then sticking it in a separate .dll, I could make a translation app that uses the UI so translators can see their translations in realtime and without having to sometimes dig deep into functionality that might be destructive or that they might not be able to see. We could allow the translator to see every section of the UI harmlessly (example: uninstalling FMs, converting audio files, viewing uncommon error scenarios that might be difficult or impossible to make happen in the regular app, etc).
Self-explanatory. No reason not to have it when we've got it for the add/remove tags area.
DL and NDL seem to be able to do this, so I guess I should too.
Making sure to copy over all config profiles, pre-post build events, etc.
Not sure how many people keep up with new versions, but currently you have to be checking the thread (or subscribed to it), then manually download and extract. If you want other languages, you have to manually download and extract those too. Auto-update would make the whole process easy and pleasant. Of course the user could turn it off and it would always ask permission first even if it was on. Don't wanna be dicks like Microsoft.
Loading large and/or image-heavy .rtf files into a RichTextBox can be horrendously slow (see An Enigmatic Treasure With A Recondite Discovery's 10MB .rtf readme with multiple huge images). This can make for a very poor user experience on startup as the form struggles to draw itself while the RichTextBox blocks and hogs the thread. We'd really like to be able to simply load its content in a separate thread and await it, but because the RTB is part of the UI, it's flat-out impossible to thread it.
EDIT: Nope, we're not going to any of the below. Instead we're going to do something way easier and more sane. As always, I research till my brains fall out and the only solution I can find is a disgusting hack, then as soon as I resign myself to actually doing said hack, a totally elegant, sane, and nice solution presents itself. Why can't these things just pop up earlier. Ah well.
Therefore, to achieve asynchrony, we're going to run it as its own process and host it inside the main UI so it will look like it's a normal part of it. We're still going to have to pop it off the UI to do the load and then pop it back on (because even though it's a separate process that's being hosted, if it's displayed on the UI, it blocks), but that's not a big deal really.
We can slap in a nice loading spinner or something while it loads. This way, the form will come up and draw itself fully immediately, and only the readme may lag behind (but it won't block and will inform the user it's loading).
So, you could say to import from DarkLoader and FMSel, and prioritize DarkLoader comments but FMSel ratings for example. Also allow prioritizing AngelLoader data.
Bug is coming from PreFilterMessage() somewhere, and I should get rid of that and switch to a custom-written version of the mouse hook anyway.
We have far too many places where we just swallow and log exceptions and then move on like nothing happened. We should stop kidding ourselves and inform the user of important errors.
[add others here]
Apparently .NET 5 works well on Wine, so we could try this.
I'm not going to get my hopes up that it won't continue to be an order of magnitude slower than Framework 4.7.2, but at least it should work much better on Linux.
Right now we kinda stomp on peoples' config files to set AngelLoader_Stub.dll as the FM selector. That's sort of fine because every loader needs to have itself specified in the config file to work, but due to our standalone nature, we're not necessarily as obvious about it as a conventional loader would be. Because other loaders are contained within the actual .dll, if you start "thief.exe -fm" expecting FMSel to start, but you get NewDarkLoader, well, at least you know that NewDarkLoader got set as the selector somehow. But with us, if you say "thief.exe -fm" and we're the loader, then the stub dll will start, but it doesn't do anything visual, it just looks for data in the stub comm file in our temp folder. If it finds it, it loads the FM specified; if it doesn't or it's invalid, then it just loads the normal game without an FM and doesn't tell the user or do anything that would make it clear what's going on. See this thread. We could maybe make it so the stub ALWAYS needs the comm file in order to start the game silently, and we can just specify whether to play the original game or an FM. Then, if it doesn't find a comm file, it could maybe throw up a dialog box and explain itself at least. Or do something else smarter, like give the option to restore other loaders?
While working on improving the sorting behavior of the FMs list columns, I realized that there could be multiple different ways you might want to sort a column. For instance, for the rating column, it could be much nicer to sort only the rated rows, and leave all unrated rows at the bottom at all times. That way you don't have to get a sea of empty rows at the top and then scroll all the way down to see your ratings. But then again, it could also sometimes be desirable to have that behavior if you're interested in seeing which FMs you haven't yet rated in particular. Or, as in the Last Played column, you might want to sort in reverse first because it makes more sense to have the most recent times at the top, but then again sorting normally is "more logical". We could have a Settings section where you can set these kind of options per-column maybe. We could also add a submenu to the column header context menu where you could sort a certain way just that once.
Currently, we have a few filter buttons that require drop-downs so the user can enter more information (these are the two date filter buttons and the rating filter button). Right now, these drop-downs are just separate windows with OK and Cancel buttons. This is functional enough but looks hacky, and autosizing based on localized strings (particularly the title bar string) is difficult (and isn't currently done). At this point we have a global mouse hook system in place, so we can dig out the old custom drop-down tests and convert them to use the global mouse hook so they can function correctly and without glitches or corner cases. We then won't have or need a title bar at all, and we can get rid of the side-by-side OK and Cancel buttons too, and then autosizing will be easy.
I've just tried out AngelLoader v1.4, and noticed that after setting the backup path in the options, I can’t unset it. Also, as I can see, AngelLoader can load backup files in the FM archives (saved by fmsel).
Would it be possible to allow the user to save the backup there, next to the FM files, as well?
It's an automatically enabled accessibility thing. We can turn it off by turning off "level 2 accessibility features" (or some similar name) but I don't want to do that because who knows what else it might turn off that somebody might be using. It's incredibly stubborn and can't be disabled otherwise (not even with reflection afaik), nor can it even be tracked programmatically. If we could track it, then we could do as Dahenjo suggested and use it to allow keyboard column sorting by detecting which column is highlighted and sorting that column when the user presses eg. Ctrl-up or Ctrl-down.
With .NET Core 3, the WinForms source code is part of it and is MIT licensed like everything else, so we can do like we did with the zip stuff and just grab the DataGridView code, modify it, and there you go. We can either use the highlighting to track and allow keyboard nav, or just get rid of it. ETA November
This feature is just too good to ignore, at least for me - I've always wanted to be able to easily keep modifications to mission folders like adding an fm.cfg to add bloom for just that mission, or turn off new mantling for OldDark missions (to prevent me being uncertain if I was meant to be able to mantle somewhere), fixing readables, etc. It would also make us more compatible with the setups of folks who use FMSel with this option.
Additionally, it would allow for all kinds of crazy cool FM-specific options in the future - we could have simple checkboxes that could turn things on and off per-FM (bloom etc.) and they would be permanent.
This would need some reasonably serious refactoring of the guts, but I notice it can get really annoying and tedious if you want to do stuff to a bunch of FMs, like say mark off finished-on state etc. With multiple FM selection, we could just click "Expert" and they all get marked. We could even install or uninstall multiple FMs at once.
Multiple selection support progress:
Right now, we just let Windows scale us as it sees fit, with the result that our UI looks slightly blurry when not at 100% scale, and I have reports that fonts may not be scaling quite as they should either. We might have to switch to .NET Framework 4.8 to do this, as judging from the release notes there's some high-DPI support improvements for WinForms in there that we might need. However, the requirements are the same as for 4.7.2, so it's not that much of a problem, other than making people download an entire new very large framework version that they may not have.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.