Some streams depend directly on tables. When working with the table tool in one of those tables, we can provide a reverse-lookup for any streams that use the element we're currently looking at. For example, if we've selected "charmander" in the pokestats table, we can do a reverse-lookup to see charmander's uses in the egg moves table.
This is a bit more manual than I'd like. Hopefully a better abstraction becomes apparent as I add more streams.
Also, in order for this to work, I need to be able to know the name of elements from text tables. As a bonus, this means that Ctrl+G->items/potion now works as expected.
- make it possible to clear a single pointer from a run in the model
- add commands and properties so the `StreamArrayElementViewModel` can auto-split data.
- update the stream when a pointer changes
- if the pointer isn't to a valid stream, don't crash
- bugfix: write the destination to the pointer, not the pointer to the destination.
Well it's not pretty and it's not well tested, but the first phase of trainer pokemon teams is complete!
The trainer pokemon team (TPT) is both a table and a stream: it's a table of pokemon, but it's also editable as a stream. This lets me show a trainer's pokemon as part of the same table as the trainer, but you can dive down for table support.
a user had the comment that bit arrays would be useful if they could show all the pokemon for a given TM, not just all the TMs for a given pokemon. The idea here is to add a bit-array element after a enum element if that enum is used by a bit array.
At some point, I'll probably depend on IronRuby or IronPython with the DLR for scripting purposes. In order to avoid making my directory structure get crazy, I'm moving all files that I can into a "resources" director.
Integer bounded fields work a lot like table-matched fields. But instead of having an option of every entry in the table, it's just an option of every entry less than the given number.
* Also moved `GetOptions` to `ModelCacheScope` since no one else is using it.
* Also updated `ArrayRunEnumSegment` to use cache scopes.
* trainerdata makes use of this feature
Trainer tables include a nested pointer, which works a bit weird because the pointer points to a different data structure depending on the `structType`. The structure is a table, but won't be named. Since that pointer will require some more changes, for now we're just adding the parent table - the trainers.
I finally did it. Multiple users asked for a blinking cursor to indicate editability in the Hex area. Well, now there's a blinky cursor.
Since the entire HexContent is designed to act as a single layer, and all the extra added effects live in TabView, I added the blinky-cursor code to TabView. It operates by drawing and erasing a tiny rectangle at the text insertion point, calculated using logic from FormatDrawer. We can't use a TextBox because a TextBox won't show its cursor when not focused, and we need the focus to stay on the HexContent.
The unit test and search logic implementation were actually pretty simple. However, WPF TextBox's don't natively support a way to show text highlight when the textbox doesn't have focus... so I had to implemnet my own focus. I did this by wrapping the TextBox in a Grid so I could overlay a Rectangle that uses the same highlight color.
See TabView.xaml.cs for all the mathy bits.
To facilitate faster editing, the table tool enums and bitarrays now include links to their sources. This should allow the user to jump to a source faster for when they want to add a new option to a list, such as adding a new type or a new item.
Make it possible to duplicate data at an anchor. This new data can be edited independently of the original data, and will only be pointed to by the one location you chose. All other pointers will still point to the original version.
As part of this change, runs need the ability to duplicate themselves at a new starting point. Refactoring runs to add the new functionality.
As part of this change, the Model needs to expose its method of finding free space in the ROM.
Added a new test that shows the new feature.
In most cases, double-click expands selection. For example, with text. But with pointers, the entire pointer is already selected anyway. So double-click is free to do something else.
Many users have tried to double-click to follow a pointer. Go ahead and make it do that.
from the usability test, the user wanted an easy way to see what tables were available. In lew of typing Ctrl+G followed by spacebar, which is not super intuitive, having the table tool itself list all the tables and let you quickly goto them seems like a reasonable solution.
Whenever a table gets found and has a dynamic length, go ahead and give it a static length. This makes things more explicit, and editing the toml file is easier.
The AutoSearchModel is nifty, but seems to have trouble in a lot of situations where data isn't in the format I expect.
However, I've noticed that while many romhacks move tables around, a lot less of them move code around. So I can depend on most of the pointers to those tables still being in the same spot.
Based on this idea, I've created a new "HardcodeTablesModel" that uses known pointer locations to find tables instead of just searching for tables based on their format. This lets me simplify a lot of the logic, reducing it to basically a pointer lookup in many cases.
Most of the tests for FireRed are passing now using the new HardcodeTablesModel. I'll continue looking into issues from FireRed and the other baseroms in the next update.
Tables can contain many entries. If the user decides to delete or cut an entry, it should only effect that single entry instead of the entire array.
If the cut or delete has the entire table selected or also selects something from outside the table, the correct behavior is less clear, so keep the implementation the same.
When copying text, don't copy all the bytes (in the case of a fixed-length string): just copy until the end-of-stream byte. This makes paste work better.