Tuesday, March 7, 2017

Viewing the MFT size on any modern Windows version

On Windows 10, you can get a lot of neat information about any given file's disk layout with this command:

fsutil volume filelayout c:\path\to\file.ext

The data size is reported in the Size row of the ::$DATA stream's section. That even works on the $MFT file (the Master File Table) for the volume. Unfortunately, the filelayout subcommand doesn't exist on older versions of Windows.

On earlier versions, the MFT size is reported with the general NTFS information:

fsutil fsinfo ntfsinfo c:

Look for the Mft Valid Data Length line. The value is the hexadecimal number of bytes.

Based on my Super User answer.

Monday, March 6, 2017

AbiathRPC - Tileinfo download

Yesterday I added full tileinfo support to AbiathRPC, minus support for it in the Download Levels feature. Today I filled in that gap. Since downloading the project might now get more than just levels, the menu has been renamed to simply Download. If and only if the current server has tileinfo, the export window has an extra field for the tileinfo file's name. As expected, that file is now saved right beside the levels.

Sunday, March 5, 2017

AbiathRPC - Tileinfo

Abiathar's ability to show tile properties is extremely useful in my opinion, and it's especially important when testing the level requires an extra step like it does with AbiathRPC (seeing as the level set is remote). Obviously, Abiathar can't show tileinfo that it doesn't have, so I today I added support for tileinfo reading and writing in AbiathRPC.

It was less difficult than I expected. The server loads a tileinfo file if indicated in the configuration file. Clients request that when they connect. When a user alters a tile property, the change is noticed when the tool calls MarkChangesMade. The client extension keeps track of the previous ATP IDs so it doesn't have to reupload all the tileinfo. On the network, the properties are transmitted as an array of bytes - 2 long or 8 long for background and foreground, respectively. (I would have used ATP IDs there, but the server application doesn't have a reference to any Abiathar component and therefore can't process those numbers.)

I have yet to incorporate tileinfo into the export feature, but that shouldn't be hard at all.

Saturday, March 4, 2017

PSThar - Selected tile cmdlets

Today I implemented a simple pair of cmdlets for PSThar: Get-SelectedTile and Set-SelectedTile. Each takes either a plane number (0 to 2) or one of three switches (e.g. -Background). The setter version, of course, takes a new tile ID to place in the appropriate selected tile bay. It also performs the bookkeeping task of sending a "selected tile changed" notification.

Friday, March 3, 2017

PSThar - Set-TileProperties

Today I wrote the Set-TileProperties cmdlet for PSThar. As expected, it was much more interesting than Get-TileProperties, mostly because I wanted to have it accept a PSThar tileinfo object of the type appropriate for the tile's plane. (There's one class for background tiles and another for foreground tiles.) One field - and therefore one parameter - can't have two different types, so I learned about dynamic parameters. The -Properties switch changes type depending on whether -Background or -Foreground was supplied.

When setting the new tileinfo on the tile, individual properties can come from different sources; it would be inconvenient to make the user supply every single aspect of the tileinfo every time. Individual switches have the highest precedence, then the property is taken from the tileinfo object if it's supplied, and the property currently on the tile is a fallback.

Thursday, March 2, 2017

PSThar - Get-TileProperties

My goal with the predefined PSThar cmdlets is to provide easier access to the project than is afforded by the normal API. Mostly, that means handling the boring bookkeeping for the user. I already made a getter and setter for level tiles; today I started the pair for tile properties.

So as to not force extensions to take a dependency on FleexCore 2 (FMod), Abiathar translates tileinfo entries to ULongs and provides some helper methods to reconstitute the meaning from those numbers. Those aren't super easy to work with from script, so I made a class with a bunch of read-only properties to represent the tileinfo for a single tile. Get-TileProperties takes a -Background or -Foreground switch, plus a tile ID, and returns one of those objects. My plan for the setter is to give it a bunch of optional switches to alter one or more parts of a tile's tileinfo.

I also noticed that calling $Abiathar.ViewState.RerenderSelTiles() does nothing from script because the pipeline is run on a different thread than the main form's UI. To fix that, I added the call to the method on the PSThar form that cleans up after script completion.

Wednesday, March 1, 2017

If tiles animate automatically, they must continue to animate

Today I helped a new NetKeen modder with their first map. Upon entering their level and after a tiny delay, NetKeen would freeze solid. It couldn't be level set corruption, since it displayed fine and all the other levels in the set had no problems. I didn't see any obvious mistakes in the level, and the Level Inspector reported no issues. I could add a new map to the level set just fine, so I decided to copy over tiles type by type to see which one caused things to break.

Sure enough, when I introduced a certain foreground tile, the freezing started. Looking at its properties, I noticed that it had an animation delay and offset configured when it definitely didn't need one. The tile that it animated to had no animation properties set. Clearing the animations on the source fixed the problem.

I conclude that if a tile automatically animates (i.e. it has an animation target set and doesn't wait for a switch to flip it), it must animate in a continuous cycle. The Tile Property Modifier's inspection mode doesn't check for this; I will see about adding logic for it.