Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input-Recording: V2 File format #4371

Closed
wants to merge 11 commits into from

Conversation

xTVaser
Copy link
Member

@xTVaser xTVaser commented Apr 17, 2021

Description

My main motivation for breaking the file format for hopefully the final time is because of several reasons:

  • The current format was not designed with flexibility/extensibility in mind. It has a lot of cruft that we'd like to cleanup, etc.
  • I needed a way to make an input recording file that I can mark certain inputs as ignored. In other words, different "types" of input recordings beyond just how they begin (savestate/poweron)

Additionally, I corrected our handling of unicode strings in the recording logging namespace, and switched the vast majority away from WX's file handling in favor of ghc::filesystem. The new file format implementation also moves away from C libraries in favor of the C++ standard lib.

For utf8 handling I referenced - http://utf8everywhere.org/
For binary file format best practices - https://fadden.com/tech/file-formats.html

This PR still likely needs some cleanup, but functionality it's decently tested (i can record/playback and accurately convert from V1). However, I wanted to put it up "early" to get feedback, mostly from @sonicfind as I know his upcoming MultiTap work may benefit from this (or be ruined if i made a mistake!)

common/include/Utilities/StringUtils.h Outdated Show resolved Hide resolved
common/src/Utilities/FileUtils.cpp Outdated Show resolved Hide resolved
pcsx2/Recording/InputRecording.cpp Outdated Show resolved Hide resolved
@Warepire
Copy link

Warepire commented Apr 17, 2021

General suggestion for the file format: If you want maximum flexibility, binary is not the best choice for the header. How about a Yaml header + binary input data for each frame. Doesn't even need to be the same file if you don't want to mix the different types of data if you use something like tar and optionally zstd to compress it on the fly.

(I picked tar as an example because the basic version can be implemented in 100 lines of code or so if you don't need to handle special files)

@xTVaser
Copy link
Member Author

xTVaser commented Apr 20, 2021

That's a good point, I abandoned the idea of YAML for the entire file for performance reasons, but I like the idea for just the header.

On the subject of compression, it was something we talked about in the past and the verdict was that it doesn't really feel worth it. Hours and hours of recording takes up less space than a single PCSX2 save-state (which is compressed!) to put it in perspective.

@Warepire
Copy link

I didn't know if it would make sense or not which is why I specified compression as optional, and you proved that it doesn't make sense to compress. So that part can definitely be ignored.

@xTVaser
Copy link
Member Author

xTVaser commented Apr 20, 2021

Thought about the YAML change a bit more, it's problematic for just the header as well. While it would be more flexible, there are values within the header that get updated every frame, and since the YAML data is going to be variable size, we can't selectively update those values in-place.

I don't think we're sacrificing too much flexibility wise. No matter the format, new fields have to be handled using the version schema appropriately. While it is certainly a bit more cumbersome to work with the binary format compared to the alternative, it affords us some optimizations we need while still keeping things fairly organized/centralized.

@xTVaser xTVaser force-pushed the recording/file-version-2 branch from 0748485 to fd0c7dc Compare April 21, 2021 03:38
@Warepire
Copy link

Updating in place can be done if you keep the data in a struct or something which you serialize to yaml as necessary. But if binary format overall is easier to manage in this situation, then I have nothing against the binary format.

@xTVaser xTVaser force-pushed the recording/file-version-2 branch from 6de2ff5 to 275524d Compare April 23, 2021 23:11
@xTVaser xTVaser force-pushed the recording/file-version-2 branch from 275524d to 75a011c Compare April 23, 2021 23:46
@xTVaser xTVaser force-pushed the recording/file-version-2 branch 2 times, most recently from 9d5d369 to bc017ae Compare April 24, 2021 00:30
@xTVaser
Copy link
Member Author

xTVaser commented Apr 24, 2021

We should disable the following codacy remark lint check:
image
It's apparently prone to false-positives (all the flagged ones here are) remarkjs/remark-lint#78

@xTVaser xTVaser force-pushed the recording/file-version-2 branch from bc017ae to 7ef7633 Compare April 24, 2021 00:41
@xTVaser xTVaser marked this pull request as ready for review April 24, 2021 00:42
@xTVaser
Copy link
Member Author

xTVaser commented Apr 24, 2021

Reasonably confident with this, did the following tests:

  • Confirmed there were no issues removing the following workaround in linux:
    wxString path = m_filePicker->GetPath();
    // wxWidget's removes the extension if it contains wildcards
    // on wxGTK https://trac.wxwidgets.org/ticket/15285
    if (!path.EndsWith(".p2m2"))
    {
    return wxString::Format("%s.p2m2", path);
    }
  • Created an input recording from power-on and from a savestate on master (legacy recordings)
    • Was able to play both back successfully. Each were converted while the originals were left in-tact.
  • Created an input recording from power-on and from a savestate on this branch (use the new format from the beginning)
    • Both of these also worked fine.

MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), nullptr, 0);

std::wstring output;
output.resize(size);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can save a line (and possibly a reallocation) if you pass size when constructing output: std::wstring output(size);

@xTVaser
Copy link
Member Author

xTVaser commented Apr 2, 2022

Closing this PR, very out of date, especially with the migration to Qt -- and I've since realized I need to radically alter the file format to do more useful things anyway. This format still holds too true to the original V1 and would be useless for planned features.

@xTVaser xTVaser closed this Apr 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants